<commit_before>package vanity

import (
	"encoding/hex"
	"testing"

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

func TestToAccount(t *testing.T) {
	var assert = assert.New(t)
	acc := "TCGQQKN5HED66OQ67Z2F7GGWZ66DWVBFJUW6F5WC"
	pub, _ := hex.DecodeString("c342dbf7cdd3096c4c3910c511a57049e62847dd5030c7e644bc855acc1fd626")

	account, err := ToAccount(pub, TestnetId)
	assert.NoError(err)

	if account != acc {
		t.Fatalf("Mismatched account: expected %v but received %v", acc, account)
	}
}

func TestToChainId(t *testing.T) {
	var assert = assert.New(t)

	_, err := ToChainId("mainnet")
	assert.NoError(err)
	_, err = ToChainId("main")
	assert.NoError(err)
	_, err = ToChainId("0x68")
	assert.NoError(err)
	_, err = ToChainId("68")
	assert.NoError(err)
	_, err = ToChainId("testnet")
	assert.NoError(err)
	_, err = ToChainId("test")
	assert.NoError(err)
	_, err = ToChainId("0x98")
	assert.NoError(err)
	_, err = ToChainId("98")
	assert.NoError(err)
	_, err = ToChainId("mijin")
	assert.NoError(err)
	_, err = ToChainId("0x60")
	assert.NoError(err)
	_, err = ToChainId("60")
	assert.NoError(err)

	_, err = ToChainId("mainNet")
	assert.Error(err)
	_, err = ToChainId("Main")
	assert.Error(err)
	_, err = ToChainId("TE")
	assert.Error(err)
	_, err = ToChainId("testN")
	assert.Error(err)
	_, err = ToChainId("0x100")
	assert.Error(err)
	_, err = ToChainId("0x")
	assert.Error(err)
	_, err = ToChainId("")
	assert.Error(err)
	_, err = ToChainId("miiijni")
	assert.Error(err)
	_, err = ToChainId("101010")
	assert.Error(err)
}

func TestGenerateAccount(t *testing.T) {
	var assert = assert.New(t)
	_, err := GenerateAccount(TestnetId)
	assert.NoError(err)
	//strings.HasPrefix(acc, "TC")

	_, err = GenerateAccount(MainnetId)
	assert.NoError(err)
	//strings.HasPrefix(acc, "NA")

	_, err = GenerateAccount(MijinId)
	assert.NoError(err)
	//strings.HasPrefix(acc, "TA")

	_, err = GenerateAccount(0x00)
	assert.Error(err)
	_, err = GenerateAccount(0xFF)
	assert.Error(err)
}
<commit_msg>Source code formating fixed<commit_after>package vanity

import (
	"encoding/hex"
	"testing"

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

func TestToAccount(t *testing.T) {
	var assert = assert.New(t)
	acc := "TCGQQKN5HED66OQ67Z2F7GGWZ66DWVBFJUW6F5WC"
	pub, _ := hex.DecodeString("c342dbf7cdd3096c4c3910c511a57049e62847dd5030c7e644bc855acc1fd626")

	account, err := ToAccount(pub, TestnetId)
	assert.NoError(err)

	if account != acc {
		t.Fatalf("Mismatched account: expected %v but received %v", acc, account)
	}
}

func TestToChainId(t *testing.T) {
	var assert = assert.New(t)

	_, err := ToChainId("mainnet")
	assert.NoError(err)
	_, err = ToChainId("main")
	assert.NoError(err)
	_, err = ToChainId("0x68")
	assert.NoError(err)
	_, err = ToChainId("68")
	assert.NoError(err)
	_, err = ToChainId("testnet")
	assert.NoError(err)
	_, err = ToChainId("test")
	assert.NoError(err)
	_, err = ToChainId("0x98")
	assert.NoError(err)
	_, err = ToChainId("98")
	assert.NoError(err)
	_, err = ToChainId("mijin")
	assert.NoError(err)
	_, err = ToChainId("0x60")
	assert.NoError(err)
	_, err = ToChainId("60")
	assert.NoError(err)

	_, err = ToChainId("mainNet")
	assert.Error(err)
	_, err = ToChainId("Main")
	assert.Error(err)
	_, err = ToChainId("TE")
	assert.Error(err)
	_, err = ToChainId("testN")
	assert.Error(err)
	_, err = ToChainId("0x100")
	assert.Error(err)
	_, err = ToChainId("0x")
	assert.Error(err)
	_, err = ToChainId("")
	assert.Error(err)
	_, err = ToChainId("miiijni")
	assert.Error(err)
	_, err = ToChainId("101010")
	assert.Error(err)
}

func TestGenerateAccount(t *testing.T) {
	var assert = assert.New(t)
	_, err := GenerateAccount(TestnetId)
	assert.NoError(err)
	//strings.HasPrefix(acc, "TC")

	_, err = GenerateAccount(MainnetId)
	assert.NoError(err)
	//strings.HasPrefix(acc, "NA")

	_, err = GenerateAccount(MijinId)
	assert.NoError(err)
	//strings.HasPrefix(acc, "TA")

	_, err = GenerateAccount(0x00)
	assert.Error(err)
	_, err = GenerateAccount(0xFF)
	assert.Error(err)
}
<|endoftext|>


<commit_before>package vault

import (
	"io/ioutil"
	"log"
	"os"

	vaultapi "github.com/hashicorp/vault/api"
	"k8s.io/client-go/rest"
)

// Client is a Vault client with Kubernetes support and token automatic renewing
type Client struct {
	client       *vaultapi.Client
	logical      *vaultapi.Logical
	tokenRenewer *vaultapi.Renewer
}

// NewClient creates a new Vault client
func NewClient(role string) (*Client, error) {
	return NewClientWithConfig(vaultapi.DefaultConfig(), role)
}

// NewClientWithConfig creates a new Vault client with custom configuration
func NewClientWithConfig(config *vaultapi.Config, role string) (*Client, error) {
	rawClient, err := vaultapi.NewClient(config)
	if err != nil {
		return nil, err
	}
	logical := rawClient.Logical()
	var tokenRenewer *vaultapi.Renewer

	client := &Client{client: rawClient, logical: logical}

	if rawClient.Token() == "" {

		token, err := ioutil.ReadFile(os.Getenv("HOME") + "/.vault-token")

		if err == nil {

			rawClient.SetToken(string(token))

		} else {
			// If VAULT_TOKEN or ~/.vault-token wasn't provided let's suppose
			// we are in Kubernetes and try to get one with the ServiceAccount token

			k8sconfig, err := rest.InClusterConfig()
			if err != nil {
				return nil, err
			}

			initialTokenArrived := make(chan string, 1)

			go func() {
				for {
					data := map[string]interface{}{"jwt": k8sconfig.BearerToken, "role": role}
					secret, err := logical.Write("auth/kubernetes/login", data)
					if err != nil {
						log.Println(err.Error())
						continue
					}

					log.Println("Received new Vault token")

					// Set the first token from the response
					rawClient.SetToken(secret.Auth.ClientToken)

					initialTokenArrived <- secret.LeaseID

					// Start the renewing process
					tokenRenewer, err = rawClient.NewRenewer(&vaultapi.RenewerInput{Secret: secret})
					if err != nil {
						log.Println(err.Error())
						continue
					}
					client.tokenRenewer = tokenRenewer

					go tokenRenewer.Renew()

					runRenewChecker(tokenRenewer)
				}
			}()

			<-initialTokenArrived
		}
	}

	return client, nil
}

func runRenewChecker(tokenRenewer *vaultapi.Renewer) {
	for {
		select {
		case err := <-tokenRenewer.DoneCh():
			if err != nil {
				log.Println("Renew error:", err.Error())
				return
			}
		case renewal := <-tokenRenewer.RenewCh():
			log.Printf("Successfully renewed at: %s", renewal.RenewedAt)
		}
	}
}

// Vault returns the underlying hashicorp Vault client
func (client *Client) Vault() *vaultapi.Client {
	return client.client
}

// Close stops the token renewing process of this client
func (client *Client) Close() {
	if client.tokenRenewer != nil {
		log.Println("Stopped Vault tokenRenewer")
		client.tokenRenewer.Stop()
	}
}
<commit_msg>Fix Stop()<commit_after>package vault

import (
	"io/ioutil"
	"log"
	"os"
	"sync"

	vaultapi "github.com/hashicorp/vault/api"
	"k8s.io/client-go/rest"
)

// Client is a Vault client with Kubernetes support and token automatic renewing
type Client struct {
	sync.Mutex
	client       *vaultapi.Client
	logical      *vaultapi.Logical
	tokenRenewer *vaultapi.Renewer
	closed       bool
}

// NewClient creates a new Vault client
func NewClient(role string) (*Client, error) {
	return NewClientWithConfig(vaultapi.DefaultConfig(), role)
}

// NewClientWithConfig creates a new Vault client with custom configuration
func NewClientWithConfig(config *vaultapi.Config, role string) (*Client, error) {
	rawClient, err := vaultapi.NewClient(config)
	if err != nil {
		return nil, err
	}
	logical := rawClient.Logical()
	var tokenRenewer *vaultapi.Renewer

	client := &Client{client: rawClient, logical: logical}

	if rawClient.Token() == "" {

		token, err := ioutil.ReadFile(os.Getenv("HOME") + "/.vault-token")

		if err == nil {

			rawClient.SetToken(string(token))

		} else {
			// If VAULT_TOKEN or ~/.vault-token wasn't provided let's suppose
			// we are in Kubernetes and try to get one with the ServiceAccount token

			k8sconfig, err := rest.InClusterConfig()
			if err != nil {
				return nil, err
			}

			initialTokenArrived := make(chan string, 1)

			go func() {
				for {
					client.Lock()
					if client.closed {
						client.Unlock()
						break
					}
					client.Unlock()

					data := map[string]interface{}{"jwt": k8sconfig.BearerToken, "role": role}
					secret, err := logical.Write("auth/kubernetes/login", data)
					if err != nil {
						log.Println("Failed to request new Vault token", err.Error())
						continue
					}

					log.Println("Received new Vault token")

					// Set the first token from the response
					rawClient.SetToken(secret.Auth.ClientToken)

					initialTokenArrived <- secret.LeaseID

					// Start the renewing process
					tokenRenewer, err = rawClient.NewRenewer(&vaultapi.RenewerInput{Secret: secret})
					if err != nil {
						log.Println("Failed to renew Vault token", err.Error())
						continue
					}

					client.Lock()
					client.tokenRenewer = tokenRenewer
					client.Unlock()

					go tokenRenewer.Renew()

					runRenewChecker(tokenRenewer)
				}
				log.Println("Vault token renewal closed")
			}()

			<-initialTokenArrived
		}
	}

	return client, nil
}

func runRenewChecker(tokenRenewer *vaultapi.Renewer) {
	for {
		select {
		case err := <-tokenRenewer.DoneCh():
			if err != nil {
				log.Println("Vault token renewal error:", err.Error())
			}
			return
		case <-tokenRenewer.RenewCh():
			log.Printf("Renewed Vault Token")
		}
	}
}

// Vault returns the underlying hashicorp Vault client
func (client *Client) Vault() *vaultapi.Client {
	return client.client
}

// Close stops the token renewing process of this client
func (client *Client) Close() {
	client.Lock()
	defer client.Unlock()
	if client.tokenRenewer != nil {
		client.closed = true
		client.tokenRenewer.Stop()
	}
}
<|endoftext|>


<commit_before>package main

func main() {
}
<commit_msg>Simple channel cache sample<commit_after>package main

import (
	"fmt"
	"time"
)

func main() {
	sharedMap := NewChannelSharedMap()

	go sharedMap.WriteToMap("Emma", "A message from Liam to Emma")
	go sharedMap.WriteToMap("Liam", "A message from Emma to Liam")
	go sharedMap.WriteToMap("Olivia", "A message from Noah to Olivia")
	go sharedMap.WriteToMap("Noah", "A message from Olivia to Noah")
	go sharedMap.WriteToMap("Ava", "A message from Isabella to Ava")
	go sharedMap.WriteToMap("Lucas", "A message from Mason to Lucas")
	go sharedMap.WriteToMap("Isabella", "A message from Ava to Isabella")
	go sharedMap.WriteToMap("Mason", "A message from Lucas to Mason")
	go sharedMap.WriteToMap("Sophia", "A message from Logan to Sophia")
	go sharedMap.WriteToMap("Logan", "A message from Sophia to Logan")

	go sharedMap.ReadFromMap("Emma")
	go sharedMap.ReadFromMap("Liam")
	go sharedMap.ReadFromMap("Olivia")
	go sharedMap.ReadFromMap("Noah")
	go sharedMap.ReadFromMap("Ava")
	go sharedMap.ReadFromMap("Lucas")
	go sharedMap.ReadFromMap("Isabella")
	go sharedMap.ReadFromMap("Mason")
	go sharedMap.ReadFromMap("Sophia")
	go sharedMap.ReadFromMap("Logan")

	<-sharedMap.Done
}

func NewChannelSharedMap() *ChannelSharedMap {
	m := &ChannelSharedMap{
		sharedMap: make(map[string]string),
		write:     make(chan *Message),
		read:      make(chan string),
		Done:      make(chan bool, 1),
	}

	go m.Loop()

	return m
}

type Message struct {
	Recipient string
	Message   string
}

type ChannelSharedMap struct {
	sharedMap map[string]string
	write     chan *Message
	read      chan string
	Done      chan bool
}

func (m *ChannelSharedMap) Loop() {
	ticker := time.NewTicker(time.Second * 5)
	defer func () {
		ticker.Stop()
	}()

	isInactive := false

	for {
		select {
		case <-ticker.C:
			if isInactive {
				fmt.Println("inactive for 10 secs, shutting down")
				m.Done <- true
				return
			} else {
				fmt.Println("inactive for 5 secs, will wait another 5 secs")
				isInactive = true
				continue
			}
		case msg := <-m.write:
			if msg != nil {
				m.sharedMap[msg.Recipient] = msg.Message
			}
		case recipient := <-m.read:
			message := m.sharedMap[recipient]

			if message == "" {
				go m.ReadFromMap(recipient)
				continue
			}

			delete(m.sharedMap, recipient)
			fmt.Println(message)
		}

		isInactive = false
	}
}

func (m *ChannelSharedMap) WriteToMap(recipient string, message string) {
	m.write <- &Message{Recipient: recipient, Message: message}
}

func (m *ChannelSharedMap) ReadFromMap(recipient string) {
	m.read <- recipient
}
<|endoftext|>


<commit_before>package helpers

import (
	"crypto/rand"
	"fmt"
	rnd "math/rand"
	"reflect"
	"strings"
	"time"
)

//AllUniqueWord will return a bool value based on if the word contains
//unique characters or not.
func AllUniqueWord(s string) bool {
	strSlice := strings.Split(s, "")
	resultSl := make(map[string]int)

	for _, v := range strSlice {
		resultSl[v]++
	}

	for _, v := range resultSl {
		if v > 1 {
			return false
		}
	}
	return true
}

//ReverseStr returns the string reversed
func ReverseStr(s string) (result string) {
	for _, v := range s {
		result = string(v) + result
	}
	return
}

//StrPermutation checks if two strings has the same elements in the same amount
func StrPermutation(a string, b string) bool {
	ma := make(map[string]int)
	mb := make(map[string]int)
	aSl := strings.Split(a, "")
	bSl := strings.Split(b, "")

	for _, v := range aSl {
		ma[v]++
	}
	for _, v := range bSl {
		mb[v]++
	}

	eq := reflect.DeepEqual(ma, mb)

	if eq {
		return true
	}

	return false

}

//ReplaceSpacesWSymb expects two strings, first arg being the string itself
//Second argument is the symbol to replace spaces
//E.G: s := "emir ozer" symb := "%20"  / Result will be "emir%20ozer"
func ReplaceSpacesWSymb(s string, symb string) (result string) {
	sp := strings.Fields(s)
	var tSp string
	for _, v := range sp {
		tSp += v + symb
	}
	return tSp[:len(tSp)-len(symb)]
}

//PseudoUUID generates a uuid like string
func PseudoUUID() (uuid string) {

	b := make([]byte, 16)
	_, err := rand.Read(b)
	if err != nil {
		fmt.Println("Error: ", err)
		return
	}

	uuid = fmt.Sprintf("%X-%X-%X-%X-%X", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])

	return
}

//RandomString gets the desired length and returns a random string
func RandomString(l int) string {
	rnd.Seed(time.Now().UnixNano())
	bytes := make([]byte, l)
	for i := 0; i < l; i++ {
		bytes[i] = byte(RandInt(65, 90))
	}
	return string(bytes)
}

//RandInt returns a random integer between the min and max you set
func RandInt(min int, max int) int {
	rnd.Seed(time.Now().UnixNano())
	return min + rnd.Intn(max-min)
}

//DiffSlices takes two integer slices and returns the diff between them
func DiffSlices(X, Y []int) []int {
	m := make(map[int]int)

	for _, y := range Y {
		m[y]++
	}

	var ret []int
	for _, x := range X {
		if m[x] > 0 {
			m[x]--
			continue
		}
		ret = append(ret, x)
	}

	return ret
}
<commit_msg>added md5 function<commit_after>package helpers

import (
	"crypto/rand"
	"crypto/sha1"
	"encoding/hex"
	"fmt"
	rnd "math/rand"
	"reflect"
	"strings"
	"time"
)

//AllUniqueWord will return a bool value based on if the word contains
//unique characters or not.
func AllUniqueWord(s string) bool {
	strSlice := strings.Split(s, "")
	resultSl := make(map[string]int)

	for _, v := range strSlice {
		resultSl[v]++
	}

	for _, v := range resultSl {
		if v > 1 {
			return false
		}
	}
	return true
}

//ReverseStr returns the string reversed
func ReverseStr(s string) (result string) {
	for _, v := range s {
		result = string(v) + result
	}
	return
}

//StrPermutation checks if two strings has the same elements in the same amount
func StrPermutation(a string, b string) bool {
	ma := make(map[string]int)
	mb := make(map[string]int)
	aSl := strings.Split(a, "")
	bSl := strings.Split(b, "")

	for _, v := range aSl {
		ma[v]++
	}
	for _, v := range bSl {
		mb[v]++
	}

	eq := reflect.DeepEqual(ma, mb)

	if eq {
		return true
	}

	return false

}

//ReplaceSpacesWSymb expects two strings, first arg being the string itself
//Second argument is the symbol to replace spaces
//E.G: s := "emir ozer" symb := "%20"  / Result will be "emir%20ozer"
func ReplaceSpacesWSymb(s string, symb string) (result string) {
	sp := strings.Fields(s)
	var tSp string
	for _, v := range sp {
		tSp += v + symb
	}
	return tSp[:len(tSp)-len(symb)]
}

//PseudoUUID generates a uuid like string
func PseudoUUID() (uuid string) {

	b := make([]byte, 16)
	_, err := rand.Read(b)
	if err != nil {
		fmt.Println("Error: ", err)
		return
	}

	uuid = fmt.Sprintf("%X-%X-%X-%X-%X", b[0:4], b[4:6], b[6:8], b[8:10], b[10:])

	return
}

//RandomString gets the desired length and returns a random string
func RandomString(l int) string {
	rnd.Seed(time.Now().UnixNano())
	bytes := make([]byte, l)
	for i := 0; i < l; i++ {
		bytes[i] = byte(RandInt(65, 90))
	}
	return string(bytes)
}

//RandInt returns a random integer between the min and max you set
func RandInt(min int, max int) int {
	rnd.Seed(time.Now().UnixNano())
	return min + rnd.Intn(max-min)
}

//DiffSlices takes two integer slices and returns the diff between them
func DiffSlices(X, Y []int) []int {
	m := make(map[int]int)

	for _, y := range Y {
		m[y]++
	}

	var ret []int
	for _, x := range X {
		if m[x] > 0 {
			m[x]--
			continue
		}
		ret = append(ret, x)
	}

	return ret
}

//MD5 encription
func MD5(cad string) string {
	hash := sha1.New()
	hash.Write([]byte(cad))
	return hex.EncodeToString(hash.Sum(nil))
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"flag"
	"fmt"
	"github.com/intervention-engine/ie/models"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"os"
	"strings"
)

func main() {

	flag.Parse()
	args := flag.Args()

	command := args[0]

	switch command {
	default:
		fmt.Println("Invalid command.")
		printUsage()
		return
	case "add":
		if len(args) == 3 {
			username := args[1]
			password := args[2]
			addUser(username, password)
		} else {
			fmt.Println("Invalid number of arguments for 'add' command.")
			printUsage()
			return
		}
	case "add_file":
		if len(args) == 2 {
			filepath := args[1]
			loadUsersFromFile(filepath)
		} else {
			fmt.Println("Invalid number of arguments for 'add_file' command.")
			printUsage()
			return
		}
	case "remove":
		if len(args) == 2 {
			username := args[1]
			removeUser(username)
		} else {
			fmt.Println("Invalid number of arguments for 'remove' command.")
			printUsage()
			return
		}
	case "remove_all":
		if len(args) == 1 {
			removeAllUsers()
		} else {
			fmt.Println("Invalid number of arguments for 'remove_all' command.")
			printUsage()
			return
		}
	case "change_pass":
		if len(args) == 3 {
			username := args[1]
			password := args[2]
			updatePassword(username, password)
		} else {
			fmt.Println("Invalid number of arguments for 'change_pass' command.")
			printUsage()
			return
		}
	}
}

func addUser(username, password string) {
	newuser := &models.User{
		Username: username,
		ID:       bson.NewObjectId(),
	}
	newuser.SetPassword(password)

	userCollection := getUserCollection()

	if userExists(username, userCollection) {
		fmt.Printf("User %s already exists.\n", username)
		return
	}

	err := userCollection.Insert(newuser)
	if err != nil {
		panic(err)
	} else {
		fmt.Printf("Successfully added user %s.\n", username)
	}
}

func loadUsersFromFile(filepath string) {
	file, err := os.Open(filepath)
	defer file.Close()
	if err != nil {
		panic(err)
	}

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		rawentry := scanner.Text()
		userentry := strings.Split(rawentry, ",")
		username := userentry[0]
		password := userentry[1]
		addUser(username, password)
	}
}

func removeUser(username string) {
	userCollection := getUserCollection()

	if userExists(username, userCollection) {
		err := userCollection.Remove(bson.M{"username": username})
		if err != nil {
			panic(err)
		} else {
			fmt.Printf("Successfully removed user %s.\n", username)
		}
	} else {
		fmt.Printf("User %s not found.\n", username)
	}
}

func removeAllUsers() {
	reader := bufio.NewReader(os.Stdin)
	fmt.Print("YOU ARE ABOUT TO REMOVE ALL USERS. ENTER 'Y' TO CONTINUE: ")
	resp, _ := reader.ReadString('\n')
	if resp == "Y\n" {
		userCollection := getUserCollection()
		userCollection.DropCollection()
		fmt.Println("Successfully removed all users.")
	} else {
		fmt.Println("User removal cancelled.")
	}

}

func updatePassword(username, password string) {
	userCollection := getUserCollection()

	if userExists(username, userCollection) {
		updated := &models.User{
			Username: username,
		}
		updated.SetPassword(password)

		_, err := userCollection.Upsert(bson.M{"username": username}, updated)
		if err != nil {
			panic(err)
		} else {
			fmt.Printf("Successfully updated password of user %s.\n", username)
		}
	} else {
		fmt.Printf("User %s not found.\n", username)
	}
}

func getUserCollection() *mgo.Collection {
	mongoHost := os.Getenv("MONGO_PORT_27017_TCP_ADDR")
	if mongoHost == "" {
		mongoHost = "localhost"
	}

	session, err := mgo.Dial(mongoHost)
	if err != nil {
		panic(err)
	}

	return session.DB("fhir").C("users")
}

func userExists(username string, collection *mgo.Collection) bool {
	count, err := collection.Find(bson.M{"username": username}).Count()
	if err != nil {
		panic(err)
	}
	return count > 0
}

func printUsage() {
	usageStatement := `Usage: command <arguments> (function)
	------
	add <username> <password> (add single user)
	add_file <filepath> (add users from comma separated file)
	remove <username> (remove single user)
	remove_all (remove all users)
	change_pass <username> <password> (change user's password)`

	fmt.Println(usageStatement)
}
<commit_msg>Print usage if no args are provided (instead of crashing)<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"os"
	"strings"

	"github.com/intervention-engine/ie/models"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

func main() {

	flag.Parse()
	args := flag.Args()

	if len(args) == 0 {
		printUsage()
		return
	}

	command := args[0]

	switch command {
	default:
		fmt.Println("Invalid command.")
		printUsage()
		return
	case "add":
		if len(args) == 3 {
			username := args[1]
			password := args[2]
			addUser(username, password)
		} else {
			fmt.Println("Invalid number of arguments for 'add' command.")
			printUsage()
			return
		}
	case "add_file":
		if len(args) == 2 {
			filepath := args[1]
			loadUsersFromFile(filepath)
		} else {
			fmt.Println("Invalid number of arguments for 'add_file' command.")
			printUsage()
			return
		}
	case "remove":
		if len(args) == 2 {
			username := args[1]
			removeUser(username)
		} else {
			fmt.Println("Invalid number of arguments for 'remove' command.")
			printUsage()
			return
		}
	case "remove_all":
		if len(args) == 1 {
			removeAllUsers()
		} else {
			fmt.Println("Invalid number of arguments for 'remove_all' command.")
			printUsage()
			return
		}
	case "change_pass":
		if len(args) == 3 {
			username := args[1]
			password := args[2]
			updatePassword(username, password)
		} else {
			fmt.Println("Invalid number of arguments for 'change_pass' command.")
			printUsage()
			return
		}
	}
}

func addUser(username, password string) {
	newuser := &models.User{
		Username: username,
		ID:       bson.NewObjectId(),
	}
	newuser.SetPassword(password)

	userCollection := getUserCollection()

	if userExists(username, userCollection) {
		fmt.Printf("User %s already exists.\n", username)
		return
	}

	err := userCollection.Insert(newuser)
	if err != nil {
		panic(err)
	} else {
		fmt.Printf("Successfully added user %s.\n", username)
	}
}

func loadUsersFromFile(filepath string) {
	file, err := os.Open(filepath)
	defer file.Close()
	if err != nil {
		panic(err)
	}

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		rawentry := scanner.Text()
		userentry := strings.Split(rawentry, ",")
		username := userentry[0]
		password := userentry[1]
		addUser(username, password)
	}
}

func removeUser(username string) {
	userCollection := getUserCollection()

	if userExists(username, userCollection) {
		err := userCollection.Remove(bson.M{"username": username})
		if err != nil {
			panic(err)
		} else {
			fmt.Printf("Successfully removed user %s.\n", username)
		}
	} else {
		fmt.Printf("User %s not found.\n", username)
	}
}

func removeAllUsers() {
	reader := bufio.NewReader(os.Stdin)
	fmt.Print("YOU ARE ABOUT TO REMOVE ALL USERS. ENTER 'Y' TO CONTINUE: ")
	resp, _ := reader.ReadString('\n')
	if resp == "Y\n" {
		userCollection := getUserCollection()
		userCollection.DropCollection()
		fmt.Println("Successfully removed all users.")
	} else {
		fmt.Println("User removal cancelled.")
	}

}

func updatePassword(username, password string) {
	userCollection := getUserCollection()

	if userExists(username, userCollection) {
		updated := &models.User{
			Username: username,
		}
		updated.SetPassword(password)

		_, err := userCollection.Upsert(bson.M{"username": username}, updated)
		if err != nil {
			panic(err)
		} else {
			fmt.Printf("Successfully updated password of user %s.\n", username)
		}
	} else {
		fmt.Printf("User %s not found.\n", username)
	}
}

func getUserCollection() *mgo.Collection {
	mongoHost := os.Getenv("MONGO_PORT_27017_TCP_ADDR")
	if mongoHost == "" {
		mongoHost = "localhost"
	}

	session, err := mgo.Dial(mongoHost)
	if err != nil {
		panic(err)
	}

	return session.DB("fhir").C("users")
}

func userExists(username string, collection *mgo.Collection) bool {
	count, err := collection.Find(bson.M{"username": username}).Count()
	if err != nil {
		panic(err)
	}
	return count > 0
}

func printUsage() {
	usageStatement := `Usage: command <arguments> (function)
	------
	add <username> <password> (add single user)
	add_file <filepath> (add users from comma separated file)
	remove <username> (remove single user)
	remove_all (remove all users)
	change_pass <username> <password> (change user's password)`

	fmt.Println(usageStatement)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"os"
	"os/user"
	"path/filepath"
	"strings"

	"github.com/PuerkitoBio/goquery"
	"github.com/bgentry/speakeasy"
	"github.com/bitly/go-simplejson"
)

type ikaClient http.Client

type stage struct {
	Name  string `json:"name"`
	Image string `json:"asset_path"`
}

type regulation struct {
	Regular []stage
	Gachi   []stage
}

type schedule struct {
	TimeBegin string     `json:"datetime_begin"`
	TimeEnd   string     `json:"datetime_end"`
	Stages    regulation `json:"stages"`
	GachiRule string     `json:"gachi_rule"`
}

type stageInfo struct {
	Festival  bool       `json:"festival"`
	Schedules []schedule `json:"schedule"`
}

const (
	splatoonCookieName = "_wag_session"
	splatoonDomainURL  = "https://splatoon.nintendo.net/"

	splatoonClientID = "12af3d0a3a1f441eb900411bb50a835a"
	splatoonOauthURL = "https://splatoon.nintendo.net/users/auth/nintendo"
	nintendoOauthURL = "https://id.nintendo.net/oauth/authorize"

	splatoonScheduleAPI = "https://splatoon.nintendo.net/schedule/index.json"
)

func checkJSONError(data []byte) error {
	js, err := simplejson.NewJson(data)
	if err != nil {
		return err
	}

	if info := js.Get("error").MustString(); len(info) != 0 {
		return errors.New(info)
	}
	return nil
}

func decodeJSONSchedule(data []byte) (*stageInfo, error) {
	info := &stageInfo{}
	if err := json.Unmarshal(data, info); err != nil {
		return nil, err
	}
	return info, nil
}

func getSessionFromCookie(resp *http.Response) string {
	for _, cookie := range resp.Cookies() {
		if cookie.Name == "_wag_session" {
			return cookie.Value
		}
	}
	return ""
}

func getOauthQuery(oarthURL string, id string, password string) (url.Values, error) {
	doc, err := goquery.NewDocument(oarthURL)

	if err != nil {
		return nil, err
	}

	query := url.Values{}
	doc.Find("input").Each(func(_ int, s *goquery.Selection) {
		name, ok := s.Attr("name")
		if !ok {
			return
		}

		// parse from docment
		switch name {
		case "cliend_id":
			if v, ok := s.Attr("value"); ok {
				query.Add(name, v)
			}
		case "state":
			if v, ok := s.Attr("value"); ok {
				query.Add(name, v)
			}
		case "redirect_uri":
			if v, ok := s.Attr("value"); ok {
				query.Add(name, v)
			}
		case "response_type":
			if v, ok := s.Attr("value"); ok {
				query.Add(name, v)
			}
		}
	})

	// fixed value
	query.Add("client_id", splatoonClientID)
	query.Add("nintendo_authenticate", "")
	query.Add("nintendo_authorize", "")
	query.Add("scope", "")
	query.Add("lang", "ja-JP")

	// user info
	query.Add("username", id)
	query.Add("password", password)

	return query, nil
}

func createClient() (*ikaClient, error) {
	jar, err := cookiejar.New(nil)
	if err != nil {
		return nil, err
	}
	client := &http.Client{Jar: jar}
	return (*ikaClient)(client), nil
}

func (c *ikaClient) setSession(session string) {
	uri, _ := url.Parse(splatoonDomainURL)
	(*http.Client)(c).Jar.SetCookies(uri, []*http.Cookie{
		&http.Cookie{
			Secure:   true,
			HttpOnly: true,
			Name:     splatoonCookieName,
			Value:    session,
		}})
}

func (c *ikaClient) login(name string, password string) (string, error) {
	query, err := getOauthQuery(splatoonOauthURL, name, password)
	if err != nil {
		return "", err
	}

	resp, err := (*http.Client)(c).PostForm(nintendoOauthURL, query)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return "", errors.New(resp.Status)
	}

	session := getSessionFromCookie(resp)

	return session, nil
}

func (c *ikaClient) getStageInfo() (*stageInfo, error) {

	resp, err := (*http.Client)(c).Get(splatoonScheduleAPI)

	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

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

	if err = checkJSONError(body); err != nil {
		return nil, err
	}

	return decodeJSONSchedule(body)
}

func getCacheFile() (string, error) {
	me, err := user.Current()
	if err != nil {
		return "", err
	}
	return filepath.Join(me.HomeDir, ".ikaring.session"), nil
}

func readSession(path string) (string, error) {
	buff, err := ioutil.ReadFile(path)
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(string(buff)), nil
}

func writeSession(path string, session string) error {
	return ioutil.WriteFile(path, []byte(session), 600)
}

func getAccount(r io.Reader) (string, string, error) {
	scanner := bufio.NewScanner(r)
	for {
		fmt.Print("User: ")
		if scanner.Scan() {
			break
		}
	}
	username := scanner.Text()
	password, err := speakeasy.Ask("Password: ")
	return username, password, err
}

func main() {
	client, err := createClient()
	if err != nil {
		fmt.Println(err)
		return
	}

	path, err := getCacheFile()
	if err != nil {
		fmt.Println(err)
		return
	}

	session, err := readSession(path)
	if err == nil && len(session) > 0 {
		client.setSession(session)
	} else {
		username, password, err := getAccount(os.Stdin)
		session, err = client.login(username, password)
		if err != nil {
			fmt.Println(err)
			return
		}
	}

	if len(session) <= 0 {
		fmt.Println("ログインできませんでした")
		return
	}

	writeSession(path, session)

	info, err := client.getStageInfo()
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(info)
}
<commit_msg>fix to format stage schedules<commit_after>package main

import (
	"bufio"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/http/cookiejar"
	"net/url"
	"os"
	"os/user"
	"path/filepath"
	"strings"
	"time"

	"github.com/PuerkitoBio/goquery"
	"github.com/bgentry/speakeasy"
	"github.com/bitly/go-simplejson"
)

type ikaClient http.Client

type stage struct {
	Name  string `json:"name"`
	Image string `json:"asset_path"`
}

type regulation struct {
	Regular []stage
	Gachi   []stage
}

type schedule struct {
	TimeBegin time.Time  `json:"datetime_begin"`
	TimeEnd   time.Time  `json:"datetime_end"`
	Stages    regulation `json:"stages"`
	GachiRule string     `json:"gachi_rule"`
}

type stageInfo struct {
	Festival  bool       `json:"festival"`
	Schedules []schedule `json:"schedule"`
}

const (
	splatoonCookieName = "_wag_session"
	splatoonDomainURL  = "https://splatoon.nintendo.net/"

	splatoonClientID = "12af3d0a3a1f441eb900411bb50a835a"
	splatoonOauthURL = "https://splatoon.nintendo.net/users/auth/nintendo"
	nintendoOauthURL = "https://id.nintendo.net/oauth/authorize"

	splatoonScheduleAPI = "https://splatoon.nintendo.net/schedule/index.json"
)

func checkJSONError(data []byte) error {
	js, err := simplejson.NewJson(data)
	if err != nil {
		return err
	}

	if info := js.Get("error").MustString(); len(info) != 0 {
		return errors.New(info)
	}
	return nil
}

func decodeJSONSchedule(data []byte) (*stageInfo, error) {
	info := &stageInfo{}
	if err := json.Unmarshal(data, info); err != nil {
		return nil, err
	}
	return info, nil
}

func getSessionFromCookie(resp *http.Response) string {
	for _, cookie := range resp.Cookies() {
		if cookie.Name == "_wag_session" {
			return cookie.Value
		}
	}
	return ""
}

func getOauthQuery(oarthURL string, id string, password string) (url.Values, error) {
	doc, err := goquery.NewDocument(oarthURL)

	if err != nil {
		return nil, err
	}

	query := url.Values{}
	doc.Find("input").Each(func(_ int, s *goquery.Selection) {
		name, ok := s.Attr("name")
		if !ok {
			return
		}

		// parse from docment
		switch name {
		case "cliend_id":
			if v, ok := s.Attr("value"); ok {
				query.Add(name, v)
			}
		case "state":
			if v, ok := s.Attr("value"); ok {
				query.Add(name, v)
			}
		case "redirect_uri":
			if v, ok := s.Attr("value"); ok {
				query.Add(name, v)
			}
		case "response_type":
			if v, ok := s.Attr("value"); ok {
				query.Add(name, v)
			}
		}
	})

	// fixed value
	query.Add("client_id", splatoonClientID)
	query.Add("nintendo_authenticate", "")
	query.Add("nintendo_authorize", "")
	query.Add("scope", "")
	query.Add("lang", "ja-JP")

	// user info
	query.Add("username", id)
	query.Add("password", password)

	return query, nil
}

func createClient() (*ikaClient, error) {
	jar, err := cookiejar.New(nil)
	if err != nil {
		return nil, err
	}
	client := &http.Client{Jar: jar}
	return (*ikaClient)(client), nil
}

func (c *ikaClient) setSession(session string) {
	uri, _ := url.Parse(splatoonDomainURL)
	(*http.Client)(c).Jar.SetCookies(uri, []*http.Cookie{
		&http.Cookie{
			Secure:   true,
			HttpOnly: true,
			Name:     splatoonCookieName,
			Value:    session,
		}})
}

func (c *ikaClient) login(name string, password string) (string, error) {
	query, err := getOauthQuery(splatoonOauthURL, name, password)
	if err != nil {
		return "", err
	}

	resp, err := (*http.Client)(c).PostForm(nintendoOauthURL, query)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	if resp.StatusCode != 200 {
		return "", errors.New(resp.Status)
	}

	session := getSessionFromCookie(resp)

	return session, nil
}

func (c *ikaClient) getStageInfo() (*stageInfo, error) {

	resp, err := (*http.Client)(c).Get(splatoonScheduleAPI)

	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

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

	if err = checkJSONError(body); err != nil {
		return nil, err
	}

	return decodeJSONSchedule(body)
}

func getCacheFile() (string, error) {
	me, err := user.Current()
	if err != nil {
		return "", err
	}
	return filepath.Join(me.HomeDir, ".ikaring.session"), nil
}

func readSession(path string) (string, error) {
	buff, err := ioutil.ReadFile(path)
	if err != nil {
		return "", err
	}
	return strings.TrimSpace(string(buff)), nil
}

func writeSession(path string, session string) error {
	return ioutil.WriteFile(path, []byte(session), 600)
}

func getAccount(r io.Reader) (string, string, error) {
	scanner := bufio.NewScanner(r)
	for {
		fmt.Print("User: ")
		if scanner.Scan() {
			break
		}
	}
	username := scanner.Text()
	password, err := speakeasy.Ask("Password: ")
	return username, password, err
}

func (s schedule) String() string {
	timefmt := "01/02 15:04:05"
	str := fmt.Sprintf("%s - %s\n",
		s.TimeBegin.Format(timefmt), s.TimeEnd.Format(timefmt))

	str += "レギュラーマッチ\n"
	for i, stage := range s.Stages.Regular {
		if i == 0 {
			str += "\t"
		} else {
			str += ", "
		}
		str += stage.Name
	}
	str += "\n"

	str += fmt.Sprintf("ガチマッチ (%s)\n", s.GachiRule)
	for i, stage := range s.Stages.Gachi {
		if i == 0 {
			str += "\t"
		} else {
			str += ", "
		}
		str += stage.Name
	}
	str += "\n"
	return str
}

func main() {
	client, err := createClient()
	if err != nil {
		fmt.Println(err)
		return
	}

	path, err := getCacheFile()
	if err != nil {
		fmt.Println(err)
		return
	}

	session, err := readSession(path)
	if err == nil && len(session) > 0 {
		client.setSession(session)
	} else {
		username, password, err := getAccount(os.Stdin)
		session, err = client.login(username, password)
		if err != nil {
			fmt.Println(err)
			return
		}
	}

	if len(session) <= 0 {
		fmt.Println("ログインできませんでした")
		return
	}

	writeSession(path, session)

	info, err := client.getStageInfo()
	if err != nil {
		fmt.Println(err)
		return
	}

	for _, s := range info.Schedules {
		fmt.Printf("%v\n", s)
	}
}
<|endoftext|>


<commit_before>package pacer

import (
	"fmt"
	"testing"
	"time"

	"github.com/ncw/rclone/fs"
)

func TestNew(t *testing.T) {
	p := New()
	if p.minSleep != 10*time.Millisecond {
		t.Errorf("minSleep")
	}
	if p.maxSleep != 2*time.Second {
		t.Errorf("maxSleep")
	}
	if p.sleepTime != p.minSleep {
		t.Errorf("sleepTime")
	}
	if p.retries != 10 {
		t.Errorf("retries")
	}
	if p.decayConstant != 2 {
		t.Errorf("decayConstant")
	}
	if cap(p.pacer) != 1 {
		t.Errorf("pacer 1")
	}
	if len(p.pacer) != 1 {
		t.Errorf("pacer 2")
	}
	if fmt.Sprintf("%p", p.calculatePace) != fmt.Sprintf("%p", p.defaultPacer) {
		t.Errorf("calculatePace")
	}
	if p.maxConnections != fs.Config.Checkers+fs.Config.Transfers {
		t.Errorf("maxConnections")
	}
	if cap(p.connTokens) != fs.Config.Checkers+fs.Config.Transfers {
		t.Errorf("connTokens")
	}
	if p.consecutiveRetries != 0 {
		t.Errorf("consecutiveRetries")
	}
}

func TestSetMinSleep(t *testing.T) {
	p := New().SetMinSleep(1 * time.Millisecond)
	if p.minSleep != 1*time.Millisecond {
		t.Errorf("didn't set")
	}
}

func TestSetMaxSleep(t *testing.T) {
	p := New().SetMaxSleep(100 * time.Second)
	if p.maxSleep != 100*time.Second {
		t.Errorf("didn't set")
	}
}

func TestMaxConnections(t *testing.T) {
	p := New().SetMaxConnections(20)
	if p.maxConnections != 20 {
		t.Errorf("maxConnections")
	}
	if cap(p.connTokens) != 20 {
		t.Errorf("connTokens")
	}
	p.SetMaxConnections(0)
	if p.maxConnections != 0 {
		t.Errorf("maxConnections is not 0")
	}
	if p.connTokens != nil {
		t.Errorf("connTokens is not nil")
	}
}

func TestSetDecayConstant(t *testing.T) {
	p := New().SetDecayConstant(17)
	if p.decayConstant != 17 {
		t.Errorf("didn't set")
	}
}

func TestSetRetries(t *testing.T) {
	p := New().SetRetries(18)
	if p.retries != 18 {
		t.Errorf("didn't set")
	}
}

func TestSetPacer(t *testing.T) {
	p := New().SetPacer(AmazonCloudDrivePacer)
	if fmt.Sprintf("%p", p.calculatePace) != fmt.Sprintf("%p", p.acdPacer) {
		t.Errorf("calculatePace is not acdPacer")
	}
	p.SetPacer(DefaultPacer)
	if fmt.Sprintf("%p", p.calculatePace) != fmt.Sprintf("%p", p.defaultPacer) {
		t.Errorf("calculatePace is not defaultPacer")
	}
}

// emptyTokens empties the pacer of all its tokens
func emptyTokens(p *Pacer) {
	for len(p.pacer) != 0 {
		<-p.pacer
	}
	for len(p.connTokens) != 0 {
		<-p.connTokens
	}
}

// waitForPace waits for duration for the pace to arrive
// returns the time that it arrived or a zero time
func waitForPace(p *Pacer, duration time.Duration) (when time.Time) {
	select {
	case <-time.After(duration):
		return
	case <-p.pacer:
		return time.Now()
	}
}

func TestBeginCall(t *testing.T) {
	p := New().SetMaxConnections(10).SetMinSleep(1 * time.Millisecond)
	emptyTokens(p)
	go p.beginCall()
	if !waitForPace(p, 10*time.Millisecond).IsZero() {
		t.Errorf("beginSleep fired too early #1")
	}
	startTime := time.Now()
	p.pacer <- struct{}{}
	time.Sleep(1 * time.Millisecond)
	connTime := time.Now()
	p.connTokens <- struct{}{}
	time.Sleep(1 * time.Millisecond)
	paceTime := waitForPace(p, 10*time.Millisecond)
	if paceTime.IsZero() {
		t.Errorf("beginSleep didn't fire")
	} else if paceTime.Sub(startTime) < 0 {
		t.Errorf("pace arrived before returning pace token")
	} else if paceTime.Sub(connTime) < 0 {
		t.Errorf("pace arrived before sending conn token")
	}
}

func TestBeginCallZeroConnections(t *testing.T) {
	p := New().SetMaxConnections(0).SetMinSleep(1 * time.Millisecond)
	emptyTokens(p)
	go p.beginCall()
	if !waitForPace(p, 10*time.Millisecond).IsZero() {
		t.Errorf("beginSleep fired too early #1")
	}
	startTime := time.Now()
	p.pacer <- struct{}{}
	time.Sleep(1 * time.Millisecond)
	paceTime := waitForPace(p, 10*time.Millisecond)
	if paceTime.IsZero() {
		t.Errorf("beginSleep didn't fire")
	} else if paceTime.Sub(startTime) < 0 {
		t.Errorf("pace arrived before returning pace token")
	}
}

func TestDefaultPacer(t *testing.T) {
	p := New().SetMinSleep(time.Millisecond).SetPacer(DefaultPacer).SetMaxSleep(time.Second).SetDecayConstant(2)
	for _, test := range []struct {
		in    time.Duration
		retry bool
		want  time.Duration
	}{
		{time.Millisecond, true, 2 * time.Millisecond},
		{time.Second, true, time.Second},
		{(3 * time.Second) / 4, true, time.Second},
		{time.Second, false, 750 * time.Millisecond},
		{1000 * time.Microsecond, false, time.Millisecond},
		{1200 * time.Microsecond, false, time.Millisecond},
	} {
		p.sleepTime = test.in
		p.defaultPacer(test.retry)
		got := p.sleepTime
		if got != test.want {
			t.Errorf("bad sleep want %v got %v", test.want, got)
		}
	}

}

func TestAmazonCloudDrivePacer(t *testing.T) {
	p := New().SetMinSleep(time.Millisecond).SetPacer(AmazonCloudDrivePacer).SetMaxSleep(time.Second).SetDecayConstant(2)
	// Do lots of times because of the random number!
	for _, test := range []struct {
		in                 time.Duration
		consecutiveRetries int
		retry              bool
		want               time.Duration
	}{
		{time.Millisecond, 0, true, time.Millisecond},
		{10 * time.Millisecond, 0, true, time.Millisecond},
		{1 * time.Second, 1, true, 500 * time.Millisecond},
		{1 * time.Second, 2, true, 1 * time.Second},
		{1 * time.Second, 3, true, 2 * time.Second},
		{1 * time.Second, 4, true, 4 * time.Second},
		{1 * time.Second, 5, true, 8 * time.Second},
		{1 * time.Second, 6, true, 16 * time.Second},
		{1 * time.Second, 7, true, 32 * time.Second},
		{1 * time.Second, 8, true, 64 * time.Second},
		{1 * time.Second, 9, true, 128 * time.Second},
		{1 * time.Second, 10, true, 128 * time.Second},
		{1 * time.Second, 11, true, 128 * time.Second},
	} {
		const n = 1000
		var sum time.Duration
		// measure average time over n cycles
		for i := 0; i < n; i++ {
			p.sleepTime = test.in
			p.consecutiveRetries = test.consecutiveRetries
			p.acdPacer(test.retry)
			sum += p.sleepTime
		}
		got := sum / n
		//t.Logf("%+v: got = %v", test, got)
		if got < (test.want*9)/10 || got > (test.want*11)/10 {
			t.Fatalf("%+v: bad sleep want %v+/-10%% got %v", test, test.want, got)
		}
	}
}

func TestEndCall(t *testing.T) {
	p := New().SetMaxConnections(5)
	emptyTokens(p)
	p.consecutiveRetries = 1
	p.endCall(true)
	if len(p.connTokens) != 1 {
		t.Errorf("Expecting 1 token")
	}
	if p.consecutiveRetries != 2 {
		t.Errorf("Bad consecutive retries")
	}
}

func TestEndCallZeroConnections(t *testing.T) {
	p := New().SetMaxConnections(0)
	emptyTokens(p)
	p.consecutiveRetries = 1
	p.endCall(false)
	if len(p.connTokens) != 0 {
		t.Errorf("Expecting 0 token")
	}
	if p.consecutiveRetries != 0 {
		t.Errorf("Bad consecutive retries")
	}
}

var errFoo = fmt.Errorf("Foo")

type dummyPaced struct {
	retry  bool
	called int
}

func (dp *dummyPaced) fn() (bool, error) {
	dp.called++
	return dp.retry, errFoo
}

func Test_callNoRetry(t *testing.T) {
	p := New().SetMinSleep(time.Millisecond).SetMaxSleep(2 * time.Millisecond)

	dp := &dummyPaced{retry: false}
	err := p.call(dp.fn, 10)
	if dp.called != 1 {
		t.Errorf("called want %d got %d", 1, dp.called)
	}
	if err != errFoo {
		t.Errorf("err want %v got %v", errFoo, err)
	}
}

func Test_callRetry(t *testing.T) {
	p := New().SetMinSleep(time.Millisecond).SetMaxSleep(2 * time.Millisecond)

	dp := &dummyPaced{retry: true}
	err := p.call(dp.fn, 10)
	if dp.called != 10 {
		t.Errorf("called want %d got %d", 10, dp.called)
	}
	if err == errFoo {
		t.Errorf("err didn't want %v got %v", errFoo, err)
	}
	_, ok := err.(fs.Retry)
	if !ok {
		t.Errorf("didn't return a retry error")
	}
}

func TestCall(t *testing.T) {
	p := New().SetMinSleep(time.Millisecond).SetMaxSleep(2 * time.Millisecond).SetRetries(20)

	dp := &dummyPaced{retry: true}
	err := p.Call(dp.fn)
	if dp.called != 20 {
		t.Errorf("called want %d got %d", 20, dp.called)
	}
	_, ok := err.(fs.Retry)
	if !ok {
		t.Errorf("didn't return a retry error")
	}
}

func TestCallNoRetry(t *testing.T) {
	p := New().SetMinSleep(time.Millisecond).SetMaxSleep(2 * time.Millisecond).SetRetries(20)

	dp := &dummyPaced{retry: true}
	err := p.CallNoRetry(dp.fn)
	if dp.called != 1 {
		t.Errorf("called want %d got %d", 1, dp.called)
	}
	_, ok := err.(fs.Retry)
	if !ok {
		t.Errorf("didn't return a retry error")
	}
}
<commit_msg>Fix pacer tests<commit_after>package pacer

import (
	"fmt"
	"testing"
	"time"

	"github.com/ncw/rclone/fs"
)

func TestNew(t *testing.T) {
	const expectedRetries = 7
	fs.Config.LowLevelRetries = expectedRetries
	p := New()
	if p.minSleep != 10*time.Millisecond {
		t.Errorf("minSleep")
	}
	if p.maxSleep != 2*time.Second {
		t.Errorf("maxSleep")
	}
	if p.sleepTime != p.minSleep {
		t.Errorf("sleepTime")
	}
	if p.retries != expectedRetries {
		t.Errorf("retries want %v got %v", expectedRetries, p.retries)
	}
	if p.decayConstant != 2 {
		t.Errorf("decayConstant")
	}
	if cap(p.pacer) != 1 {
		t.Errorf("pacer 1")
	}
	if len(p.pacer) != 1 {
		t.Errorf("pacer 2")
	}
	if fmt.Sprintf("%p", p.calculatePace) != fmt.Sprintf("%p", p.defaultPacer) {
		t.Errorf("calculatePace")
	}
	if p.maxConnections != fs.Config.Checkers+fs.Config.Transfers {
		t.Errorf("maxConnections")
	}
	if cap(p.connTokens) != fs.Config.Checkers+fs.Config.Transfers {
		t.Errorf("connTokens")
	}
	if p.consecutiveRetries != 0 {
		t.Errorf("consecutiveRetries")
	}
}

func TestSetMinSleep(t *testing.T) {
	p := New().SetMinSleep(1 * time.Millisecond)
	if p.minSleep != 1*time.Millisecond {
		t.Errorf("didn't set")
	}
}

func TestSetMaxSleep(t *testing.T) {
	p := New().SetMaxSleep(100 * time.Second)
	if p.maxSleep != 100*time.Second {
		t.Errorf("didn't set")
	}
}

func TestMaxConnections(t *testing.T) {
	p := New().SetMaxConnections(20)
	if p.maxConnections != 20 {
		t.Errorf("maxConnections")
	}
	if cap(p.connTokens) != 20 {
		t.Errorf("connTokens")
	}
	p.SetMaxConnections(0)
	if p.maxConnections != 0 {
		t.Errorf("maxConnections is not 0")
	}
	if p.connTokens != nil {
		t.Errorf("connTokens is not nil")
	}
}

func TestSetDecayConstant(t *testing.T) {
	p := New().SetDecayConstant(17)
	if p.decayConstant != 17 {
		t.Errorf("didn't set")
	}
}

func TestSetRetries(t *testing.T) {
	p := New().SetRetries(18)
	if p.retries != 18 {
		t.Errorf("didn't set")
	}
}

func TestSetPacer(t *testing.T) {
	p := New().SetPacer(AmazonCloudDrivePacer)
	if fmt.Sprintf("%p", p.calculatePace) != fmt.Sprintf("%p", p.acdPacer) {
		t.Errorf("calculatePace is not acdPacer")
	}
	p.SetPacer(DefaultPacer)
	if fmt.Sprintf("%p", p.calculatePace) != fmt.Sprintf("%p", p.defaultPacer) {
		t.Errorf("calculatePace is not defaultPacer")
	}
}

// emptyTokens empties the pacer of all its tokens
func emptyTokens(p *Pacer) {
	for len(p.pacer) != 0 {
		<-p.pacer
	}
	for len(p.connTokens) != 0 {
		<-p.connTokens
	}
}

// waitForPace waits for duration for the pace to arrive
// returns the time that it arrived or a zero time
func waitForPace(p *Pacer, duration time.Duration) (when time.Time) {
	select {
	case <-time.After(duration):
		return
	case <-p.pacer:
		return time.Now()
	}
}

func TestBeginCall(t *testing.T) {
	p := New().SetMaxConnections(10).SetMinSleep(1 * time.Millisecond)
	emptyTokens(p)
	go p.beginCall()
	if !waitForPace(p, 10*time.Millisecond).IsZero() {
		t.Errorf("beginSleep fired too early #1")
	}
	startTime := time.Now()
	p.pacer <- struct{}{}
	time.Sleep(1 * time.Millisecond)
	connTime := time.Now()
	p.connTokens <- struct{}{}
	time.Sleep(1 * time.Millisecond)
	paceTime := waitForPace(p, 10*time.Millisecond)
	if paceTime.IsZero() {
		t.Errorf("beginSleep didn't fire")
	} else if paceTime.Sub(startTime) < 0 {
		t.Errorf("pace arrived before returning pace token")
	} else if paceTime.Sub(connTime) < 0 {
		t.Errorf("pace arrived before sending conn token")
	}
}

func TestBeginCallZeroConnections(t *testing.T) {
	p := New().SetMaxConnections(0).SetMinSleep(1 * time.Millisecond)
	emptyTokens(p)
	go p.beginCall()
	if !waitForPace(p, 10*time.Millisecond).IsZero() {
		t.Errorf("beginSleep fired too early #1")
	}
	startTime := time.Now()
	p.pacer <- struct{}{}
	time.Sleep(1 * time.Millisecond)
	paceTime := waitForPace(p, 10*time.Millisecond)
	if paceTime.IsZero() {
		t.Errorf("beginSleep didn't fire")
	} else if paceTime.Sub(startTime) < 0 {
		t.Errorf("pace arrived before returning pace token")
	}
}

func TestDefaultPacer(t *testing.T) {
	p := New().SetMinSleep(time.Millisecond).SetPacer(DefaultPacer).SetMaxSleep(time.Second).SetDecayConstant(2)
	for _, test := range []struct {
		in    time.Duration
		retry bool
		want  time.Duration
	}{
		{time.Millisecond, true, 2 * time.Millisecond},
		{time.Second, true, time.Second},
		{(3 * time.Second) / 4, true, time.Second},
		{time.Second, false, 750 * time.Millisecond},
		{1000 * time.Microsecond, false, time.Millisecond},
		{1200 * time.Microsecond, false, time.Millisecond},
	} {
		p.sleepTime = test.in
		p.defaultPacer(test.retry)
		got := p.sleepTime
		if got != test.want {
			t.Errorf("bad sleep want %v got %v", test.want, got)
		}
	}

}

func TestAmazonCloudDrivePacer(t *testing.T) {
	p := New().SetMinSleep(time.Millisecond).SetPacer(AmazonCloudDrivePacer).SetMaxSleep(time.Second).SetDecayConstant(2)
	// Do lots of times because of the random number!
	for _, test := range []struct {
		in                 time.Duration
		consecutiveRetries int
		retry              bool
		want               time.Duration
	}{
		{time.Millisecond, 0, true, time.Millisecond},
		{10 * time.Millisecond, 0, true, time.Millisecond},
		{1 * time.Second, 1, true, 500 * time.Millisecond},
		{1 * time.Second, 2, true, 1 * time.Second},
		{1 * time.Second, 3, true, 2 * time.Second},
		{1 * time.Second, 4, true, 4 * time.Second},
		{1 * time.Second, 5, true, 8 * time.Second},
		{1 * time.Second, 6, true, 16 * time.Second},
		{1 * time.Second, 7, true, 32 * time.Second},
		{1 * time.Second, 8, true, 64 * time.Second},
		{1 * time.Second, 9, true, 128 * time.Second},
		{1 * time.Second, 10, true, 128 * time.Second},
		{1 * time.Second, 11, true, 128 * time.Second},
	} {
		const n = 1000
		var sum time.Duration
		// measure average time over n cycles
		for i := 0; i < n; i++ {
			p.sleepTime = test.in
			p.consecutiveRetries = test.consecutiveRetries
			p.acdPacer(test.retry)
			sum += p.sleepTime
		}
		got := sum / n
		//t.Logf("%+v: got = %v", test, got)
		if got < (test.want*9)/10 || got > (test.want*11)/10 {
			t.Fatalf("%+v: bad sleep want %v+/-10%% got %v", test, test.want, got)
		}
	}
}

func TestEndCall(t *testing.T) {
	p := New().SetMaxConnections(5)
	emptyTokens(p)
	p.consecutiveRetries = 1
	p.endCall(true)
	if len(p.connTokens) != 1 {
		t.Errorf("Expecting 1 token")
	}
	if p.consecutiveRetries != 2 {
		t.Errorf("Bad consecutive retries")
	}
}

func TestEndCallZeroConnections(t *testing.T) {
	p := New().SetMaxConnections(0)
	emptyTokens(p)
	p.consecutiveRetries = 1
	p.endCall(false)
	if len(p.connTokens) != 0 {
		t.Errorf("Expecting 0 token")
	}
	if p.consecutiveRetries != 0 {
		t.Errorf("Bad consecutive retries")
	}
}

var errFoo = fmt.Errorf("Foo")

type dummyPaced struct {
	retry  bool
	called int
}

func (dp *dummyPaced) fn() (bool, error) {
	dp.called++
	return dp.retry, errFoo
}

func Test_callNoRetry(t *testing.T) {
	p := New().SetMinSleep(time.Millisecond).SetMaxSleep(2 * time.Millisecond)

	dp := &dummyPaced{retry: false}
	err := p.call(dp.fn, 10)
	if dp.called != 1 {
		t.Errorf("called want %d got %d", 1, dp.called)
	}
	if err != errFoo {
		t.Errorf("err want %v got %v", errFoo, err)
	}
}

func Test_callRetry(t *testing.T) {
	p := New().SetMinSleep(time.Millisecond).SetMaxSleep(2 * time.Millisecond)

	dp := &dummyPaced{retry: true}
	err := p.call(dp.fn, 10)
	if dp.called != 10 {
		t.Errorf("called want %d got %d", 10, dp.called)
	}
	if err == errFoo {
		t.Errorf("err didn't want %v got %v", errFoo, err)
	}
	_, ok := err.(fs.Retry)
	if !ok {
		t.Errorf("didn't return a retry error")
	}
}

func TestCall(t *testing.T) {
	p := New().SetMinSleep(time.Millisecond).SetMaxSleep(2 * time.Millisecond).SetRetries(20)

	dp := &dummyPaced{retry: true}
	err := p.Call(dp.fn)
	if dp.called != 20 {
		t.Errorf("called want %d got %d", 20, dp.called)
	}
	_, ok := err.(fs.Retry)
	if !ok {
		t.Errorf("didn't return a retry error")
	}
}

func TestCallNoRetry(t *testing.T) {
	p := New().SetMinSleep(time.Millisecond).SetMaxSleep(2 * time.Millisecond).SetRetries(20)

	dp := &dummyPaced{retry: true}
	err := p.CallNoRetry(dp.fn)
	if dp.called != 1 {
		t.Errorf("called want %d got %d", 1, dp.called)
	}
	_, ok := err.(fs.Retry)
	if !ok {
		t.Errorf("didn't return a retry error")
	}
}
<|endoftext|>


<commit_before>package v1payload

// CreateSecretInput is the input for creating a secret
type CreateSecretInput struct {
	ProjectID string `json:"project_id" valid:"required"`
	Name      string `json:"name" valid:"required"`
	Key       string `json:"key" valid:"required"`
	Value     string `json:"value" valid:"required"`
}

// CreateSecretOutput is the output from creating a secret
type CreateSecretOutput struct {
	ProjectID string `json:"project_id" valid:"required"`
	Name      string `json:"name" valid:"required"`
	Key       string `json:"key" valid:"required"`
	Value     string `json:"value" valid:"required"`
}

// GetSecretInput is the input for getting a secret
type GetSecretInput struct {
	ProjectID string `json:"project_id" valid:"required"`
	Name      string `json:"name" valid:"required"`
}

// GetSecretOutput is the output from getting a secret
type GetSecretOutput struct {
	ProjectID string `json:"project_id" valid:"required"`
	Name      string `json:"name" valid:"required"`
	Key       string `json:"key" valid:"required"`
	Value     string `json:"value" valid:"required"`
}

// DeleteSecretInput is the input for deleting a secret
type DeleteSecretInput struct {
	ProjectID string `json:"project_id" valid:"required"`
	Name      string `json:"name" valid:"required"`
}

// DeleteSecretOutput is the output from deleting a secret
type DeleteSecretOutput struct {
}

//SecretSummary is summary of a secret
type SecretSummary struct {
	ProjectID string `json:"project_id" valid:"required"`
	Name      string `json:"name" valid:"required"`
	Key       string `json:"key" valid:"required"`
	Value     string `json:"value" valid:"required"`
}

// ListSecretsInput is the input for listing secrets
type ListSecretsInput struct {
	ProjectID string `json:"project_id" valid:"required"`
}

// ListSecretsOutput is the output from listing secrets
type ListSecretsOutput struct {
	ProjectID string           `json:"project_id" valid:"required"`
	Secrets   []*SecretSummary `json:"secrets" valid:"required"`
}
<commit_msg>Change get to describe in secret payload<commit_after>package v1payload

// CreateSecretInput is the input for creating a secret
type CreateSecretInput struct {
	ProjectID string `json:"project_id" valid:"required"`
	Name      string `json:"name" valid:"required"`
	Key       string `json:"key" valid:"required"`
	Value     string `json:"value" valid:"required"`
}

// CreateSecretOutput is the output from creating a secret
type CreateSecretOutput struct {
	ProjectID string `json:"project_id" valid:"required"`
	Name      string `json:"name" valid:"required"`
	Key       string `json:"key" valid:"required"`
	Value     string `json:"value" valid:"required"`
}

// DescribeSecretInput is the input for describing a secret
type DescribeSecretInput struct {
	ProjectID string `json:"project_id" valid:"required"`
	Name      string `json:"name" valid:"required"`
}

// DescribeSecretOutput is the output from describing a secret
type DescribeSecretOutput struct {
	ProjectID string `json:"project_id" valid:"required"`
	Name      string `json:"name" valid:"required"`
	Key       string `json:"key" valid:"required"`
	Value     string `json:"value" valid:"required"`
}

// DeleteSecretInput is the input for deleting a secret
type DeleteSecretInput struct {
	ProjectID string `json:"project_id" valid:"required"`
	Name      string `json:"name" valid:"required"`
}

// DeleteSecretOutput is the output from deleting a secret
type DeleteSecretOutput struct {
}

//SecretSummary is summary of a secret
type SecretSummary struct {
	ProjectID string `json:"project_id" valid:"required"`
	Name      string `json:"name" valid:"required"`
	Key       string `json:"key" valid:"required"`
	Value     string `json:"value" valid:"required"`
}

// ListSecretsInput is the input for listing secrets
type ListSecretsInput struct {
	ProjectID string `json:"project_id" valid:"required"`
}

// ListSecretsOutput is the output from listing secrets
type ListSecretsOutput struct {
	ProjectID string           `json:"project_id" valid:"required"`
	Secrets   []*SecretSummary `json:"secrets" valid:"required"`
}
<|endoftext|>


<commit_before>package main

import (
    "archive/zip"
    "fmt"
    "os"
)

func main() {
    if len(os.Args) > 1 {
        jarFileName := os.Args[1]
        handleJar(jarFileName)
    }
}

func handleJar(jarFileName string) {
    fmt.Printf("jar: %v\n", jarFileName)

    // open jar
    r, err := zip.OpenReader(jarFileName) // func OpenReader(name string) (*ReadCloser, error)
    if err != nil {
        panic(err.Error())
    }
    defer r.Close()

    // find class
    for _, f := range r.File {
        fmt.Printf("%v\n", f.Name)
        // if f.Name == className {
        //     rc, err := f.Open() // func (f *File) Open() (rc io.ReadCloser, err error)
        //     if err != nil {
        //         return nil, err
        //     }
        //     // read class data
        //     data, err := ioutil.ReadAll(rc) // func ReadAll(r io.Reader) ([]byte, error)
        //     rc.Close()
        //     if err != nil {
        //         return nil, err
        //     }
        //     return data, nil
        // }
    }
}
<commit_msg>print classes in jar..<commit_after>package main

import (
    "archive/zip"
    "fmt"
    "io/ioutil"
    "os"
    "strings"
    "jvmgo/classfile"
)

func main() {
    if len(os.Args) > 1 {
        jarFileName := os.Args[1]
        handleJar(jarFileName)
    }
}

func handleJar(jarFileName string) {
    fmt.Printf("jar: %v\n", jarFileName)

    // open jar
    r, err := zip.OpenReader(jarFileName) // func OpenReader(name string) (*ReadCloser, error)
    if err != nil {
        panic(err.Error())
    }
    defer r.Close()

    // find classes
    for _, f := range r.File {
        if strings.HasSuffix(f.Name, ".class") {
            handleClass(f)
        }
    }
}

func handleClass(f *zip.File) {
    //fmt.Printf("%v\n", f.Name)

    // open classfile
    rc, err := f.Open() // func (f *File) Open() (rc io.ReadCloser, err error)
    if err != nil {
        panic(err.Error())
    }

    // read class data
    data, err := ioutil.ReadAll(rc) // func ReadAll(r io.Reader) ([]byte, error)
    rc.Close()
    if err != nil {
        panic(err.Error())
    }

    // parse classfile
    cf, err := classfile.ParseClassFile(data)
    if err != nil {
        panic(err.Error())
    }

    handleClassfile(cf)
}

func handleClassfile(cf *classfile.ClassFile) {
    fmt.Printf("%v\n", cf)

}
<|endoftext|>


<commit_before>package stackdriver

import (
	"context"

	"cloud.google.com/go/monitoring/apiv3"
	"github.com/cloudfoundry-community/gcp-tools-release/src/stackdriver-nozzle/version"
	"google.golang.org/api/option"
	metricpb "google.golang.org/genproto/googleapis/api/metric"
	monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
)

type MetricClient interface {
	Post(*monitoringpb.CreateTimeSeriesRequest) error
	CreateMetricDescriptor(*monitoringpb.CreateMetricDescriptorRequest) error
	ListMetricDescriptors(*monitoringpb.ListMetricDescriptorsRequest) ([]*metricpb.MetricDescriptor, error)
}

func NewMetricClient() (MetricClient, error) {
	ctx := context.Background()
	sdMetricClient, err := monitoring.NewMetricClient(ctx, option.WithScopes("https://www.googleapis.com/auth/monitoring.write"))
	if err != nil {
		return nil, err
	}

	sdMetricClient.SetGoogleClientInfo(version.Name, version.Release)

	return &metricClient{
		sdMetricClient: sdMetricClient,
		ctx:            ctx,
	}, nil
}

type metricClient struct {
	sdMetricClient *monitoring.MetricClient
	ctx            context.Context
}

func (m *metricClient) Post(request *monitoringpb.CreateTimeSeriesRequest) error {
	return m.sdMetricClient.CreateTimeSeries(m.ctx, request)
}

func (m *metricClient) CreateMetricDescriptor(request *monitoringpb.CreateMetricDescriptorRequest) error {
	_, err := m.sdMetricClient.CreateMetricDescriptor(m.ctx, request)
	return err
}

func (m *metricClient) ListMetricDescriptors(request *monitoringpb.ListMetricDescriptorsRequest) ([]*metricpb.MetricDescriptor, error) {
	it := m.sdMetricClient.ListMetricDescriptors(m.ctx, request)

	descriptors := []*metricpb.MetricDescriptor{}
	for {
		metricDescriptor, err := it.Next()
		if err == monitoring.Done {
			break
		}
		if err != nil {
			return nil, err
		}

		descriptors = append(descriptors, metricDescriptor)
	}

	return descriptors, nil

}
<commit_msg>updated user agent for metric client<commit_after>package stackdriver

import (
	"context"

	"cloud.google.com/go/monitoring/apiv3"
	"github.com/cloudfoundry-community/gcp-tools-release/src/stackdriver-nozzle/version"
	"google.golang.org/api/option"
	metricpb "google.golang.org/genproto/googleapis/api/metric"
	monitoringpb "google.golang.org/genproto/googleapis/monitoring/v3"
)

type MetricClient interface {
	Post(*monitoringpb.CreateTimeSeriesRequest) error
	CreateMetricDescriptor(*monitoringpb.CreateMetricDescriptorRequest) error
	ListMetricDescriptors(*monitoringpb.ListMetricDescriptorsRequest) ([]*metricpb.MetricDescriptor, error)
}

func NewMetricClient() (MetricClient, error) {
	ctx := context.Background()
	sdMetricClient, err := monitoring.NewMetricClient(ctx, option.WithScopes("https://www.googleapis.com/auth/monitoring.write"), option.WithUserAgent(version.UserAgent))
	if err != nil {
		return nil, err
	}

	return &metricClient{
		sdMetricClient: sdMetricClient,
		ctx:            ctx,
	}, nil
}

type metricClient struct {
	sdMetricClient *monitoring.MetricClient
	ctx            context.Context
}

func (m *metricClient) Post(request *monitoringpb.CreateTimeSeriesRequest) error {
	return m.sdMetricClient.CreateTimeSeries(m.ctx, request)
}

func (m *metricClient) CreateMetricDescriptor(request *monitoringpb.CreateMetricDescriptorRequest) error {
	_, err := m.sdMetricClient.CreateMetricDescriptor(m.ctx, request)
	return err
}

func (m *metricClient) ListMetricDescriptors(request *monitoringpb.ListMetricDescriptorsRequest) ([]*metricpb.MetricDescriptor, error) {
	it := m.sdMetricClient.ListMetricDescriptors(m.ctx, request)

	descriptors := []*metricpb.MetricDescriptor{}
	for {
		metricDescriptor, err := it.Next()
		if err == monitoring.Done {
			break
		}
		if err != nil {
			return nil, err
		}

		descriptors = append(descriptors, metricDescriptor)
	}

	return descriptors, nil

}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"log"
	"os/exec"
	"path/filepath"
	"strings"
)

func volPath(target string) string {
	var err error

	target, err = filepath.Abs(target)
	if err != nil {
		log.Fatal(err)
	}
	target = filepath.Clean(target)

	target_list := filepath.SplitList(target)
	if target_list[0] == "Volumes" {
		return target
	}

	volName := ""

	cmd := exec.Command("diskutil", "info", "/")
	stdout, err := cmd.StdoutPipe()
	if err != nil {
		log.Fatal(err)
	}
	defer stdout.Close()

	if err := cmd.Start(); err != nil {
		log.Fatal(err)
	}
	stdlines := bufio.NewScanner(stdout)
	for stdlines.Scan() {
		line := stdlines.Text()
		if strings.HasPrefix(line, "   Volume Name:") {
			volName = strings.Fields(line)[2]
		}
	}
	if err := stdlines.Err(); err != nil {
		fmt.Println("reading output of diskutil")
		log.Fatal(err)
	}
	if err := cmd.Wait(); err != nil {
		log.Fatal(err)
	}
	if volName == "" {
		log.Fatal("Unable to determine root volume.")
	}

	return filepath.Join("/Volumes", volName, target)
}

func getTMDir() (dirname string, err error) {
	dirname_bytes, err := exec.Command("tmutil", "machinedirectory").CombinedOutput()
	if err != nil {
		dirname = filepath.Join(strings.TrimSpace(string(dirname_bytes)), "Latest")
	}
	return
}
<commit_msg>Much better refactoring of code to find root volume<commit_after>package main

import (
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

func rootVolPath() string {
	volumes, err := filepath.Glob("/Volumes/*")
	if err != nil || volumes == nil {
		log.Println("Unable to list /Volumes/*")
		log.Fatal(err)
	}

	for _, volume := range volumes {
		link_path, err := os.Readlink(volume)
		if err == nil && link_path == "/" {
			return volume
		}
	}

	log.Fatal("Could not find root volume")
	return ""
}

func volPath(target string) string {
	var err error

	target, err = filepath.Abs(target)
	if err != nil {
		log.Fatal(err)
	}
	target = filepath.Clean(target)

	target_list := strings.Split(target, string(filepath.Separator))
	if len(target_list) >= 2 &&
		target_list[0] == "" &&
		target_list[1] == "Volumes" {
		return target
	}

	return filepath.Join(rootVolPath(), target)
}

func getTMDir() (dirname string, err error) {
	dirname_bytes, err := exec.Command("tmutil", "machinedirectory").CombinedOutput()
	if err != nil {
		dirname = filepath.Join(strings.TrimSpace(string(dirname_bytes)), "Latest")
	}
	return
}
<|endoftext|>


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

// json.go contains checks for a JSON body.

package ht

import (
	"bytes"
	"encoding/json"
	"fmt"
	"reflect"
	"strconv"
	"strings"

	"github.com/nytlabs/gojee"
	hjson "github.com/vdobler/ht/internal/hjson"
)

func init() {
	RegisterCheck(&JSONExpr{})
	RegisterCheck(&JSON{})
}

// ----------------------------------------------------------------------------
// JSONExpr

// JSONExpr allows checking JSON documents via gojee expressions.
// See github.com/nytlabs/gojee (or the vendored version) for details.
//
// Consider this JSON:
//     { "foo": 5, "bar": [ 1, 2, 3 ] }
// The follwing expression have these truth values:
//     .foo == 5                    true
//     $len(.bar) > 2               true as $len(.bar)==3
//     .bar[1] == 2                 true
//     (.foo == 9) || (.bar[0]<7)   true as .bar[0]==1
//     $max(.bar) == 3              true
//     $has(.bar, 7)                false as bar has no 7
type JSONExpr struct {
	// Expression is a boolean gojee expression which must evaluate
	// to true for the check to pass.
	Expression string `json:",omitempty"`

	tt *jee.TokenTree
}

// Prepare implements Check's Prepare method.
func (c *JSONExpr) Prepare() (err error) {
	if c.Expression == "" {
		return fmt.Errorf("Expression must not be empty")
	}

	tokens, err := jee.Lexer(c.Expression)
	if err != nil {
		return err
	}
	c.tt, err = jee.Parser(tokens)
	return err
}

// Execute implements Check's Execute method.
func (c *JSONExpr) Execute(t *Test) error {
	if c.tt == nil {
		if err := c.Prepare(); err != nil {
			return MalformedCheck{err}
		}
	}
	if t.Response.BodyErr != nil {
		return ErrBadBody
	}

	var bmsg jee.BMsg
	body := []byte(t.Response.BodyStr)
	err := json.Unmarshal(body, &bmsg)
	if err != nil {
		return augmentJSONError(err, body)
	}

	result, err := jee.Eval(c.tt, bmsg)
	if err != nil {
		return err
	}

	if b, ok := result.(bool); !ok {
		return MalformedCheck{fmt.Errorf("Expected bool, got %T (%#v)", result, result)}
	} else if !b {
		return fmt.Errorf("Expression evaluated to false")
	}
	return nil
}

// ----------------------------------------------------------------------------
// JSON

// JSON allow to check an element in a JSON document against a Condition
// and to validate the structur of the document against a schema.
//
// The element of the JSON document is selected by its "path". Example:
// In the JSON document
//     {
//       "foo": 5,
//       "bar": [ 1, "qux" ,3 ],
//       "waz": true,
//       "maa": { "muh": 3.141, "mee": 0 },
//       "nil": null
//     }
// the following table shows several element paths and their value:
//     foo       5
//     bar       [ 1, "qux" ,3 ]
//     bar.0     1
//     bar.1     "qux"
//     bar.2     3
//     waz       true
//     maa       { "muh": 3.141, "mee": 0 }
//     maa.muh   3.141
//     maa.mee   0
//     nil       null
// Note that the value for "bar" is the raw string and contains the original
// white space characters as present in the original JSON document.
//
// A schema is an example JSON document with the same structure where each
// leave element just determines the expected type. The JSON document from
// above would conform to the schema:
//     {
//       "foo": 0, "bar": [0,"",1], "waz": false,
//       "maa": { "muh": 0.0, "mee": 0 },
//     }
// Contrary to standard JSON this check allows to distinguish floats from
// ints with the rule that an integer is a valid value for a float in a schema.
// So any string in a schema forces a string value, any int in a schema forces
// an integer value, any float in a schema forces either an int or a float.
// Null values in schemas act as wildcards: any value (int, bool, float, string
// or null) is valid. This is useful if you want to skip validation of e.g.
// the first two array elements.
//
// It is typically not useful to combine schema validation with checking
// a condition.
type JSON struct {
	// Element in the flattened JSON map to apply the Condition to.
	// E.g.  "foo.2" in "{foo: [4,5,6,7]}" would be 6.
	// The whole JSON can be selected by Sep, typically ".".
	// An empty value result in just a check for 'wellformedness' of
	// the JSON.
	Element string

	// Condition to apply to the value selected by Element.
	// If Condition is the zero value then only the existence of
	// a JSON element selected by Element is checked.
	// Note that Condition is checked against the actual raw value of
	// the JSON document and will contain quotation marks for strings.
	Condition

	// Schema is the expected structure of the selected element.
	Schema string `json:",omitempty"`

	// Embedded is a JSON check applied to the value selected by
	// Element. Useful when JSON contains embedded, quoted JSON as
	// a string and checking via Condition is not practical.
	// (It seems this nested JSON is common nowadays. I'm getting old.)
	Embedded *JSON `json:",omitempty"`

	// Sep is the separator in Element when checking the Condition.
	// A zero value is equivalent to "."
	Sep string `json:",omitempty"`

	schema interface{}
}

// Prepare implements Check's Prepare method.
func (c *JSON) Prepare() error {
	err := c.Compile()
	if err != nil {
		return err
	}
	if c.Schema != "" {
		err = hjson.Unmarshal([]byte(c.Schema), &c.schema)
		if err != nil {
			return err
		}
	}
	if c.Embedded != nil {
		return c.Embedded.Prepare()
	}
	return nil
}

func findJSONelement(data []byte, element, sep string) ([]byte, error) {
	path := strings.Split(element, sep)
	for e, elem := range path {
		if elem == "" {
			continue
		}
		data = bytes.TrimSpace(data)
		if len(data) == 0 {
			return nil, nil
		}
		switch data[0] {
		case '[':
			v := []json.RawMessage{}
			err := json.Unmarshal(data, &v)
			if err != nil {
				return nil, err
			}
			i, err := strconv.Atoi(elem)
			if err != nil {
				return nil, fmt.Errorf("%s is not a valid index", elem)
			}
			if i < 0 || i >= len(v) {
				return nil, fmt.Errorf("No index %d in array %s of len %d",
					i, strings.Join(path[:e], sep), len(v))
			}
			data = []byte(v[i])
		case '{':
			v := map[string]json.RawMessage{}
			err := json.Unmarshal(data, &v)
			if err != nil {
				return nil, err
			}
			raw, ok := v[elem]
			if !ok {
				return nil, fmt.Errorf("Element %s not found",
					strings.Join(path[:e+1], sep))
			}
			data = []byte(raw)
		default:
			return nil, fmt.Errorf("Element %s not found",
				strings.Join(path[:e+1], sep))
		}
	}
	return data, nil
}

// Execute implements Check's Execute method.
func (c *JSON) Execute(t *Test) error {
	if t.Response.BodyErr != nil {
		return ErrBadBody
	}

	sep := "." // The default value for Sep.
	if c.Sep != "" {
		sep = c.Sep
	}

	// Check for wellformed of overall, outer JSON.
	var v interface{}
	body := []byte(t.Response.BodyStr)
	if err := json.Unmarshal(body, &v); err != nil {
		return augmentJSONError(err, body)
	}

	raw, err := findJSONelement(body, c.Element, sep)
	if err != nil {
		return err
	}

	// Check for wellformed JSON.
	err = json.Unmarshal(raw, &v)
	if err != nil {
		return err
	}

	if c.Embedded != nil {
		unquoted, err := strconv.Unquote(string(raw))
		if err != nil {
			return fmt.Errorf("element %s: %s", c.Element, err)
		}
		etest := &Test{Response: Response{BodyStr: unquoted}}
		eerr := c.Embedded.Execute(etest)
		if eerr != nil {
			return fmt.Errorf("embedded: %s", eerr)
		}
	}

	if c.schema != nil {
		var actual interface{}
		err = hjson.Unmarshal(raw, &actual)
		if err != nil {
			return err // That should not happen here as JSON-validity
			// has been checked above.

		}
		av, sv := reflect.ValueOf(actual), reflect.ValueOf(c.schema)
		err = compareStructure(c.Element, sep, av, sv)
		if err != nil {
			return err
		}
	}

	err = c.Fulfilled(string(raw))
	if err != nil {
		return fmt.Errorf("%s in %s", err, LimitString(string(raw)))
	}
	return nil
}

// augmentJSONError tries to augment err by a line/column number pointing into
// jsonData. encoding/json.Unmarshal's error for syntax errors in the JSON is
// very hard to use as a human, augmenting the error with a line number makes
// debugging much simplier.
func augmentJSONError(err error, jsonData []byte) error {
	off := 0

	se, ok := err.(*json.SyntaxError)
	if !ok {
		return err
	}
	off = int(se.Offset)

	lines := bytes.Split(jsonData, []byte("\n"))
	total := 0
	lineNo := 0
	for total+len(lines[lineNo])+1 < off {
		total += len(lines[lineNo]) + 1 // +1 for the \n removed in splitting
		lineNo++
	}
	lineNo++ // Lines are counted 1-based.
	byteNo := off - total
	return fmt.Errorf("json syntax error in line %d, byte %d: %s",
		lineNo, byteNo, err)
}

func kind(v reflect.Value) string {
	s := v.Kind().String()
	if strings.HasSuffix(s, "64") {
		s = s[:len(s)-2]
	}
	return s
}

// compareStructure returns the/one/all (?) deviations in actual from
// the desired structure.
func compareStructure(element, sep string, actual, schema reflect.Value) error {
	for actual.Kind() == reflect.Interface {
		actual = actual.Elem()
	}
	for schema.Kind() == reflect.Interface {
		schema = schema.Elem()
	}
	if !schema.IsValid() {
		// null value in schema accepts everything.
		return nil
	}
	if !actual.IsValid() {
		// null value in actual does not match anything.
		return fmt.Errorf("element %s: got null, want %s",
			element, kind(schema))
	}

	switch schema.Kind() {
	case reflect.Float64:
		if actual.Kind() != reflect.Float64 && actual.Kind() != reflect.Int64 {
			return fmt.Errorf("element %s: got %s, want float",
				element, kind(actual))
		}
	case reflect.Bool, reflect.String, reflect.Int64:
		if actual.Kind() != schema.Kind() {
			return fmt.Errorf("element %s: got %s, want %s",
				element, kind(actual), kind(schema))
		}
	case reflect.Slice:
		if err := compareSlice(element, sep, actual, schema); err != nil {
			return err
		}
	case reflect.Map:
		if err := compareMap(element, sep, actual, schema); err != nil {
			return err
		}
	default:
		return fmt.Errorf("ht: ooops: type of %s (%s) should not happen in unmarshaled JSON",
			schema.Kind(), schema)
	}
	return nil
}

func compareSlice(element, sep string, actual, schema reflect.Value) error {
	if actual.Kind() != reflect.Slice {
		return fmt.Errorf("element %s: got %s, want array",
			element, kind(actual))
	}
	an, sn := actual.Len(), schema.Len()
	if an < sn {
		return fmt.Errorf("element %s: got only %d array elements, need %d",
			element, an, sn)
	}
	for i := 0; i < sn; i++ {
		elmt := fmt.Sprintf("%d", i)
		if element != "" {
			elmt = element + sep + elmt
		}
		err := compareStructure(elmt, sep, actual.Index(i), schema.Index(i))
		if err != nil {
			return err
		}

	}
	return nil
}

func compareMap(element, sep string, actual, schema reflect.Value) error {
	if actual.Kind() != reflect.Map {
		return fmt.Errorf("element %s: got %s, want object",
			element, kind(actual))
	}
	// BUG: handle only string keys
	for _, key := range schema.MapKeys() {
		acv := actual.MapIndex(key)
		if !acv.IsValid() {
			return fmt.Errorf("element %s: missing child %s",
				element, key.String())
		}
		elmt := key.String()
		if element != "" {
			elmt = element + sep + elmt
		}
		err := compareStructure(elmt, sep, acv, schema.MapIndex(key))
		if err != nil {
			return err
		}
	}
	return nil
}
<commit_msg>ht: silence ineffeassign<commit_after>// Copyright 2014 Volker Dobler.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// json.go contains checks for a JSON body.

package ht

import (
	"bytes"
	"encoding/json"
	"fmt"
	"reflect"
	"strconv"
	"strings"

	"github.com/nytlabs/gojee"
	hjson "github.com/vdobler/ht/internal/hjson"
)

func init() {
	RegisterCheck(&JSONExpr{})
	RegisterCheck(&JSON{})
}

// ----------------------------------------------------------------------------
// JSONExpr

// JSONExpr allows checking JSON documents via gojee expressions.
// See github.com/nytlabs/gojee (or the vendored version) for details.
//
// Consider this JSON:
//     { "foo": 5, "bar": [ 1, 2, 3 ] }
// The follwing expression have these truth values:
//     .foo == 5                    true
//     $len(.bar) > 2               true as $len(.bar)==3
//     .bar[1] == 2                 true
//     (.foo == 9) || (.bar[0]<7)   true as .bar[0]==1
//     $max(.bar) == 3              true
//     $has(.bar, 7)                false as bar has no 7
type JSONExpr struct {
	// Expression is a boolean gojee expression which must evaluate
	// to true for the check to pass.
	Expression string `json:",omitempty"`

	tt *jee.TokenTree
}

// Prepare implements Check's Prepare method.
func (c *JSONExpr) Prepare() (err error) {
	if c.Expression == "" {
		return fmt.Errorf("Expression must not be empty")
	}

	tokens, err := jee.Lexer(c.Expression)
	if err != nil {
		return err
	}
	c.tt, err = jee.Parser(tokens)
	return err
}

// Execute implements Check's Execute method.
func (c *JSONExpr) Execute(t *Test) error {
	if c.tt == nil {
		if err := c.Prepare(); err != nil {
			return MalformedCheck{err}
		}
	}
	if t.Response.BodyErr != nil {
		return ErrBadBody
	}

	var bmsg jee.BMsg
	body := []byte(t.Response.BodyStr)
	err := json.Unmarshal(body, &bmsg)
	if err != nil {
		return augmentJSONError(err, body)
	}

	result, err := jee.Eval(c.tt, bmsg)
	if err != nil {
		return err
	}

	if b, ok := result.(bool); !ok {
		return MalformedCheck{fmt.Errorf("Expected bool, got %T (%#v)", result, result)}
	} else if !b {
		return fmt.Errorf("Expression evaluated to false")
	}
	return nil
}

// ----------------------------------------------------------------------------
// JSON

// JSON allow to check an element in a JSON document against a Condition
// and to validate the structur of the document against a schema.
//
// The element of the JSON document is selected by its "path". Example:
// In the JSON document
//     {
//       "foo": 5,
//       "bar": [ 1, "qux" ,3 ],
//       "waz": true,
//       "maa": { "muh": 3.141, "mee": 0 },
//       "nil": null
//     }
// the following table shows several element paths and their value:
//     foo       5
//     bar       [ 1, "qux" ,3 ]
//     bar.0     1
//     bar.1     "qux"
//     bar.2     3
//     waz       true
//     maa       { "muh": 3.141, "mee": 0 }
//     maa.muh   3.141
//     maa.mee   0
//     nil       null
// Note that the value for "bar" is the raw string and contains the original
// white space characters as present in the original JSON document.
//
// A schema is an example JSON document with the same structure where each
// leave element just determines the expected type. The JSON document from
// above would conform to the schema:
//     {
//       "foo": 0, "bar": [0,"",1], "waz": false,
//       "maa": { "muh": 0.0, "mee": 0 },
//     }
// Contrary to standard JSON this check allows to distinguish floats from
// ints with the rule that an integer is a valid value for a float in a schema.
// So any string in a schema forces a string value, any int in a schema forces
// an integer value, any float in a schema forces either an int or a float.
// Null values in schemas act as wildcards: any value (int, bool, float, string
// or null) is valid. This is useful if you want to skip validation of e.g.
// the first two array elements.
//
// It is typically not useful to combine schema validation with checking
// a condition.
type JSON struct {
	// Element in the flattened JSON map to apply the Condition to.
	// E.g.  "foo.2" in "{foo: [4,5,6,7]}" would be 6.
	// The whole JSON can be selected by Sep, typically ".".
	// An empty value result in just a check for 'wellformedness' of
	// the JSON.
	Element string

	// Condition to apply to the value selected by Element.
	// If Condition is the zero value then only the existence of
	// a JSON element selected by Element is checked.
	// Note that Condition is checked against the actual raw value of
	// the JSON document and will contain quotation marks for strings.
	Condition

	// Schema is the expected structure of the selected element.
	Schema string `json:",omitempty"`

	// Embedded is a JSON check applied to the value selected by
	// Element. Useful when JSON contains embedded, quoted JSON as
	// a string and checking via Condition is not practical.
	// (It seems this nested JSON is common nowadays. I'm getting old.)
	Embedded *JSON `json:",omitempty"`

	// Sep is the separator in Element when checking the Condition.
	// A zero value is equivalent to "."
	Sep string `json:",omitempty"`

	schema interface{}
}

// Prepare implements Check's Prepare method.
func (c *JSON) Prepare() error {
	err := c.Compile()
	if err != nil {
		return err
	}
	if c.Schema != "" {
		err = hjson.Unmarshal([]byte(c.Schema), &c.schema)
		if err != nil {
			return err
		}
	}
	if c.Embedded != nil {
		return c.Embedded.Prepare()
	}
	return nil
}

func findJSONelement(data []byte, element, sep string) ([]byte, error) {
	path := strings.Split(element, sep)
	for e, elem := range path {
		if elem == "" {
			continue
		}
		data = bytes.TrimSpace(data)
		if len(data) == 0 {
			return nil, nil
		}
		switch data[0] {
		case '[':
			v := []json.RawMessage{}
			err := json.Unmarshal(data, &v)
			if err != nil {
				return nil, err
			}
			i, err := strconv.Atoi(elem)
			if err != nil {
				return nil, fmt.Errorf("%s is not a valid index", elem)
			}
			if i < 0 || i >= len(v) {
				return nil, fmt.Errorf("No index %d in array %s of len %d",
					i, strings.Join(path[:e], sep), len(v))
			}
			data = []byte(v[i])
		case '{':
			v := map[string]json.RawMessage{}
			err := json.Unmarshal(data, &v)
			if err != nil {
				return nil, err
			}
			raw, ok := v[elem]
			if !ok {
				return nil, fmt.Errorf("Element %s not found",
					strings.Join(path[:e+1], sep))
			}
			data = []byte(raw)
		default:
			return nil, fmt.Errorf("Element %s not found",
				strings.Join(path[:e+1], sep))
		}
	}
	return data, nil
}

// Execute implements Check's Execute method.
func (c *JSON) Execute(t *Test) error {
	if t.Response.BodyErr != nil {
		return ErrBadBody
	}

	sep := "." // The default value for Sep.
	if c.Sep != "" {
		sep = c.Sep
	}

	// Check for wellformed of overall, outer JSON.
	var v interface{}
	body := []byte(t.Response.BodyStr)
	if err := json.Unmarshal(body, &v); err != nil {
		return augmentJSONError(err, body)
	}

	raw, err := findJSONelement(body, c.Element, sep)
	if err != nil {
		return err
	}

	// Check for wellformed JSON.
	err = json.Unmarshal(raw, &v)
	if err != nil {
		return err
	}

	if c.Embedded != nil {
		unquoted, err := strconv.Unquote(string(raw))
		if err != nil {
			return fmt.Errorf("element %s: %s", c.Element, err)
		}
		etest := &Test{Response: Response{BodyStr: unquoted}}
		eerr := c.Embedded.Execute(etest)
		if eerr != nil {
			return fmt.Errorf("embedded: %s", eerr)
		}
	}

	if c.schema != nil {
		var actual interface{}
		err = hjson.Unmarshal(raw, &actual)
		if err != nil {
			return err // That should not happen here as JSON-validity
			// has been checked above.

		}
		av, sv := reflect.ValueOf(actual), reflect.ValueOf(c.schema)
		err = compareStructure(c.Element, sep, av, sv)
		if err != nil {
			return err
		}
	}

	err = c.Fulfilled(string(raw))
	if err != nil {
		return fmt.Errorf("%s in %s", err, LimitString(string(raw)))
	}
	return nil
}

// augmentJSONError tries to augment err by a line/column number pointing into
// jsonData. encoding/json.Unmarshal's error for syntax errors in the JSON is
// very hard to use as a human, augmenting the error with a line number makes
// debugging much simplier.
func augmentJSONError(err error, jsonData []byte) error {
	se, ok := err.(*json.SyntaxError)
	if !ok {
		return err
	}
	off := int(se.Offset)

	lines := bytes.Split(jsonData, []byte("\n"))
	total := 0
	lineNo := 0
	for total+len(lines[lineNo])+1 < off {
		total += len(lines[lineNo]) + 1 // +1 for the \n removed in splitting
		lineNo++
	}
	lineNo++ // Lines are counted 1-based.
	byteNo := off - total
	return fmt.Errorf("json syntax error in line %d, byte %d: %s",
		lineNo, byteNo, err)
}

func kind(v reflect.Value) string {
	s := v.Kind().String()
	if strings.HasSuffix(s, "64") {
		s = s[:len(s)-2]
	}
	return s
}

// compareStructure returns the/one/all (?) deviations in actual from
// the desired structure.
func compareStructure(element, sep string, actual, schema reflect.Value) error {
	for actual.Kind() == reflect.Interface {
		actual = actual.Elem()
	}
	for schema.Kind() == reflect.Interface {
		schema = schema.Elem()
	}
	if !schema.IsValid() {
		// null value in schema accepts everything.
		return nil
	}
	if !actual.IsValid() {
		// null value in actual does not match anything.
		return fmt.Errorf("element %s: got null, want %s",
			element, kind(schema))
	}

	switch schema.Kind() {
	case reflect.Float64:
		if actual.Kind() != reflect.Float64 && actual.Kind() != reflect.Int64 {
			return fmt.Errorf("element %s: got %s, want float",
				element, kind(actual))
		}
	case reflect.Bool, reflect.String, reflect.Int64:
		if actual.Kind() != schema.Kind() {
			return fmt.Errorf("element %s: got %s, want %s",
				element, kind(actual), kind(schema))
		}
	case reflect.Slice:
		if err := compareSlice(element, sep, actual, schema); err != nil {
			return err
		}
	case reflect.Map:
		if err := compareMap(element, sep, actual, schema); err != nil {
			return err
		}
	default:
		return fmt.Errorf("ht: ooops: type of %s (%s) should not happen in unmarshaled JSON",
			schema.Kind(), schema)
	}
	return nil
}

func compareSlice(element, sep string, actual, schema reflect.Value) error {
	if actual.Kind() != reflect.Slice {
		return fmt.Errorf("element %s: got %s, want array",
			element, kind(actual))
	}
	an, sn := actual.Len(), schema.Len()
	if an < sn {
		return fmt.Errorf("element %s: got only %d array elements, need %d",
			element, an, sn)
	}
	for i := 0; i < sn; i++ {
		elmt := fmt.Sprintf("%d", i)
		if element != "" {
			elmt = element + sep + elmt
		}
		err := compareStructure(elmt, sep, actual.Index(i), schema.Index(i))
		if err != nil {
			return err
		}

	}
	return nil
}

func compareMap(element, sep string, actual, schema reflect.Value) error {
	if actual.Kind() != reflect.Map {
		return fmt.Errorf("element %s: got %s, want object",
			element, kind(actual))
	}
	// BUG: handle only string keys
	for _, key := range schema.MapKeys() {
		acv := actual.MapIndex(key)
		if !acv.IsValid() {
			return fmt.Errorf("element %s: missing child %s",
				element, key.String())
		}
		elmt := key.String()
		if element != "" {
			elmt = element + sep + elmt
		}
		err := compareStructure(elmt, sep, acv, schema.MapIndex(key))
		if err != nil {
			return err
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package renter

import (
	"testing"
	"time"
)

// TestAddChunkToCache tests that the oldest chunk is removed
func TestAddChunkToCache(t *testing.T) {
	var udc unfinishedDownloadChunk
	udc.download = &download{
		staticDestinationType: "httpseekstream",
	}

	data := []byte{1, 2, 3, 4}

	// Fill Cache
	for i := 0; i < downloadCacheSize; i++ {
		udc.addChunkToCache(data)
		time.Sleep(1 * time.Millisecond)
	}

	// Get oldest key
	var oldestKey string
	oldestTime := time.Now()

	for id, chunk := range udc.chunkCache {
		if chunk.lastAccess.Before(oldestTime) {
			oldestTime = chunk.lastAccess
			oldestKey = id
		}
	}

	// Add additional chunk to force deletion of a chunk
	udc.addChunkToCache(data)

	// check if the chunk with the oldestKey was removed
	if _, ok := udc.chunkCache[oldestKey]; ok {
		t.Errorf("Expected ok to be false instead it was %v", ok)
	}

}
<commit_msg>update TestAddChunkToCache to fix failing test.  Test-long now passing as well<commit_after>package renter

import (
	"strconv"
	"sync"
	"testing"
	"time"
)

// TestAddChunkToCache tests that the oldest chunk is removed
func TestAddChunkToCache(t *testing.T) {
	udc := &unfinishedDownloadChunk{
		download: &download{
			staticDestinationType: "httpseekstream",
		},
		chunkCache: make(map[string]*cacheData),
		cacheMu:    new(sync.Mutex),
	}

	data := []byte{1, 2, 3, 4}

	// Fill Cache
	for i := 0; i < downloadCacheSize; i++ {
		udc.staticCacheID = strconv.Itoa(i)
		udc.addChunkToCache(data)
		time.Sleep(1 * time.Millisecond)
	}

	// Add additional chunk to force deletion of a chunk
	udc.staticCacheID = strconv.Itoa(downloadCacheSize)
	udc.addChunkToCache(data)

	// check if the chunk with staticCacheID = "0" was removed
	// as that would have been the first to be added
	if _, ok := udc.chunkCache["0"]; ok {
		t.Errorf("Expected ok to be false instead it was %v", ok)
	}

}
<|endoftext|>


<commit_before>/*
Package httperr defines a simple HTTP error which has a message and status
code.
*/
package httperr

// Error represents a simple HTTP error which has a message and status code.
type Error interface {
	error
	// Code returns the error's HTTP status code.
	Code() int
}

type httpError struct {
	message string
	code    int
}

// New returns a new Error with the given message and code.
func New(message string, code int) Error {
	return &httpError{message, code}
}

// Error returns the error's message.
func (e *httpError) Error() string {
	return e.message
}

// Code returns the error's HTTP status code.
func (e *httpError) Code() int {
	return e.code
}
<commit_msg>Add example to godoc<commit_after>/*
httperr defines a simple HTTP error which has a message and status code. This
can be useful for returning errors with relevant HTTP status codes, which the
standard errors package allow for.

Example:
	func Foo() httperr.Error {
	  if err := Bar(); err != nil {
	    return httperr.New(err.Error(), http.StatusInternalServerError)
	  }
	  return nil
	}

	func FooHandler(w http.ResponseWriter, r *http.Request) {
	  if httpErr := Foo(); httpErr != nil {
	    http.Error(w, httpErr.Error(), httpErr.Code())
	  }
	}
*/
package httperr

// Error represents a simple HTTP error which has a message and status code.
type Error interface {
	error
	// Code returns the error's HTTP status code.
	Code() int
}

type httpError struct {
	message string
	code    int
}

// New returns a new Error with the given message and code.
func New(message string, code int) Error {
	return &httpError{message, code}
}

// Error returns the error's message.
func (e *httpError) Error() string {
	return e.message
}

// Code returns the error's HTTP status code.
func (e *httpError) Code() int {
	return e.code
}
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Robin Engel
 *
 * 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 handler

import (
	"github.com/WE-Development/mosel/moseld/server/context"
	"net/http"
	"github.com/WE-Development/mosel/api"
	"log"
	"encoding/json"
)

type infoHandler struct {
	ctxd *context.MoseldServerContext
}

func NewInfoHandler(ctxd *context.MoseldServerContext) *infoHandler {
	return &infoHandler{
		ctxd: ctxd,
	}
}

func (handler infoHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	resp := api.NewInfoResponse()

	resp.Nodes = handler.ctxd.DataCache.GetNodes()

	log.Println(resp)
	json.NewEncoder(w).Encode(resp)
}

func (handler infoHandler) GetPath() string {
	return "/info"
}

func (handler infoHandler) Secure() bool {
	return true
}<commit_msg>remove old logging<commit_after>/*
 * Copyright 2016 Robin Engel
 *
 * 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 handler

import (
	"github.com/WE-Development/mosel/moseld/server/context"
	"net/http"
	"github.com/WE-Development/mosel/api"
	"encoding/json"
)

type infoHandler struct {
	ctxd *context.MoseldServerContext
}

func NewInfoHandler(ctxd *context.MoseldServerContext) *infoHandler {
	return &infoHandler{
		ctxd: ctxd,
	}
}

func (handler infoHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	resp := api.NewInfoResponse()
	resp.Nodes = handler.ctxd.DataCache.GetNodes()
	json.NewEncoder(w).Encode(resp)
}

func (handler infoHandler) GetPath() string {
	return "/info"
}

func (handler infoHandler) Secure() bool {
	return true
}<|endoftext|>