<commit_before>package main

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/spf13/cobra"

	"restic"
	"restic/errors"
	"restic/repository"
)

var cmdLs = &cobra.Command{
	Use:   "ls [flags] snapshot-ID",
	Short: "list files in a snapshot",
	Long: `
The "ls" command allows listing files and directories in a snapshot.
`,
	RunE: func(cmd *cobra.Command, args []string) error {
		return runLs(globalOptions, args)
	},
}

var listLong bool

func init() {
	cmdRoot.AddCommand(cmdLs)

	cmdLs.Flags().BoolVarP(&listLong, "long", "l", false, "use a long listing format showing size and mode")
}

func printNode(prefix string, n *restic.Node) string {
	if !listLong {
		return filepath.Join(prefix, n.Name)
	}

	switch n.Type {
	case "file":
		return fmt.Sprintf("%s %5d %5d %6d %s %s",
			n.Mode, n.UID, n.GID, n.Size, n.ModTime.Format(TimeFormat), filepath.Join(prefix, n.Name))
	case "dir":
		return fmt.Sprintf("%s %5d %5d %6d %s %s",
			n.Mode|os.ModeDir, n.UID, n.GID, n.Size, n.ModTime.Format(TimeFormat), filepath.Join(prefix, n.Name))
	case "symlink":
		return fmt.Sprintf("%s %5d %5d %6d %s %s -> %s",
			n.Mode|os.ModeSymlink, n.UID, n.GID, n.Size, n.ModTime.Format(TimeFormat), filepath.Join(prefix, n.Name), n.LinkTarget)
	default:
		return fmt.Sprintf("<Node(%s) %s>", n.Type, n.Name)
	}
}

func printTree(prefix string, repo *repository.Repository, id restic.ID) error {
	tree, err := repo.LoadTree(id)
	if err != nil {
		return err
	}

	for _, entry := range tree.Nodes {
		Printf(printNode(prefix, entry) + "\n")

		if entry.Type == "dir" && entry.Subtree != nil {
			err = printTree(filepath.Join(prefix, entry.Name), repo, *entry.Subtree)
			if err != nil {
				return err
			}
		}
	}

	return nil
}

func runLs(gopts GlobalOptions, args []string) error {
	if len(args) < 1 || len(args) > 2 {
		return errors.Fatalf("no snapshot ID given")
	}

	repo, err := OpenRepository(gopts)
	if err != nil {
		return err
	}

	err = repo.LoadIndex()
	if err != nil {
		return err
	}

	id, err := restic.FindSnapshot(repo, args[0])
	if err != nil {
		return err
	}

	sn, err := restic.LoadSnapshot(repo, id)
	if err != nil {
		return err
	}

	Verbosef("snapshot of %v at %s:\n", sn.Paths, sn.Time)

	return printTree("", repo, *sn.Tree)
}
<commit_msg>Added latest keyword in ls command.<commit_after>package main

import (
	"fmt"
	"os"
	"path/filepath"

	"github.com/spf13/cobra"

	"restic"
	"restic/errors"
	"restic/repository"
)

var cmdLs = &cobra.Command{
	Use:   "ls [flags] snapshot-ID",
	Short: "list files in a snapshot",
	Long: `
The "ls" command allows listing files and directories in a snapshot.

The special snapshot-ID "latest" can be used to list files and directories of the latest snapshot in the repository.
`,
	RunE: func(cmd *cobra.Command, args []string) error {
		return runLs(globalOptions, args)
	},
}

var listLong bool

func init() {
	cmdRoot.AddCommand(cmdLs)

	cmdLs.Flags().BoolVarP(&listLong, "long", "l", false, "use a long listing format showing size and mode")
}

func printNode(prefix string, n *restic.Node) string {
	if !listLong {
		return filepath.Join(prefix, n.Name)
	}

	switch n.Type {
	case "file":
		return fmt.Sprintf("%s %5d %5d %6d %s %s",
			n.Mode, n.UID, n.GID, n.Size, n.ModTime.Format(TimeFormat), filepath.Join(prefix, n.Name))
	case "dir":
		return fmt.Sprintf("%s %5d %5d %6d %s %s",
			n.Mode|os.ModeDir, n.UID, n.GID, n.Size, n.ModTime.Format(TimeFormat), filepath.Join(prefix, n.Name))
	case "symlink":
		return fmt.Sprintf("%s %5d %5d %6d %s %s -> %s",
			n.Mode|os.ModeSymlink, n.UID, n.GID, n.Size, n.ModTime.Format(TimeFormat), filepath.Join(prefix, n.Name), n.LinkTarget)
	default:
		return fmt.Sprintf("<Node(%s) %s>", n.Type, n.Name)
	}
}

func printTree(prefix string, repo *repository.Repository, id restic.ID) error {
	tree, err := repo.LoadTree(id)
	if err != nil {
		return err
	}

	for _, entry := range tree.Nodes {
		Printf(printNode(prefix, entry) + "\n")

		if entry.Type == "dir" && entry.Subtree != nil {
			err = printTree(filepath.Join(prefix, entry.Name), repo, *entry.Subtree)
			if err != nil {
				return err
			}
		}
	}

	return nil
}

func runLs(gopts GlobalOptions, args []string) error {
	if len(args) < 1 || len(args) > 2 {
		return errors.Fatalf("no snapshot ID given")
	}

	repo, err := OpenRepository(gopts)
	if err != nil {
		return err
	}

	err = repo.LoadIndex()
	if err != nil {
		return err
	}

	snapshotIDString := args[0]
	var id restic.ID
	var paths []string

	if snapshotIDString == "latest" {
		id, err = restic.FindLatestSnapshot(repo, paths, "")
		if err != nil {
			return err
		}
	} else {
		id, err = restic.FindSnapshot(repo, snapshotIDString)
		if err != nil {
			return err
		}
	}

	sn, err := restic.LoadSnapshot(repo, id)
	if err != nil {
		return err
	}

	Verbosef("snapshot of %v at %s:\n", sn.Paths, sn.Time)

	return printTree("", repo, *sn.Tree)
}
<|endoftext|>


<commit_before>/*
Copyright 2011-2013 Frederic Langlet
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 main

import (
	"fmt"
	"kanzi/transform"
	"math/rand"
	"os"
	"time"
)

func main() {
	fmt.Printf("\nTestBWT")
	TestCorrectness()
	TestSpeed()
}

func TestCorrectness() {
	fmt.Printf("\n\nCorrectness test")

	// Test behavior
	for ii := 0; ii < 20; ii++ {
		fmt.Printf("\nTest %v\n", ii)
		rnd := rand.New(rand.NewSource(time.Now().UnixNano()))

		size := uint(0)
		var buf1 []byte
		var buf2 []byte
		var buf3 []byte

		if ii == 0 {
			size = 0
			buf1 = []byte{'m', 'i', 's', 's', 'i', 's', 's', 'i', 'p', 'p', 'i'}
		} else {
			size = 128
			buf1 = make([]byte, size)

			for i := 0; i < len(buf1); i++ {
				buf1[i] = byte(65 + rnd.Intn(4*ii))
			}

			buf1[len(buf1)-1] = byte(0)
		}

		buf2 = make([]byte, len(buf1))
		buf3 = make([]byte, len(buf1))

		bwt, _ := transform.NewBWT(size)
		str1 := string(buf1)
		fmt.Printf("Input:   %s\n", str1)
		_, _, err1 := bwt.Forward(buf1, buf2)

		if err1 != nil {
			fmt.Printf("Error: %v\n", err1)
			os.Exit(1)
		}

		primaryIndex := bwt.PrimaryIndex()
		str2 := string(buf2)
		fmt.Printf("Encoded: %s", str2)
		fmt.Printf("  (Primary index=%v)\n", bwt.PrimaryIndex())
		bwt.SetPrimaryIndex(primaryIndex)
		_, _, err2 := bwt.Inverse(buf2, buf3)

		if err2 != nil {
			fmt.Printf("Error: %v\n", err2)
			os.Exit(1)
		}

		str3 := string(buf3)
		fmt.Printf("Output:  %s\n", str3)

		if str1 == str3 {
			fmt.Printf("Identical\n")
		} else {
			fmt.Printf("Different\n")
			os.Exit(1)
		}
	}
}

func TestSpeed() {
	fmt.Printf("\nSpeed test")
	iter := 2000
	size := 256 * 1024
	buf1 := make([]byte, size)
	buf2 := make([]byte, size)
	buf3 := make([]byte, size)
	fmt.Printf("\nIterations: %v", iter)
	fmt.Printf("\nTransform size: %v\n", size)

	for jj := 0; jj < 3; jj++ {
		delta1 := int64(0)
		delta2 := int64(0)
		bwt, _ := transform.NewBWT(0)
		rnd := rand.New(rand.NewSource(time.Now().UnixNano()))

		for i := 0; i < iter; i++ {
			for i := range buf1 {
				buf1[i] = byte(rnd.Intn(255) + 1)
			}

			buf1[size-1] = 0
			before := time.Now()
			bwt.Forward(buf1, buf2)
			after := time.Now()
			delta1 += after.Sub(before).Nanoseconds()
			before = time.Now()
			bwt.Inverse(buf2, buf3)
			after = time.Now()
			delta2 += after.Sub(before).Nanoseconds()

			// Sanity check
			for i := range buf1 {
				if buf1[i] != buf3[i] {
					println("Error at index %v: %v<->%v\n", i, buf1[i], buf3[i])
					os.Exit(1)
				}
			}
		}

		println()
		prod := int64(iter) * int64(size)
		fmt.Printf("Forward transform [ms] : %v\n", delta1/1000000)
		fmt.Printf("Throughput [KB/s]      : %d\n", prod*1000000/delta1*1000/1024)
		fmt.Printf("Inverse transform [ms] : %v\n", delta2/1000000)
		fmt.Printf("Throughput [KB/s]      : %d\n", prod*1000000/delta1*1000/1024)
		println()
	}
}
<commit_msg>Fix incorrect perf parameter display.<commit_after>/*
Copyright 2011-2013 Frederic Langlet
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 main

import (
	"fmt"
	"kanzi/transform"
	"math/rand"
	"os"
	"time"
)

func main() {
	fmt.Printf("\nTestBWT")
	TestCorrectness()
	TestSpeed()
}

func TestCorrectness() {
	fmt.Printf("\n\nCorrectness test")

	// Test behavior
	for ii := 0; ii < 20; ii++ {
		fmt.Printf("\nTest %v\n", ii)
		rnd := rand.New(rand.NewSource(time.Now().UnixNano()))

		size := uint(0)
		var buf1 []byte
		var buf2 []byte
		var buf3 []byte

		if ii == 0 {
			size = 0
			buf1 = []byte{'m', 'i', 's', 's', 'i', 's', 's', 'i', 'p', 'p', 'i'}
		} else {
			size = 128
			buf1 = make([]byte, size)

			for i := 0; i < len(buf1); i++ {
				buf1[i] = byte(65 + rnd.Intn(4*ii))
			}

			buf1[len(buf1)-1] = byte(0)
		}

		buf2 = make([]byte, len(buf1))
		buf3 = make([]byte, len(buf1))

		bwt, _ := transform.NewBWT(size)
		str1 := string(buf1)
		fmt.Printf("Input:   %s\n", str1)
		_, _, err1 := bwt.Forward(buf1, buf2)

		if err1 != nil {
			fmt.Printf("Error: %v\n", err1)
			os.Exit(1)
		}

		primaryIndex := bwt.PrimaryIndex()
		str2 := string(buf2)
		fmt.Printf("Encoded: %s", str2)
		fmt.Printf("  (Primary index=%v)\n", bwt.PrimaryIndex())
		bwt.SetPrimaryIndex(primaryIndex)
		_, _, err2 := bwt.Inverse(buf2, buf3)

		if err2 != nil {
			fmt.Printf("Error: %v\n", err2)
			os.Exit(1)
		}

		str3 := string(buf3)
		fmt.Printf("Output:  %s\n", str3)

		if str1 == str3 {
			fmt.Printf("Identical\n")
		} else {
			fmt.Printf("Different\n")
			os.Exit(1)
		}
	}
}

func TestSpeed() {
	fmt.Printf("\nSpeed test")
	iter := 2000
	size := 256 * 1024
	buf1 := make([]byte, size)
	buf2 := make([]byte, size)
	buf3 := make([]byte, size)
	fmt.Printf("\nIterations: %v", iter)
	fmt.Printf("\nTransform size: %v\n", size)

	for jj := 0; jj < 3; jj++ {
		delta1 := int64(0)
		delta2 := int64(0)
		bwt, _ := transform.NewBWT(0)
		rnd := rand.New(rand.NewSource(time.Now().UnixNano()))

		for i := 0; i < iter; i++ {
			for i := range buf1 {
				buf1[i] = byte(rnd.Intn(255) + 1)
			}

			buf1[size-1] = 0
			before := time.Now()
			bwt.Forward(buf1, buf2)
			after := time.Now()
			delta1 += after.Sub(before).Nanoseconds()
			before = time.Now()
			bwt.Inverse(buf2, buf3)
			after = time.Now()
			delta2 += after.Sub(before).Nanoseconds()

			// Sanity check
			for i := range buf1 {
				if buf1[i] != buf3[i] {
					println("Error at index %v: %v<->%v\n", i, buf1[i], buf3[i])
					os.Exit(1)
				}
			}
		}

		println()
		prod := int64(iter) * int64(size)
		fmt.Printf("Forward transform [ms] : %v\n", delta1/1000000)
		fmt.Printf("Throughput [KB/s]      : %d\n", prod*1000000/delta1*1000/1024)
		fmt.Printf("Inverse transform [ms] : %v\n", delta2/1000000)
		fmt.Printf("Throughput [KB/s]      : %d\n", prod*1000000/delta2*1000/1024)
		println()
	}
}
<|endoftext|>


<commit_before>// Package entitlement provides entitlement certificate based authentication
// scheme that checks whether the requested path is present in the entitlement
// certificate or not.
//
// This authentication must be used under TLS, as non SSL requests won't have the
// certificate data in the request
package entitlement

import (
	"fmt"
	"net/http"
	"strings"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/distribution/context"
	"github.com/docker/distribution/registry/auth"
)

// accessController provides a implementation of auth.AccessController
// that checks for a non-empty SSL CLIENT header, which is then used for
// entitlement cert based authentication. It is useful for
// candlepin issued entitlement cert based auth.
type accessController struct {
	realm   string
	service *Entitlement
}

var _ auth.AccessController = &accessController{}

func newAccessController(options map[string]interface{}) (auth.AccessController, error) {
	realm, present := options["realm"]
	if _, ok := realm.(string); !present || !ok {
		return nil, fmt.Errorf(`"realm" must be set for entitlement access controller`)
	}

	service, present := options["servicePath"]
	if _, ok := service.(string); !present || !ok {
		return nil, fmt.Errorf(`"servicePath" must be set for entitlement access controller`)
	}

	//var e Entitlement
	e := NewEntitlement(service.(string))

	return &accessController{realm: realm.(string), service: e}, nil
}

// Authorized simply checks for the existence of the SSL CLIENT headers,
// using which entitlement check is done
func (ac *accessController) Authorized(ctx context.Context, accessRecords ...auth.Access) (context.Context, error) {
	var resData ResponseData
	var err1 error
	req, err := context.GetRequest(ctx)
	if err != nil {
		return nil, err
	}

	if req.Header.Get("SSL_CLIENT_CERT") == "" {
		log.Debugln("repo name: %s", getName(ctx))

		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	pemStr := req.Header.Get("SSL_CLIENT_CERT")
	log.Debugln("SSL CERT: %s", pemStr)
	repoName := getName(ctx)
	//if it is a push request
	//or the the URI requested is /v2/ (ping)
	//then don't call authentication service
	log.Debugln("requestURI: ", req.RequestURI)
	log.Debugln("requested repo name: ", getName(ctx))
	if skipAuth(req) {
		log.Debugln("Returning without calling authentication servie")
		return auth.WithUser(ctx, auth.UserInfo{Name: "entitled-ping"}), nil
	}

	// check for repo name being empty. If repo name is empty
	// and the URI is not for ping, return authentication error
	if "/v2/" != req.RequestURI && repoName == "" {
		log.Errorln("No repo name retrieved. This should not happen")
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure as no repo name has been supplied"),
		}
	}

	libraryName := repoName[:strings.LastIndex(repoName, "/")+1]
	log.Debugln("Computed library name: ", libraryName)
	path := fmt.Sprintf("/content/dist/rhel/server/7/7Server/x86_64/containers/registry/%s", libraryName)
	http.Redirect(req, ac.service.EndPoint, 302)
	if resData, err1 = ac.service.CheckEntitlement(pemStr, path); err1 != nil {
		log.Errorln("Service returned error: ", err1)
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	if resData.Verified != "true" {
		log.Errorln("Service returned unauthenticated/unauthorized")
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	return auth.WithUser(ctx, auth.UserInfo{Name: "entitled"}), nil
}

type challenge struct {
	realm string
	err   error
}

// Error returns the internal error string for this authChallenge.
func (ac challenge) Error() string {
	return ac.err.Error()
}

// SetChallenge sets the WWW-Authenticate value for the response. However
// that is not required for entitlement based auth. Hence, providing empty
// implementation
func (ac challenge) SetHeaders(w http.ResponseWriter) {

}

var _ auth.Challenge = challenge{}

// init handles registering the entitlement auth backend.
func init() {
	auth.Register("entitlement", auth.InitFunc(newAccessController))
}

func getName(ctx context.Context) (name string) {
	return context.GetStringValue(ctx, "vars.name")
}

func skipAuth(req *http.Request) bool {
	return "/v2/" == req.RequestURI || req.Method == "POST" || req.Method == "HEAD" || req.Method == "PATCH" || req.Method == "PUT"
}
<commit_msg>NA: Redirecting to auth service<commit_after>// Package entitlement provides entitlement certificate based authentication
// scheme that checks whether the requested path is present in the entitlement
// certificate or not.
//
// This authentication must be used under TLS, as non SSL requests won't have the
// certificate data in the request
package entitlement

import (
	"fmt"
	"net/http"
	"strings"

	log "github.com/Sirupsen/logrus"
	"github.com/docker/distribution/context"
	"github.com/docker/distribution/registry/auth"
)

// accessController provides a implementation of auth.AccessController
// that checks for a non-empty SSL CLIENT header, which is then used for
// entitlement cert based authentication. It is useful for
// candlepin issued entitlement cert based auth.
type accessController struct {
	realm   string
	service *Entitlement
}

var _ auth.AccessController = &accessController{}

func newAccessController(options map[string]interface{}) (auth.AccessController, error) {
	realm, present := options["realm"]
	if _, ok := realm.(string); !present || !ok {
		return nil, fmt.Errorf(`"realm" must be set for entitlement access controller`)
	}

	service, present := options["servicePath"]
	if _, ok := service.(string); !present || !ok {
		return nil, fmt.Errorf(`"servicePath" must be set for entitlement access controller`)
	}

	//var e Entitlement
	e := NewEntitlement(service.(string))

	return &accessController{realm: realm.(string), service: e}, nil
}

// Authorized simply checks for the existence of the SSL CLIENT headers,
// using which entitlement check is done
func (ac *accessController) Authorized(ctx context.Context, accessRecords ...auth.Access) (context.Context, error) {
	var resData ResponseData
	var err1 error
	req, err := context.GetRequest(ctx)
	res, err2 := context.GetResponseWriter(ctx)
	if err != nil || err2 != nil {
		return nil, err
	}

	if req.Header.Get("SSL_CLIENT_CERT") == "" {
		log.Debugln("repo name: %s", getName(ctx))

		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	pemStr := req.Header.Get("SSL_CLIENT_CERT")
	log.Debugln("SSL CERT: %s", pemStr)
	repoName := getName(ctx)
	//if it is a push request
	//or the the URI requested is /v2/ (ping)
	//then don't call authentication service
	log.Debugln("requestURI: ", req.RequestURI)
	log.Debugln("requested repo name: ", getName(ctx))
	if skipAuth(req) {
		log.Debugln("Returning without calling authentication servie")
		return auth.WithUser(ctx, auth.UserInfo{Name: "entitled-ping"}), nil
	}

	// check for repo name being empty. If repo name is empty
	// and the URI is not for ping, return authentication error
	if "/v2/" != req.RequestURI && repoName == "" {
		log.Errorln("No repo name retrieved. This should not happen")
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure as no repo name has been supplied"),
		}
	}

	libraryName := repoName[:strings.LastIndex(repoName, "/")+1]
	log.Debugln("Computed library name: ", libraryName)
	path := fmt.Sprintf("/content/dist/rhel/server/7/7Server/x86_64/containers/registry/%s", libraryName)
	http.Redirect(res, req, ac.service.EndPoint, 302)
	if resData, err1 = ac.service.CheckEntitlement(pemStr, path); err1 != nil {
		log.Errorln("Service returned error: ", err1)
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	if resData.Verified != "true" {
		log.Errorln("Service returned unauthenticated/unauthorized")
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	return auth.WithUser(ctx, auth.UserInfo{Name: "entitled"}), nil
}

type challenge struct {
	realm string
	err   error
}

// Error returns the internal error string for this authChallenge.
func (ac challenge) Error() string {
	return ac.err.Error()
}

// SetChallenge sets the WWW-Authenticate value for the response. However
// that is not required for entitlement based auth. Hence, providing empty
// implementation
func (ac challenge) SetHeaders(w http.ResponseWriter) {

}

var _ auth.Challenge = challenge{}

// init handles registering the entitlement auth backend.
func init() {
	auth.Register("entitlement", auth.InitFunc(newAccessController))
}

func getName(ctx context.Context) (name string) {
	return context.GetStringValue(ctx, "vars.name")
}

func skipAuth(req *http.Request) bool {
	return "/v2/" == req.RequestURI || req.Method == "POST" || req.Method == "HEAD" || req.Method == "PATCH" || req.Method == "PUT"
}
<|endoftext|>


<commit_before>// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package http

import (
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"reflect"

	"github.com/goharbor/harbor/src/common/http/modifier"
	"github.com/goharbor/harbor/src/lib"
)

const (
	// InsecureTransport used to get the insecure http Transport
	InsecureTransport = iota
	// SecureTransport used to get the external secure http Transport
	SecureTransport
)

var (
	secureHTTPTransport   *http.Transport
	insecureHTTPTransport *http.Transport
)

func init() {
	secureHTTPTransport = http.DefaultTransport.(*http.Transport).Clone()
	insecureHTTPTransport = http.DefaultTransport.(*http.Transport).Clone()
	insecureHTTPTransport.TLSClientConfig.InsecureSkipVerify = true

	if InternalTLSEnabled() {
		tlsConfig, err := GetInternalTLSConfig()
		if err != nil {
			panic(err)
		}
		secureHTTPTransport.TLSClientConfig = tlsConfig
	}
}

// Client is a util for common HTTP operations, such Get, Head, Post, Put and Delete.
// Use Do instead if  those methods can not meet your requirement
type Client struct {
	modifiers []modifier.Modifier
	client    *http.Client
}

// GetHTTPTransport returns HttpTransport based on insecure configuration
func GetHTTPTransport(clientType uint) *http.Transport {
	switch clientType {
	case SecureTransport:
		return secureHTTPTransport
	case InsecureTransport:
		return insecureHTTPTransport
	default:
		// default Transport is secure one
		return secureHTTPTransport
	}
}

// GetHTTPTransportByInsecure returns a insecure HttpTransport if insecure is true or it returns secure one
func GetHTTPTransportByInsecure(insecure bool) *http.Transport {
	if insecure {
		return insecureHTTPTransport
	}
	return secureHTTPTransport
}

// NewClient creates an instance of Client.
// Use net/http.Client as the default value if c is nil.
// Modifiers modify the request before sending it.
func NewClient(c *http.Client, modifiers ...modifier.Modifier) *Client {
	client := &Client{
		client: c,
	}
	if client.client == nil {
		client.client = &http.Client{
			Transport: GetHTTPTransport(SecureTransport),
		}
	}
	if len(modifiers) > 0 {
		client.modifiers = modifiers
	}
	return client
}

// Do ...
func (c *Client) Do(req *http.Request) (*http.Response, error) {
	for _, modifier := range c.modifiers {
		if err := modifier.Modify(req); err != nil {
			return nil, err
		}
	}

	return c.client.Do(req)
}

// Get ...
func (c *Client) Get(url string, v ...interface{}) error {
	req, err := http.NewRequest(http.MethodGet, url, nil)
	if err != nil {
		return err
	}

	data, err := c.do(req)
	if err != nil {
		return err
	}

	if len(v) == 0 {
		return nil
	}

	return json.Unmarshal(data, v[0])
}

// Head ...
func (c *Client) Head(url string) error {
	req, err := http.NewRequest(http.MethodHead, url, nil)
	if err != nil {
		return err
	}
	_, err = c.do(req)
	return err
}

// Post ...
func (c *Client) Post(url string, v ...interface{}) error {
	var reader io.Reader
	if len(v) > 0 {
		if r, ok := v[0].(io.Reader); ok {
			reader = r
		} else {
			data, err := json.Marshal(v[0])
			if err != nil {
				return err
			}

			reader = bytes.NewReader(data)
		}
	}

	req, err := http.NewRequest(http.MethodPost, url, reader)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")
	_, err = c.do(req)
	return err
}

// Put ...
func (c *Client) Put(url string, v ...interface{}) error {
	var reader io.Reader
	if len(v) > 0 {
		data := []byte{}
		data, err := json.Marshal(v[0])
		if err != nil {
			return err
		}
		reader = bytes.NewReader(data)
	}

	req, err := http.NewRequest(http.MethodPut, url, reader)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")
	_, err = c.do(req)
	return err
}

// Delete ...
func (c *Client) Delete(url string) error {
	req, err := http.NewRequest(http.MethodDelete, url, nil)
	if err != nil {
		return err
	}
	_, err = c.do(req)
	return err
}

func (c *Client) do(req *http.Request) ([]byte, error) {
	resp, err := c.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

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

	if resp.StatusCode < 200 || resp.StatusCode > 299 {
		return nil, &Error{
			Code:    resp.StatusCode,
			Message: string(data),
		}
	}

	return data, nil
}

// GetAndIteratePagination iterates the pagination header and returns all resources
// The parameter "v" must be a pointer to a slice
func (c *Client) GetAndIteratePagination(endpoint string, v interface{}) error {
	url, err := url.Parse(endpoint)
	if err != nil {
		return err
	}

	rv := reflect.ValueOf(v)
	if rv.Kind() != reflect.Ptr {
		return errors.New("v should be a pointer to a slice")
	}
	elemType := rv.Elem().Type()
	if elemType.Kind() != reflect.Slice {
		return errors.New("v should be a pointer to a slice")
	}

	resources := reflect.Indirect(reflect.New(elemType))
	for len(endpoint) > 0 {
		req, err := http.NewRequest(http.MethodGet, endpoint, nil)
		if err != nil {
			return err
		}
		resp, err := c.Do(req)
		if err != nil {
			return err
		}
		data, err := ioutil.ReadAll(resp.Body)
		resp.Body.Close()
		if err != nil {
			return err
		}
		if resp.StatusCode < 200 || resp.StatusCode > 299 {
			return &Error{
				Code:    resp.StatusCode,
				Message: string(data),
			}
		}

		res := reflect.New(elemType)
		if err = json.Unmarshal(data, res.Interface()); err != nil {
			return err
		}
		resources = reflect.AppendSlice(resources, reflect.Indirect(res))

		endpoint = ""
		links := lib.ParseLinks(resp.Header.Get("Link"))
		for _, link := range links {
			if link.Rel == "next" {
				endpoint = url.Scheme + "://" + url.Host + link.URL
				break
			}
		}
	}
	rv.Elem().Set(resources)
	return nil
}
<commit_msg>Fix: Default Transport HTTP2 related hang issue<commit_after>// Copyright Project Harbor Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package http

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"errors"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"reflect"
	"time"

	"github.com/goharbor/harbor/src/common/http/modifier"
	"github.com/goharbor/harbor/src/lib"
)

const (
	// InsecureTransport used to get the insecure http Transport
	InsecureTransport = iota
	// SecureTransport used to get the external secure http Transport
	SecureTransport
)

var (
	secureHTTPTransport   *http.Transport
	insecureHTTPTransport *http.Transport
)

func init() {
	secureHTTPTransport = newDefaultTransport()
	insecureHTTPTransport = newDefaultTransport()
	insecureHTTPTransport.TLSClientConfig.InsecureSkipVerify = true

	if InternalTLSEnabled() {
		tlsConfig, err := GetInternalTLSConfig()
		if err != nil {
			panic(err)
		}
		secureHTTPTransport.TLSClientConfig = tlsConfig
	}
}

func newDefaultTransport() *http.Transport {
	return &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		DialContext: (&net.Dialer{
			Timeout:   30 * time.Second,
			KeepAlive: 30 * time.Second,
			DualStack: true,
		}).DialContext,
		TLSClientConfig:       &tls.Config{},
		MaxIdleConns:          100,
		IdleConnTimeout:       90 * time.Second,
		TLSHandshakeTimeout:   10 * time.Second,
		ExpectContinueTimeout: 1 * time.Second,
	}
}

// Client is a util for common HTTP operations, such Get, Head, Post, Put and Delete.
// Use Do instead if  those methods can not meet your requirement
type Client struct {
	modifiers []modifier.Modifier
	client    *http.Client
}

// GetHTTPTransport returns HttpTransport based on insecure configuration
func GetHTTPTransport(clientType uint) *http.Transport {
	switch clientType {
	case SecureTransport:
		return secureHTTPTransport
	case InsecureTransport:
		return insecureHTTPTransport
	default:
		// default Transport is secure one
		return secureHTTPTransport
	}
}

// GetHTTPTransportByInsecure returns a insecure HttpTransport if insecure is true or it returns secure one
func GetHTTPTransportByInsecure(insecure bool) *http.Transport {
	if insecure {
		return insecureHTTPTransport
	}
	return secureHTTPTransport
}

// NewClient creates an instance of Client.
// Use net/http.Client as the default value if c is nil.
// Modifiers modify the request before sending it.
func NewClient(c *http.Client, modifiers ...modifier.Modifier) *Client {
	client := &Client{
		client: c,
	}
	if client.client == nil {
		client.client = &http.Client{
			Transport: GetHTTPTransport(SecureTransport),
		}
	}
	if len(modifiers) > 0 {
		client.modifiers = modifiers
	}
	return client
}

// Do ...
func (c *Client) Do(req *http.Request) (*http.Response, error) {
	for _, modifier := range c.modifiers {
		if err := modifier.Modify(req); err != nil {
			return nil, err
		}
	}

	return c.client.Do(req)
}

// Get ...
func (c *Client) Get(url string, v ...interface{}) error {
	req, err := http.NewRequest(http.MethodGet, url, nil)
	if err != nil {
		return err
	}

	data, err := c.do(req)
	if err != nil {
		return err
	}

	if len(v) == 0 {
		return nil
	}

	return json.Unmarshal(data, v[0])
}

// Head ...
func (c *Client) Head(url string) error {
	req, err := http.NewRequest(http.MethodHead, url, nil)
	if err != nil {
		return err
	}
	_, err = c.do(req)
	return err
}

// Post ...
func (c *Client) Post(url string, v ...interface{}) error {
	var reader io.Reader
	if len(v) > 0 {
		if r, ok := v[0].(io.Reader); ok {
			reader = r
		} else {
			data, err := json.Marshal(v[0])
			if err != nil {
				return err
			}

			reader = bytes.NewReader(data)
		}
	}

	req, err := http.NewRequest(http.MethodPost, url, reader)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")
	_, err = c.do(req)
	return err
}

// Put ...
func (c *Client) Put(url string, v ...interface{}) error {
	var reader io.Reader
	if len(v) > 0 {
		data := []byte{}
		data, err := json.Marshal(v[0])
		if err != nil {
			return err
		}
		reader = bytes.NewReader(data)
	}

	req, err := http.NewRequest(http.MethodPut, url, reader)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", "application/json")
	_, err = c.do(req)
	return err
}

// Delete ...
func (c *Client) Delete(url string) error {
	req, err := http.NewRequest(http.MethodDelete, url, nil)
	if err != nil {
		return err
	}
	_, err = c.do(req)
	return err
}

func (c *Client) do(req *http.Request) ([]byte, error) {
	resp, err := c.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

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

	if resp.StatusCode < 200 || resp.StatusCode > 299 {
		return nil, &Error{
			Code:    resp.StatusCode,
			Message: string(data),
		}
	}

	return data, nil
}

// GetAndIteratePagination iterates the pagination header and returns all resources
// The parameter "v" must be a pointer to a slice
func (c *Client) GetAndIteratePagination(endpoint string, v interface{}) error {
	url, err := url.Parse(endpoint)
	if err != nil {
		return err
	}

	rv := reflect.ValueOf(v)
	if rv.Kind() != reflect.Ptr {
		return errors.New("v should be a pointer to a slice")
	}
	elemType := rv.Elem().Type()
	if elemType.Kind() != reflect.Slice {
		return errors.New("v should be a pointer to a slice")
	}

	resources := reflect.Indirect(reflect.New(elemType))
	for len(endpoint) > 0 {
		req, err := http.NewRequest(http.MethodGet, endpoint, nil)
		if err != nil {
			return err
		}
		resp, err := c.Do(req)
		if err != nil {
			return err
		}
		data, err := ioutil.ReadAll(resp.Body)
		resp.Body.Close()
		if err != nil {
			return err
		}
		if resp.StatusCode < 200 || resp.StatusCode > 299 {
			return &Error{
				Code:    resp.StatusCode,
				Message: string(data),
			}
		}

		res := reflect.New(elemType)
		if err = json.Unmarshal(data, res.Interface()); err != nil {
			return err
		}
		resources = reflect.AppendSlice(resources, reflect.Indirect(res))

		endpoint = ""
		links := lib.ParseLinks(resp.Header.Get("Link"))
		for _, link := range links {
			if link.Rel == "next" {
				endpoint = url.Scheme + "://" + url.Host + link.URL
				break
			}
		}
	}
	rv.Elem().Set(resources)
	return nil
}
<|endoftext|>


<commit_before>package utils

import (
	prifilog "github.com/lbarman/prifi/prifi-lib/log"
	"gopkg.in/dedis/onet.v1/log"
	"math"
	"strconv"
	"time"
)

// PCAPReceivedPacket represents a PCAP that was transmitted through Prifi and received at the relay
type PCAPReceivedPacket struct {
	ID              uint32
	ReceivedAt      uint64
	SentAt          uint64
	Delay           uint64
	DataLen         uint32
	IsFinalFragment bool
}

// PCAPLog is a collection of PCAPReceivedPackets
type PCAPLog struct {
	receivedPackets []*PCAPReceivedPacket
	nextReport      time.Time
	period          time.Duration
}

// Returns an instantiated PCAPLog
func NewPCAPLog() *PCAPLog {
	p := &PCAPLog{
		receivedPackets: make([]*PCAPReceivedPacket, 0),
		period:          time.Duration(5) * time.Second,
		nextReport:      time.Now(),
	}
	return p
}

// should be called with the received pcap packet
func (pl *PCAPLog) ReceivedPcap(ID uint32, frag bool, tsSent uint64, tsExperimentStart uint64, dataLen uint32) {

	if pl.receivedPackets == nil {
		pl.receivedPackets = make([]*PCAPReceivedPacket, 0)
	}

	receptionTime := uint64(prifilog.MsTimeStampNow()) - tsExperimentStart

	if receptionTime < 0 {
		receptionTime = 0
	}

	p := &PCAPReceivedPacket{
		ID:              ID,
		ReceivedAt:      receptionTime,
		SentAt:          tsSent,
		Delay:           receptionTime - tsSent,
		DataLen:         dataLen,
		IsFinalFragment: frag,
	}

	pl.receivedPackets = append(pl.receivedPackets, p)

	now := time.Now()
	if now.After(pl.nextReport) {
		pl.Print()
		pl.nextReport = now.Add(pl.period)
	}
}

// prints current statistics for the pcap logger
func (pl *PCAPLog) Print() {

	totalPackets := 0
	totalUniquePackets := 0
	totalFragments := 0

	//compute min max and other stats
	delaysSum := uint64(0)
	delayMax := uint64(0)
	for _, v := range pl.receivedPackets {
		totalPackets++
		if v.IsFinalFragment {
			totalUniquePackets++
		} else {
			totalFragments++
		}

		delaysSum += v.Delay

		if v.Delay > delayMax {
			delayMax = v.Delay
		}
	}

	delayMean := float64(delaysSum) / float64(totalPackets)

	//now compute variance
	variance := float64(0)
	for _, v := range pl.receivedPackets {
		variance += (float64(v.Delay) - delayMean) * (float64(v.Delay) - delayMean)
	}

	variance = variance / float64(totalPackets)

	//compute stddev
	stddev := math.Sqrt(variance)

	log.Lvl1("PCAPLog : ", totalFragments, "fragments,", totalUniquePackets, "final,", totalPackets, "fragments+final; mean",
		math.Ceil(delayMean*100)/100, "ms, stddev", math.Ceil(stddev*100)/100, "max", math.Ceil(float64(delayMax)*100)/100, "ms")

	str := ""
	for _, v := range pl.receivedPackets {
		str += strconv.Itoa(int(v.Delay)) + ";"
	}

	log.Lvl1("PCAPLog-individuals: ", str)
	pl.receivedPackets = make([]*PCAPReceivedPacket, 0)
}
<commit_msg>Adds pcap logging<commit_after>package utils

import (
	prifilog "github.com/lbarman/prifi/prifi-lib/log"
	"gopkg.in/dedis/onet.v1/log"
	"math"
	"strconv"
	"time"
)

// PCAPReceivedPacket represents a PCAP that was transmitted through Prifi and received at the relay
type PCAPReceivedPacket struct {
	ID              uint32
	ReceivedAt      uint64
	SentAt          uint64
	Delay           uint64
	DataLen         uint32
	IsFinalFragment bool
}

// PCAPLog is a collection of PCAPReceivedPackets
type PCAPLog struct {
	reportID        int
	receivedPackets []*PCAPReceivedPacket
	nextReport      time.Time
	period          time.Duration
}

// Returns an instantiated PCAPLog
func NewPCAPLog() *PCAPLog {
	p := &PCAPLog{
		reportID:        0,
		receivedPackets: make([]*PCAPReceivedPacket, 0),
		period:          time.Duration(5) * time.Second,
		nextReport:      time.Now(),
	}
	return p
}

// should be called with the received pcap packet
func (pl *PCAPLog) ReceivedPcap(ID uint32, frag bool, tsSent uint64, tsExperimentStart uint64, dataLen uint32) {

	if pl.receivedPackets == nil {
		pl.receivedPackets = make([]*PCAPReceivedPacket, 0)
	}

	receptionTime := uint64(prifilog.MsTimeStampNow()) - tsExperimentStart

	if receptionTime < 0 {
		receptionTime = 0
	}

	p := &PCAPReceivedPacket{
		ID:              ID,
		ReceivedAt:      receptionTime,
		SentAt:          tsSent,
		Delay:           receptionTime - tsSent,
		DataLen:         dataLen,
		IsFinalFragment: frag,
	}

	pl.receivedPackets = append(pl.receivedPackets, p)

	now := time.Now()
	if now.After(pl.nextReport) {
		pl.Print()
		pl.nextReport = now.Add(pl.period)
	}
}

// prints current statistics for the pcap logger
func (pl *PCAPLog) Print() {

	totalPackets := 0
	totalUniquePackets := 0
	totalFragments := 0

	//compute min max and other stats
	delaysSum := uint64(0)
	delayMax := uint64(0)
	for _, v := range pl.receivedPackets {
		totalPackets++
		if v.IsFinalFragment {
			totalUniquePackets++
		} else {
			totalFragments++
		}

		delaysSum += v.Delay

		if v.Delay > delayMax {
			delayMax = v.Delay
		}
	}

	delayMean := float64(delaysSum) / float64(totalPackets)

	//now compute variance
	variance := float64(0)
	for _, v := range pl.receivedPackets {
		variance += (float64(v.Delay) - delayMean) * (float64(v.Delay) - delayMean)
	}

	variance = variance / float64(totalPackets)

	//compute stddev
	stddev := math.Sqrt(variance)

	log.Lvl1("PCAPLog (", pl.reportID, "): ", totalFragments, "fragments,", totalUniquePackets, "final,", totalPackets, "fragments+final; mean",
		math.Ceil(delayMean*100)/100, "ms, stddev", math.Ceil(stddev*100)/100, "max", math.Ceil(float64(delayMax)*100)/100, "ms")

	str := ""
	for _, v := range pl.receivedPackets {
		str += strconv.Itoa(int(v.Delay)) + ";"
	}

	log.Lvl1("PCAPLog-individuals (", pl.reportID, "): ", str)
	pl.reportID++
	pl.receivedPackets = make([]*PCAPReceivedPacket, 0)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"koding/db/mongodb"
	"koding/db/mongodb/modelhelper"
	"koding/kontrol/kontroldaemon/handler"
	"koding/kontrol/kontrolhelper"
	"koding/tools/config"
	"koding/tools/logger"

	"github.com/streadway/amqp"
)

var (
	mongo       *mongodb.MongoDB
	flagProfile = flag.String("c", "", "Configuration profile from file")
	flagDebug   = flag.Bool("d", false, "Debug mode")
	log         = logger.New("kontroldaemon")
)

func main() {
	flag.Parse()
	if *flagProfile == "" {
		log.Fatal("Please define config file with -c")
	}

	conf := config.MustConfig(*flagProfile)

	var logLevel logger.Level
	if *flagDebug {
		logLevel = logger.DEBUG
	} else {
		logLevel = logger.GetLoggingLevelFromConfig("kontroldaemon", *flagProfile)
	}
	log.SetLevel(logLevel)

	mongo = mongodb.NewMongoDB(conf.Mongo)
	modelhelper.Initialize(conf.Mongo)

	handler.Startup(conf)
	startRouting(conf)
}

func startRouting(conf *config.Config) {
	type bind struct {
		name     string
		queue    string
		key      string
		exchange string
		kind     string
	}

	streams := make(map[string]<-chan amqp.Delivery)
	bindings := []bind{
		bind{"api", "kontrol-api", "input.api", "infoExchange", "topic"},
		bind{"worker", "kontrol-worker", "input.worker", "workerExchange", "topic"},
		bind{"client", "kontrol-client", "", "clientExchange", "fanout"},
	}

	connection := kontrolhelper.CreateAmqpConnection(conf)
	channel := kontrolhelper.CreateChannel(connection)

	for _, b := range bindings {
		streams[b.name] = kontrolhelper.CreateStream(channel, b.kind, b.exchange, b.queue, b.key, true, false)
	}

	err := channel.Qos(len(bindings), 0, false)
	if err != nil {
		log.Fatal("basic.qos: %s", err.Error())
	}

	log.Info("kontroldaemon routing started")
	for {
		select {
		case d := <-streams["api"]:
			go handler.ApiMessage(d.Body)
		case d := <-streams["worker"]:
			go handler.WorkerMessage(d.Body)
		case d := <-streams["client"]:
			go handler.ClientMessage(d)
		}
	}
}
<commit_msg>kontroldaemon: remove client binding and QOS settings.<commit_after>package main

import (
	"flag"
	"koding/db/mongodb"
	"koding/db/mongodb/modelhelper"
	"koding/kontrol/kontroldaemon/handler"
	"koding/kontrol/kontrolhelper"
	"koding/tools/config"
	"koding/tools/logger"

	"github.com/streadway/amqp"
)

var (
	mongo       *mongodb.MongoDB
	flagProfile = flag.String("c", "", "Configuration profile from file")
	flagDebug   = flag.Bool("d", false, "Debug mode")
	log         = logger.New("kontroldaemon")
)

func main() {
	flag.Parse()
	if *flagProfile == "" {
		log.Fatal("Please define config file with -c")
	}

	conf := config.MustConfig(*flagProfile)

	var logLevel logger.Level
	if *flagDebug {
		logLevel = logger.DEBUG
	} else {
		logLevel = logger.GetLoggingLevelFromConfig("kontroldaemon", *flagProfile)
	}
	log.SetLevel(logLevel)

	mongo = mongodb.NewMongoDB(conf.Mongo)
	modelhelper.Initialize(conf.Mongo)

	handler.Startup(conf)
	startRouting(conf)
}

func startRouting(conf *config.Config) {
	type bind struct {
		name     string
		queue    string
		key      string
		exchange string
		kind     string
	}

	streams := make(map[string]<-chan amqp.Delivery)
	bindings := []bind{
		bind{"api", "kontrol-api", "input.api", "infoExchange", "topic"},
		bind{"worker", "kontrol-worker", "input.worker", "workerExchange", "topic"},
	}

	connection := kontrolhelper.CreateAmqpConnection(conf)
	channel := kontrolhelper.CreateChannel(connection)

	for _, b := range bindings {
		streams[b.name] = kontrolhelper.CreateStream(channel, b.kind, b.exchange, b.queue, b.key, true, false)
	}

	log.Info("kontroldaemon routing started")
	for {
		select {
		case d := <-streams["api"]:
			go handler.ApiMessage(d.Body)
		case d := <-streams["worker"]:
			go handler.WorkerMessage(d.Body)
		}
	}
}
<|endoftext|>


<commit_before>package response

import (
	"errors"
	"net/http"
	"socialapi/config"
	"socialapi/workers/helper"

	"github.com/koding/bongo"
)

// NewBadRequest is creating a new http response with predifined
// http response properties
func NewBadRequest(err error) (int, http.Header, interface{}, error) {
	if err == nil {
		err = errors.New("request is not valid")
	}

	// make sure errors are outputted
	helper.MustGetLogger().Error("Bad Request: %s", err)

	// do not expose errors to the client
	if config.MustGet().Environment != config.VagrantEnvName {
		err = genericError
	}

	return http.StatusBadRequest, nil, nil, BadRequest{err}
}

// NewAccessDenied sends access denied response back to client
//
// here not to leak info about the resource
// do send NotFound err
func NewAccessDenied(err error) (int, http.Header, interface{}, error) {
	helper.MustGetLogger().Error("Access Denied Err: %s", err.Error())
	return NewNotFound()
}

// HandleResultAndError wraps the function calls and get its reponse,
// assuming the second parameter as error checks it if it is null or not
// if err nor found, returns OK response
func HandleResultAndError(res interface{}, err error) (int, http.Header, interface{}, error) {
	if err == bongo.RecordNotFound {
		return NewNotFound()
	}

	if err != nil {
		return NewBadRequest(err)
	}

	return NewOK(res)
}

// HandleResultAndClientError is same as `HandleResultAndError`, but it
// returns the actual error to client as opposed to generic error.
func HandleResultAndClientError(res interface{}, err error) (int, http.Header, interface{}, error) {
	if err != nil {
		return http.StatusBadRequest, nil, nil, err
	}

	return NewOK(res)
}

// NewOK returns http StatusOK response
func NewOK(res interface{}) (int, http.Header, interface{}, error) {
	return http.StatusOK, nil, res, nil
}

// NewNotFound returns http StatusNotFound response
func NewNotFound() (int, http.Header, interface{}, error) {
	return http.StatusNotFound, nil, nil, NotFoundError{errors.New("content not found")}
}

// NewDeleted returns http StatusAccepted response
func NewDeleted() (int, http.Header, interface{}, error) {
	return http.StatusAccepted, nil, nil, nil
}

// NewDefaultOK returns http StatusOK response with `{status:true}` response
func NewDefaultOK() (int, http.Header, interface{}, error) {
	res := map[string]interface{}{
		"status": true,
	}

	return NewOK(res)
}
<commit_msg>Social: make content not found error an exported one<commit_after>package response

import (
	"errors"
	"net/http"
	"socialapi/config"
	"socialapi/workers/helper"

	"github.com/koding/bongo"
)

var ErrContentNotFound = errors.New("content not found")

// NewBadRequest is creating a new http response with predifined
// http response properties
func NewBadRequest(err error) (int, http.Header, interface{}, error) {
	if err == nil {
		err = errors.New("request is not valid")
	}

	// make sure errors are outputted
	helper.MustGetLogger().Error("Bad Request: %s", err)

	// do not expose errors to the client
	if config.MustGet().Environment != "dev" {
		err = genericError
	}

	return http.StatusBadRequest, nil, nil, BadRequest{err}
}

// NewAccessDenied sends access denied response back to client
//
// here not to leak info about the resource
// do send NotFound err
func NewAccessDenied(err error) (int, http.Header, interface{}, error) {
	helper.MustGetLogger().Error("Access Denied Err: %s", err.Error())
	return NewNotFound()
}

// HandleResultAndError wraps the function calls and get its reponse,
// assuming the second parameter as error checks it if it is null or not
// if err nor found, returns OK response
func HandleResultAndError(res interface{}, err error) (int, http.Header, interface{}, error) {
	if err == bongo.RecordNotFound {
		return NewNotFound()
	}

	if err != nil {
		return NewBadRequest(err)
	}

	return NewOK(res)
}

// HandleResultAndClientError is same as `HandleResultAndError`, but it
// returns the actual error to client as opposed to generic error.
func HandleResultAndClientError(res interface{}, err error) (int, http.Header, interface{}, error) {
	if err != nil {
		return http.StatusBadRequest, nil, nil, err
	}

	return NewOK(res)
}

// NewOK returns http StatusOK response
func NewOK(res interface{}) (int, http.Header, interface{}, error) {
	return http.StatusOK, nil, res, nil
}

// NewNotFound returns http StatusNotFound response
func NewNotFound() (int, http.Header, interface{}, error) {
	return http.StatusNotFound, nil, nil, NotFoundError{ErrContentNotFound}
}

// NewDeleted returns http StatusAccepted response
func NewDeleted() (int, http.Header, interface{}, error) {
	return http.StatusAccepted, nil, nil, nil
}

// NewDefaultOK returns http StatusOK response with `{status:true}` response
func NewDefaultOK() (int, http.Header, interface{}, error) {
	res := map[string]interface{}{
		"status": true,
	}

	return NewOK(res)
}
<|endoftext|>


<commit_before>package request_agent

import (
	"bytes"
	"encoding/binary"
	"net"
	"testing"
	"time"

	"github.com/mark-rushakoff/go_tftpd/helpers"
	"github.com/mark-rushakoff/go_tftpd/messages"
)

const timeoutMs = 100

func TestAcknowledgementPacketCausesAck(t *testing.T) {
	const blockNum uint16 = 1234

	conn := &helpers.MockPacketConn{}
	conn.ReadFromFunc = buildReaderFunc(t, []interface{}{
		uint16(messages.AckOpcode),
		uint16(blockNum),
	})

	agent := NewRequestAgent(conn)
	go agent.Read()

	select {
	case ack := <-agent.Ack:
		if ack.BlockNumber != blockNum {
			t.Errorf("Received block number %v, expected %v", ack.BlockNumber, blockNum)
		}
	case <-time.After(timeoutMs * time.Millisecond):
		t.Errorf("Did not receive Ack in time")
	}
}

func TestErrorPacketCausesError(t *testing.T) {
	const blockNum uint16 = 3456

	conn := &helpers.MockPacketConn{}
	conn.ReadFromFunc = buildReaderFunc(t, []interface{}{
		uint16(messages.ErrorOpcode),
		uint16(messages.FileNotFound),
		string("lol"),
		byte(0),
	})

	agent := NewRequestAgent(conn)
	go agent.Read()

	select {
	case errorPacket := <-agent.Error:
		expectedCode := messages.FileNotFound
		if errorPacket.Code != expectedCode {
			t.Errorf("Received code %v, expected %v", errorPacket.Code, expectedCode)
		}

		expectedMessage := "lol"
		if errorPacket.Message != expectedMessage {
			t.Errorf("Received message %v, expected %v", errorPacket.Message, expectedMessage)
		}
	case <-time.After(timeoutMs * time.Millisecond):
		t.Errorf("Did not receive Error in time")
	}
}

func TestDataPacketCausesData(t *testing.T) {
	const blockNum uint16 = 2345

	conn := &helpers.MockPacketConn{}
	conn.ReadFromFunc = buildReaderFunc(t, []interface{}{
		uint16(messages.DataOpcode),
		uint16(blockNum),
		[]byte{0, 1, 2, 3, 4, 5, 255},
	})

	agent := NewRequestAgent(conn)
	go agent.Read()

	select {
	case data := <-agent.Data:
		if data.BlockNumber != blockNum {
			t.Errorf("Received block number %v, expected %v", data.BlockNumber, blockNum)
		}

		expectedData := []byte{0, 1, 2, 3, 4, 5, 255}
		if !bytes.Equal(data.Data, expectedData) {
			t.Errorf("Received data %v, expected %v", data.Data, expectedData)
		}
	case <-time.After(timeoutMs * time.Millisecond):
		t.Errorf("Did not receive Data in time")
	}
}

func TestReadRequestPacketCausesReadRequest(t *testing.T) {
	const blockNum uint16 = 9876

	conn := &helpers.MockPacketConn{}
	conn.ReadFromFunc = buildReaderFunc(t, []interface{}{
		uint16(messages.ReadOpcode),
		string("/foo/bar"),
		byte(0),
		string("netascii"),
		byte(0),
	})

	agent := NewRequestAgent(conn)
	go agent.Read()

	select {
	case readPacket := <-agent.ReadRequest:
		expectedFilename := "/foo/bar"
		if readPacket.Filename != expectedFilename {
			t.Errorf("Received name %v, expected %v", readPacket.Filename, expectedFilename)
		}

		expectedMode := messages.NetAscii
		if readPacket.Mode != expectedMode {
			t.Errorf("Received mode %v, expected %v", readPacket.Mode, expectedMode)
		}
	case <-time.After(timeoutMs * time.Millisecond):
		t.Errorf("Did not receive Read in time")
	}
}

func TestWriteRequestPacketCausesWriteRequest(t *testing.T) {
	t.Skipf("Pending")
}

func buildReaderFunc(t *testing.T, data []interface{}) func([]byte) (int, net.Addr, error) {
	wasCalledOnce := false
	return func(b []byte) (int, net.Addr, error) {
		if wasCalledOnce {
			// block forever
			select {}
		}
		wasCalledOnce = true

		buf := new(bytes.Buffer)
		for _, v := range data {
			str, isString := v.(string)
			if isString {
				_, err := buf.WriteString(str)
				if err != nil {
					t.Errorf("Failed to write string to buffer")
				}
			} else {
				err := binary.Write(buf, binary.BigEndian, v)
				if err != nil {
					t.Errorf("Failed to write data to buffer")
				}
			}
		}
		n := copy(b, buf.Bytes())
		return n, nil, nil
	}
}
<commit_msg>More test DRYing<commit_after>package request_agent

import (
	"bytes"
	"encoding/binary"
	"net"
	"testing"
	"time"

	"github.com/mark-rushakoff/go_tftpd/helpers"
	"github.com/mark-rushakoff/go_tftpd/messages"
)

const timeoutMs = 100

func TestAcknowledgementPacketCausesAck(t *testing.T) {
	const blockNum uint16 = 1234

	agent := agentWithIncomingPacket(t, []interface{}{
		uint16(messages.AckOpcode),
		uint16(blockNum),
	})

	select {
	case ack := <-agent.Ack:
		if ack.BlockNumber != blockNum {
			t.Errorf("Received block number %v, expected %v", ack.BlockNumber, blockNum)
		}
	case <-time.After(timeoutMs * time.Millisecond):
		t.Errorf("Did not receive Ack in time")
	}
}

func TestErrorPacketCausesError(t *testing.T) {
	const blockNum uint16 = 3456

	agent := agentWithIncomingPacket(t, []interface{}{
		uint16(messages.ErrorOpcode),
		uint16(messages.FileNotFound),
		string("lol"),
		byte(0),
	})

	select {
	case errorPacket := <-agent.Error:
		expectedCode := messages.FileNotFound
		if errorPacket.Code != expectedCode {
			t.Errorf("Received code %v, expected %v", errorPacket.Code, expectedCode)
		}

		expectedMessage := "lol"
		if errorPacket.Message != expectedMessage {
			t.Errorf("Received message %v, expected %v", errorPacket.Message, expectedMessage)
		}
	case <-time.After(timeoutMs * time.Millisecond):
		t.Errorf("Did not receive Error in time")
	}
}

func TestDataPacketCausesData(t *testing.T) {
	const blockNum uint16 = 2345

	agent := agentWithIncomingPacket(t, []interface{}{
		uint16(messages.DataOpcode),
		uint16(blockNum),
		[]byte{0, 1, 2, 3, 4, 5, 255},
	})

	select {
	case data := <-agent.Data:
		if data.BlockNumber != blockNum {
			t.Errorf("Received block number %v, expected %v", data.BlockNumber, blockNum)
		}

		expectedData := []byte{0, 1, 2, 3, 4, 5, 255}
		if !bytes.Equal(data.Data, expectedData) {
			t.Errorf("Received data %v, expected %v", data.Data, expectedData)
		}
	case <-time.After(timeoutMs * time.Millisecond):
		t.Errorf("Did not receive Data in time")
	}
}

func TestReadRequestPacketCausesReadRequest(t *testing.T) {
	const blockNum uint16 = 9876

	agent := agentWithIncomingPacket(t, []interface{}{
		uint16(messages.ReadOpcode),
		string("/foo/bar"),
		byte(0),
		string("netascii"),
		byte(0),
	})

	select {
	case readPacket := <-agent.ReadRequest:
		expectedFilename := "/foo/bar"
		if readPacket.Filename != expectedFilename {
			t.Errorf("Received name %v, expected %v", readPacket.Filename, expectedFilename)
		}

		expectedMode := messages.NetAscii
		if readPacket.Mode != expectedMode {
			t.Errorf("Received mode %v, expected %v", readPacket.Mode, expectedMode)
		}
	case <-time.After(timeoutMs * time.Millisecond):
		t.Errorf("Did not receive Read in time")
	}
}

func TestWriteRequestPacketCausesWriteRequest(t *testing.T) {
	t.Skipf("Pending")
}

func agentWithIncomingPacket(t *testing.T, data []interface{}) *RequestAgent {
	conn := &helpers.MockPacketConn{
		ReadFromFunc: buildReaderFunc(t, data),
	}

	agent := NewRequestAgent(conn)
	go agent.Read()

	return agent
}

func buildReaderFunc(t *testing.T, data []interface{}) func([]byte) (int, net.Addr, error) {
	wasCalledOnce := false
	return func(b []byte) (int, net.Addr, error) {
		if wasCalledOnce {
			// block forever
			select {}
		}
		wasCalledOnce = true

		buf := new(bytes.Buffer)
		for _, v := range data {
			str, isString := v.(string)
			if isString {
				_, err := buf.WriteString(str)
				if err != nil {
					t.Errorf("Failed to write string to buffer")
				}
			} else {
				err := binary.Write(buf, binary.BigEndian, v)
				if err != nil {
					t.Errorf("Failed to write data to buffer")
				}
			}
		}
		n := copy(b, buf.Bytes())
		return n, nil, nil
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package e2e

import (
	"fmt"
	"os"
	"strings"
	"time"

	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5"
	fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util"
	"k8s.io/kubernetes/pkg/api/unversioned"
	"k8s.io/kubernetes/pkg/api/v1"
	"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
	"k8s.io/kubernetes/pkg/util/wait"
	"k8s.io/kubernetes/test/e2e/framework"

	"reflect"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"k8s.io/kubernetes/pkg/api/errors"
)

const (
	FederationDeploymentName   = "federation-deployment"
	FederatedDeploymentTimeout = 120 * time.Second
)

// Create/delete deployment api objects
var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", func() {
	f := framework.NewDefaultFederatedFramework("federation-deployment")

	Describe("Deployment objects", func() {
		AfterEach(func() {
			framework.SkipUnlessFederated(f.ClientSet)

			// Delete all deployments.
			nsName := f.FederationNamespace.Name
			deleteAllDeploymentsOrFail(f.FederationClientset_1_5, nsName)
		})

		It("should be created and deleted successfully", func() {
			framework.SkipUnlessFederated(f.ClientSet)

			nsName := f.FederationNamespace.Name
			deployment := createDeploymentOrFail(f.FederationClientset_1_5, nsName)
			By(fmt.Sprintf("Creation of deployment %q in namespace %q succeeded.  Deleting deployment.", deployment.Name, nsName))
			// Cleanup
			err := f.FederationClientset_1_5.Extensions().Deployments(nsName).Delete(deployment.Name, &v1.DeleteOptions{})
			framework.ExpectNoError(err, "Error deleting deployment %q in namespace %q", deployment.Name, deployment.Namespace)
			By(fmt.Sprintf("Deletion of deployment %q in namespace %q succeeded.", deployment.Name, nsName))
		})

	})

	// e2e cases for federated deployment controller
	Describe("Federated Deployment", func() {
		var (
			clusters       map[string]*cluster
			federationName string
		)
		BeforeEach(func() {
			framework.SkipUnlessFederated(f.ClientSet)
			if federationName = os.Getenv("FEDERATION_NAME"); federationName == "" {
				federationName = DefaultFederationName
			}
			clusters = map[string]*cluster{}
			registerClusters(clusters, UserAgentName, federationName, f)
		})

		AfterEach(func() {
			nsName := f.FederationNamespace.Name
			deleteAllDeploymentsOrFail(f.FederationClientset_1_5, nsName)
			unregisterClusters(clusters, f)
		})

		It("should create and update matching deployments in underling clusters", func() {
			nsName := f.FederationNamespace.Name
			dep := createDeploymentOrFail(f.FederationClientset_1_5, nsName)
			defer func() {
				// cleanup. deletion of deployments is not supported for underlying clusters
				By(fmt.Sprintf("Preparing deployment %q/%q for deletion by setting replicas to zero", nsName, dep.Name))
				replicas := int32(0)
				dep.Spec.Replicas = &replicas
				f.FederationClientset_1_5.Deployments(nsName).Update(dep)
				waitForDeploymentOrFail(f.FederationClientset_1_5, nsName, dep.Name, clusters)
				f.FederationClientset_1_5.Deployments(nsName).Delete(dep.Name, &v1.DeleteOptions{})
			}()

			waitForDeploymentOrFail(f.FederationClientset_1_5, nsName, dep.Name, clusters)
			By(fmt.Sprintf("Successfuly created and synced deployment %q/%q to clusters", nsName, dep.Name))
			updateDeploymentOrFail(f.FederationClientset_1_5, nsName)
			waitForDeploymentOrFail(f.FederationClientset_1_5, nsName, dep.Name, clusters)
			By(fmt.Sprintf("Successfuly updated and synced deployment %q/%q to clusters", nsName, dep.Name))
		})

		It("should be deleted from underlying clusters when OrphanDependents is false", func() {
			framework.SkipUnlessFederated(f.ClientSet)
			nsName := f.FederationNamespace.Name
			orphanDependents := false
			verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
			By(fmt.Sprintf("Verified that deployments were deleted from underlying clusters"))
		})

		It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
			framework.SkipUnlessFederated(f.ClientSet)
			nsName := f.FederationNamespace.Name
			orphanDependents := true
			verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
			By(fmt.Sprintf("Verified that deployments were not deleted from underlying clusters"))
		})

		It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
			framework.SkipUnlessFederated(f.ClientSet)
			nsName := f.FederationNamespace.Name
			verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, nil, nsName)
			By(fmt.Sprintf("Verified that deployments were not deleted from underlying clusters"))
		})

	})
})

// deleteAllDeploymentsOrFail deletes all deployments in the given namespace name.
func deleteAllDeploymentsOrFail(clientset *fedclientset.Clientset, nsName string) {
	deploymentList, err := clientset.Extensions().Deployments(nsName).List(v1.ListOptions{})
	Expect(err).NotTo(HaveOccurred())
	orphanDependents := false
	for _, deployment := range deploymentList.Items {
		deleteDeploymentOrFail(clientset, nsName, deployment.Name, &orphanDependents)
	}
}

// verifyCascadingDeletionForDeployment verifies that deployments are deleted
// from underlying clusters when orphan dependents is false and they are not
// deleted when orphan dependents is true.
func verifyCascadingDeletionForDeployment(clientset *fedclientset.Clientset, clusters map[string]*cluster, orphanDependents *bool, nsName string) {
	deployment := createDeploymentOrFail(clientset, nsName)
	deploymentName := deployment.Name
	// Check subclusters if the deployment was created there.
	By(fmt.Sprintf("Waiting for deployment %s to be created in all underlying clusters", deploymentName))
	err := wait.Poll(5*time.Second, 2*time.Minute, func() (bool, error) {
		for _, cluster := range clusters {
			_, err := cluster.Extensions().Deployments(nsName).Get(deploymentName)
			if err != nil && errors.IsNotFound(err) {
				return false, nil
			}
			if err != nil {
				return false, err
			}
		}
		return true, nil
	})
	framework.ExpectNoError(err, "Not all deployments created")

	By(fmt.Sprintf("Deleting deployment %s", deploymentName))
	deleteDeploymentOrFail(clientset, nsName, deploymentName, orphanDependents)

	By(fmt.Sprintf("Verifying deployments %s in underlying clusters", deploymentName))
	errMessages := []string{}
	// deployment should be present in underlying clusters unless orphanDependents is false.
	shouldExist := orphanDependents == nil || *orphanDependents == true
	for clusterName, clusterClientset := range clusters {
		_, err := clusterClientset.Extensions().Deployments(nsName).Get(deploymentName)
		if shouldExist && errors.IsNotFound(err) {
			errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for deployment %s in cluster %s, expected deployment to exist", deploymentName, clusterName))
		} else if shouldExist && !errors.IsNotFound(err) {
			errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for deployment %s in cluster %s, got error: %v", deploymentName, clusterName, err))
		}
	}
	if len(errMessages) != 0 {
		framework.Failf("%s", strings.Join(errMessages, "; "))
	}
}

func waitForDeploymentOrFail(c *fedclientset.Clientset, namespace string, deploymentName string, clusters map[string]*cluster) {
	err := waitForDeployment(c, namespace, deploymentName, clusters)
	framework.ExpectNoError(err, "Failed to verify deployment %q/%q, err: %v", namespace, deploymentName, err)
}

func waitForDeployment(c *fedclientset.Clientset, namespace string, deploymentName string, clusters map[string]*cluster) error {
	err := wait.Poll(10*time.Second, FederatedDeploymentTimeout, func() (bool, error) {
		fdep, err := c.Deployments(namespace).Get(deploymentName)
		if err != nil {
			return false, err
		}
		specReplicas, statusReplicas := int32(0), int32(0)
		for _, cluster := range clusters {
			dep, err := cluster.Deployments(namespace).Get(deploymentName)
			if err != nil && !errors.IsNotFound(err) {
				By(fmt.Sprintf("Failed getting deployment: %q/%q/%q, err: %v", cluster.name, namespace, deploymentName, err))
				return false, err
			}
			if err == nil {
				if !equivalentDeployment(fdep, dep) {
					By(fmt.Sprintf("Deployment meta or spec not match for cluster %q:\n    federation: %v\n    cluster: %v", cluster.name, fdep, dep))
					return false, nil
				}
				specReplicas += *dep.Spec.Replicas
				statusReplicas += dep.Status.Replicas
			}
		}
		if statusReplicas == fdep.Status.Replicas && specReplicas >= *fdep.Spec.Replicas {
			return true, nil
		}
		By(fmt.Sprintf("Replicas not match, federation replicas: %v/%v, clusters replicas: %v/%v\n", *fdep.Spec.Replicas, fdep.Status.Replicas, specReplicas, statusReplicas))
		return false, nil
	})

	return err
}

func equivalentDeployment(fedDeployment, localDeployment *v1beta1.Deployment) bool {
	localDeploymentSpec := localDeployment.Spec
	localDeploymentSpec.Replicas = fedDeployment.Spec.Replicas
	return fedutil.ObjectMetaEquivalent(fedDeployment.ObjectMeta, localDeployment.ObjectMeta) &&
		reflect.DeepEqual(fedDeployment.Spec, localDeploymentSpec)
}

func createDeploymentOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.Deployment {
	if clientset == nil || len(namespace) == 0 {
		Fail(fmt.Sprintf("Internal error: invalid parameters passed to createDeploymentOrFail: clientset: %v, namespace: %v", clientset, namespace))
	}
	By(fmt.Sprintf("Creating federation deployment %q in namespace %q", FederationDeploymentName, namespace))

	deployment := newDeploymentForFed(namespace, FederationDeploymentName, 5)

	_, err := clientset.Extensions().Deployments(namespace).Create(deployment)
	framework.ExpectNoError(err, "Creating deployment %q in namespace %q", deployment.Name, namespace)
	By(fmt.Sprintf("Successfully created federation deployment %q in namespace %q", FederationDeploymentName, namespace))
	return deployment
}

func updateDeploymentOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.Deployment {
	if clientset == nil || len(namespace) == 0 {
		Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateDeploymentOrFail: clientset: %v, namespace: %v", clientset, namespace))
	}
	By(fmt.Sprintf("Updating federation deployment %q in namespace %q", FederationDeploymentName, namespace))

	deployment := newDeploymentForFed(namespace, FederationDeploymentName, 15)

	newRs, err := clientset.Deployments(namespace).Update(deployment)
	framework.ExpectNoError(err, "Updating deployment %q in namespace %q", deployment.Name, namespace)
	By(fmt.Sprintf("Successfully updated federation deployment %q in namespace %q", FederationDeploymentName, namespace))

	return newRs
}

func deleteDeploymentOrFail(clientset *fedclientset.Clientset, nsName string, deploymentName string, orphanDependents *bool) {
	By(fmt.Sprintf("Deleting deployment %q in namespace %q", deploymentName, nsName))
	err := clientset.Extensions().Deployments(nsName).Delete(deploymentName, &v1.DeleteOptions{OrphanDependents: orphanDependents})
	framework.ExpectNoError(err, "Error deleting deployment %q in namespace %q", deploymentName, nsName)

	// Wait for the deployment to be deleted.
	err = wait.Poll(5*time.Second, wait.ForeverTestTimeout, func() (bool, error) {
		_, err := clientset.Extensions().Deployments(nsName).Get(deploymentName)
		if err != nil && errors.IsNotFound(err) {
			return true, nil
		}
		return false, err
	})
	if err != nil {
		framework.Failf("Error in deleting deployment %s: %v", deploymentName, err)
	}
}

func newDeploymentForFed(namespace string, name string, replicas int32) *v1beta1.Deployment {
	return &v1beta1.Deployment{
		ObjectMeta: v1.ObjectMeta{
			Name:      name,
			Namespace: namespace,
		},
		Spec: v1beta1.DeploymentSpec{
			Replicas: &replicas,
			Selector: &unversioned.LabelSelector{
				MatchLabels: map[string]string{"name": "myrs"},
			},
			Template: v1.PodTemplateSpec{
				ObjectMeta: v1.ObjectMeta{
					Labels: map[string]string{"name": "myrs"},
				},
				Spec: v1.PodSpec{
					Containers: []v1.Container{
						{
							Name:  "nginx",
							Image: "nginx",
						},
					},
				},
			},
		},
	}
}
<commit_msg>Fixing a typo in deployment e2e<commit_after>/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package e2e

import (
	"fmt"
	"os"
	"strings"
	"time"

	fedclientset "k8s.io/kubernetes/federation/client/clientset_generated/federation_release_1_5"
	fedutil "k8s.io/kubernetes/federation/pkg/federation-controller/util"
	"k8s.io/kubernetes/pkg/api/unversioned"
	"k8s.io/kubernetes/pkg/api/v1"
	"k8s.io/kubernetes/pkg/apis/extensions/v1beta1"
	"k8s.io/kubernetes/pkg/util/wait"
	"k8s.io/kubernetes/test/e2e/framework"

	"reflect"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"k8s.io/kubernetes/pkg/api/errors"
)

const (
	FederationDeploymentName   = "federation-deployment"
	FederatedDeploymentTimeout = 120 * time.Second
)

// Create/delete deployment api objects
var _ = framework.KubeDescribe("Federation deployments [Feature:Federation]", func() {
	f := framework.NewDefaultFederatedFramework("federation-deployment")

	Describe("Deployment objects", func() {
		AfterEach(func() {
			framework.SkipUnlessFederated(f.ClientSet)

			// Delete all deployments.
			nsName := f.FederationNamespace.Name
			deleteAllDeploymentsOrFail(f.FederationClientset_1_5, nsName)
		})

		It("should be created and deleted successfully", func() {
			framework.SkipUnlessFederated(f.ClientSet)

			nsName := f.FederationNamespace.Name
			deployment := createDeploymentOrFail(f.FederationClientset_1_5, nsName)
			By(fmt.Sprintf("Creation of deployment %q in namespace %q succeeded.  Deleting deployment.", deployment.Name, nsName))
			// Cleanup
			err := f.FederationClientset_1_5.Extensions().Deployments(nsName).Delete(deployment.Name, &v1.DeleteOptions{})
			framework.ExpectNoError(err, "Error deleting deployment %q in namespace %q", deployment.Name, deployment.Namespace)
			By(fmt.Sprintf("Deletion of deployment %q in namespace %q succeeded.", deployment.Name, nsName))
		})

	})

	// e2e cases for federated deployment controller
	Describe("Federated Deployment", func() {
		var (
			clusters       map[string]*cluster
			federationName string
		)
		BeforeEach(func() {
			framework.SkipUnlessFederated(f.ClientSet)
			if federationName = os.Getenv("FEDERATION_NAME"); federationName == "" {
				federationName = DefaultFederationName
			}
			clusters = map[string]*cluster{}
			registerClusters(clusters, UserAgentName, federationName, f)
		})

		AfterEach(func() {
			nsName := f.FederationNamespace.Name
			deleteAllDeploymentsOrFail(f.FederationClientset_1_5, nsName)
			unregisterClusters(clusters, f)
		})

		It("should create and update matching deployments in underling clusters", func() {
			nsName := f.FederationNamespace.Name
			dep := createDeploymentOrFail(f.FederationClientset_1_5, nsName)
			defer func() {
				// cleanup. deletion of deployments is not supported for underlying clusters
				By(fmt.Sprintf("Preparing deployment %q/%q for deletion by setting replicas to zero", nsName, dep.Name))
				replicas := int32(0)
				dep.Spec.Replicas = &replicas
				f.FederationClientset_1_5.Deployments(nsName).Update(dep)
				waitForDeploymentOrFail(f.FederationClientset_1_5, nsName, dep.Name, clusters)
				f.FederationClientset_1_5.Deployments(nsName).Delete(dep.Name, &v1.DeleteOptions{})
			}()

			waitForDeploymentOrFail(f.FederationClientset_1_5, nsName, dep.Name, clusters)
			By(fmt.Sprintf("Successfuly created and synced deployment %q/%q to clusters", nsName, dep.Name))
			updateDeploymentOrFail(f.FederationClientset_1_5, nsName)
			waitForDeploymentOrFail(f.FederationClientset_1_5, nsName, dep.Name, clusters)
			By(fmt.Sprintf("Successfuly updated and synced deployment %q/%q to clusters", nsName, dep.Name))
		})

		It("should be deleted from underlying clusters when OrphanDependents is false", func() {
			framework.SkipUnlessFederated(f.ClientSet)
			nsName := f.FederationNamespace.Name
			orphanDependents := false
			verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
			By(fmt.Sprintf("Verified that deployments were deleted from underlying clusters"))
		})

		It("should not be deleted from underlying clusters when OrphanDependents is true", func() {
			framework.SkipUnlessFederated(f.ClientSet)
			nsName := f.FederationNamespace.Name
			orphanDependents := true
			verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, &orphanDependents, nsName)
			By(fmt.Sprintf("Verified that deployments were not deleted from underlying clusters"))
		})

		It("should not be deleted from underlying clusters when OrphanDependents is nil", func() {
			framework.SkipUnlessFederated(f.ClientSet)
			nsName := f.FederationNamespace.Name
			verifyCascadingDeletionForDeployment(f.FederationClientset_1_5, clusters, nil, nsName)
			By(fmt.Sprintf("Verified that deployments were not deleted from underlying clusters"))
		})

	})
})

// deleteAllDeploymentsOrFail deletes all deployments in the given namespace name.
func deleteAllDeploymentsOrFail(clientset *fedclientset.Clientset, nsName string) {
	deploymentList, err := clientset.Extensions().Deployments(nsName).List(v1.ListOptions{})
	Expect(err).NotTo(HaveOccurred())
	orphanDependents := false
	for _, deployment := range deploymentList.Items {
		deleteDeploymentOrFail(clientset, nsName, deployment.Name, &orphanDependents)
	}
}

// verifyCascadingDeletionForDeployment verifies that deployments are deleted
// from underlying clusters when orphan dependents is false and they are not
// deleted when orphan dependents is true.
func verifyCascadingDeletionForDeployment(clientset *fedclientset.Clientset, clusters map[string]*cluster, orphanDependents *bool, nsName string) {
	deployment := createDeploymentOrFail(clientset, nsName)
	deploymentName := deployment.Name
	// Check subclusters if the deployment was created there.
	By(fmt.Sprintf("Waiting for deployment %s to be created in all underlying clusters", deploymentName))
	err := wait.Poll(5*time.Second, 2*time.Minute, func() (bool, error) {
		for _, cluster := range clusters {
			_, err := cluster.Extensions().Deployments(nsName).Get(deploymentName)
			if err != nil && errors.IsNotFound(err) {
				return false, nil
			}
			if err != nil {
				return false, err
			}
		}
		return true, nil
	})
	framework.ExpectNoError(err, "Not all deployments created")

	By(fmt.Sprintf("Deleting deployment %s", deploymentName))
	deleteDeploymentOrFail(clientset, nsName, deploymentName, orphanDependents)

	By(fmt.Sprintf("Verifying deployments %s in underlying clusters", deploymentName))
	errMessages := []string{}
	// deployment should be present in underlying clusters unless orphanDependents is false.
	shouldExist := orphanDependents == nil || *orphanDependents == true
	for clusterName, clusterClientset := range clusters {
		_, err := clusterClientset.Extensions().Deployments(nsName).Get(deploymentName)
		if shouldExist && errors.IsNotFound(err) {
			errMessages = append(errMessages, fmt.Sprintf("unexpected NotFound error for deployment %s in cluster %s, expected deployment to exist", deploymentName, clusterName))
		} else if !shouldExist && !errors.IsNotFound(err) {
			errMessages = append(errMessages, fmt.Sprintf("expected NotFound error for deployment %s in cluster %s, got error: %v", deploymentName, clusterName, err))
		}
	}
	if len(errMessages) != 0 {
		framework.Failf("%s", strings.Join(errMessages, "; "))
	}
}

func waitForDeploymentOrFail(c *fedclientset.Clientset, namespace string, deploymentName string, clusters map[string]*cluster) {
	err := waitForDeployment(c, namespace, deploymentName, clusters)
	framework.ExpectNoError(err, "Failed to verify deployment %q/%q, err: %v", namespace, deploymentName, err)
}

func waitForDeployment(c *fedclientset.Clientset, namespace string, deploymentName string, clusters map[string]*cluster) error {
	err := wait.Poll(10*time.Second, FederatedDeploymentTimeout, func() (bool, error) {
		fdep, err := c.Deployments(namespace).Get(deploymentName)
		if err != nil {
			return false, err
		}
		specReplicas, statusReplicas := int32(0), int32(0)
		for _, cluster := range clusters {
			dep, err := cluster.Deployments(namespace).Get(deploymentName)
			if err != nil && !errors.IsNotFound(err) {
				By(fmt.Sprintf("Failed getting deployment: %q/%q/%q, err: %v", cluster.name, namespace, deploymentName, err))
				return false, err
			}
			if err == nil {
				if !equivalentDeployment(fdep, dep) {
					By(fmt.Sprintf("Deployment meta or spec not match for cluster %q:\n    federation: %v\n    cluster: %v", cluster.name, fdep, dep))
					return false, nil
				}
				specReplicas += *dep.Spec.Replicas
				statusReplicas += dep.Status.Replicas
			}
		}
		if statusReplicas == fdep.Status.Replicas && specReplicas >= *fdep.Spec.Replicas {
			return true, nil
		}
		By(fmt.Sprintf("Replicas not match, federation replicas: %v/%v, clusters replicas: %v/%v\n", *fdep.Spec.Replicas, fdep.Status.Replicas, specReplicas, statusReplicas))
		return false, nil
	})

	return err
}

func equivalentDeployment(fedDeployment, localDeployment *v1beta1.Deployment) bool {
	localDeploymentSpec := localDeployment.Spec
	localDeploymentSpec.Replicas = fedDeployment.Spec.Replicas
	return fedutil.ObjectMetaEquivalent(fedDeployment.ObjectMeta, localDeployment.ObjectMeta) &&
		reflect.DeepEqual(fedDeployment.Spec, localDeploymentSpec)
}

func createDeploymentOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.Deployment {
	if clientset == nil || len(namespace) == 0 {
		Fail(fmt.Sprintf("Internal error: invalid parameters passed to createDeploymentOrFail: clientset: %v, namespace: %v", clientset, namespace))
	}
	By(fmt.Sprintf("Creating federation deployment %q in namespace %q", FederationDeploymentName, namespace))

	deployment := newDeploymentForFed(namespace, FederationDeploymentName, 5)

	_, err := clientset.Extensions().Deployments(namespace).Create(deployment)
	framework.ExpectNoError(err, "Creating deployment %q in namespace %q", deployment.Name, namespace)
	By(fmt.Sprintf("Successfully created federation deployment %q in namespace %q", FederationDeploymentName, namespace))
	return deployment
}

func updateDeploymentOrFail(clientset *fedclientset.Clientset, namespace string) *v1beta1.Deployment {
	if clientset == nil || len(namespace) == 0 {
		Fail(fmt.Sprintf("Internal error: invalid parameters passed to updateDeploymentOrFail: clientset: %v, namespace: %v", clientset, namespace))
	}
	By(fmt.Sprintf("Updating federation deployment %q in namespace %q", FederationDeploymentName, namespace))

	deployment := newDeploymentForFed(namespace, FederationDeploymentName, 15)

	newRs, err := clientset.Deployments(namespace).Update(deployment)
	framework.ExpectNoError(err, "Updating deployment %q in namespace %q", deployment.Name, namespace)
	By(fmt.Sprintf("Successfully updated federation deployment %q in namespace %q", FederationDeploymentName, namespace))

	return newRs
}

func deleteDeploymentOrFail(clientset *fedclientset.Clientset, nsName string, deploymentName string, orphanDependents *bool) {
	By(fmt.Sprintf("Deleting deployment %q in namespace %q", deploymentName, nsName))
	err := clientset.Extensions().Deployments(nsName).Delete(deploymentName, &v1.DeleteOptions{OrphanDependents: orphanDependents})
	framework.ExpectNoError(err, "Error deleting deployment %q in namespace %q", deploymentName, nsName)

	// Wait for the deployment to be deleted.
	err = wait.Poll(5*time.Second, wait.ForeverTestTimeout, func() (bool, error) {
		_, err := clientset.Extensions().Deployments(nsName).Get(deploymentName)
		if err != nil && errors.IsNotFound(err) {
			return true, nil
		}
		return false, err
	})
	if err != nil {
		framework.Failf("Error in deleting deployment %s: %v", deploymentName, err)
	}
}

func newDeploymentForFed(namespace string, name string, replicas int32) *v1beta1.Deployment {
	return &v1beta1.Deployment{
		ObjectMeta: v1.ObjectMeta{
			Name:      name,
			Namespace: namespace,
		},
		Spec: v1beta1.DeploymentSpec{
			Replicas: &replicas,
			Selector: &unversioned.LabelSelector{
				MatchLabels: map[string]string{"name": "myrs"},
			},
			Template: v1.PodTemplateSpec{
				ObjectMeta: v1.ObjectMeta{
					Labels: map[string]string{"name": "myrs"},
				},
				Spec: v1.PodSpec{
					Containers: []v1.Container{
						{
							Name:  "nginx",
							Image: "nginx",
						},
					},
				},
			},
		},
	}
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"testing"
	"time"
)

const exampleTimeString = "2012-08-28T21:24:35.37465188Z"
const milliAccuracy = "2012-08-28T21:24:35.374Z"
const secondAccuracy = "2012-08-28T21:24:35Z"

var exampleTime time.Time

func init() {
	var err error
	exampleTime, err = time.Parse(time.RFC3339, exampleTimeString)
	if err != nil {
		panic(err)
	}
	if exampleTimeString != exampleTime.UTC().Format(time.RFC3339Nano) {
		log.Panicf("Expected %v, got %v", exampleTimeString,
			exampleTime.UTC().Format(time.RFC3339Nano))
	}
}

func TestTimeParsing(t *testing.T) {
	tests := []struct {
		input string
		exp   string
	}{
		{"1346189075374651880", exampleTimeString},
		{"1346189075374", milliAccuracy},
		{"1346189075", secondAccuracy},
		{"2012-08-28T21:24:35.37465188Z", exampleTimeString},
		{secondAccuracy, secondAccuracy},
		{"Tue, 28 Aug 2012 21:24:35 +0000", secondAccuracy},
		{"Tue, 28 Aug 2012 21:24:35 UTC", secondAccuracy},
		{"Tue Aug 28 21:24:35 UTC 2012", secondAccuracy},
		{"Tue Aug 28 21:24:35 2012", secondAccuracy},
		{"Tue Aug 28 21:24:35 +0000 2012", secondAccuracy},
		{"2012-08-28T21:24", "2012-08-28T21:24:00Z"},
		{"2012-08-28T21", "2012-08-28T21:00:00Z"},
		{"2012-08-28", "2012-08-28T00:00:00Z"},
		{"2012-08", "2012-08-01T00:00:00Z"},
		{"2012", "2012-01-01T00:00:00Z"},
	}

	for _, x := range tests {
		tm, err := parseTime(x.input)
		if err != nil {
			t.Errorf("Error on %v - %v", x.input, err)
			t.Fail()
		}
		got := tm.UTC().Format(time.RFC3339Nano)
		if x.exp != got {
			t.Errorf("Expected %v for %v, got %v", x.exp, x.input, got)
			t.Fail()
		}
	}
}

func TestCanonicalParser(t *testing.T) {
	tests := []struct {
		input string
		exp   string
	}{
		{"2012-08-28T21:24:35.374651883Z", ""},
		{"2012-08-28T21:24:35.37465188Z", ""},
		{"2012-08-28T21:24:35.3746518Z", ""},
		{"2012-08-28T21:24:35.374651Z", ""},
		{"2012-08-28T21:24:35.37465Z", ""},
		{"2012-08-28T21:24:35.3746Z", ""},
		{"2012-08-28T21:24:35.374Z", ""},
		{"2012-08-28T21:24:35.37Z", ""},
		{"2012-08-28T21:24:35.3Z", ""},
		{"2012-08-28T21:24:35.0Z", "2012-08-28T21:24:35Z"},
		{"2012-08-28T21:24:35.Z", "2012-08-28T21:24:35Z"},
		{"2012-08-28T21:24:35Z", ""},
	}

	for _, x := range tests {
		tm, err := parseCanonicalTime(x.input)
		if err != nil {
			t.Errorf("Error on %v - %v", x.input, err)
			t.Fail()
		}
		got := tm.UTC().Format(time.RFC3339Nano)
		exp := x.exp
		if exp == "" {
			exp = x.input
		}
		if exp != got {
			t.Errorf("Expected %v for %v, got %v", x.exp, x.input, got)
			t.Fail()
		}
	}
}

func TestUnparseable(t *testing.T) {
	tm, err := parseTime("an hour ago")
	if err != errUnparseableTimestamp {
		t.Fatalf("Expected unparseable, got %v/%v", tm, err)
	}
}

func benchTimeParsing(b *testing.B, input string) {
	for i := 0; i < b.N; i++ {
		_, err := parseTime(input)
		if err != nil {
			b.Fatalf("Error on %v - %v", input, err)
		}
	}
}

func BenchmarkParseTimeCanonicalDirect(b *testing.B) {
	input := "2012-08-28T21:24:35.37465188Z"
	for i := 0; i < b.N; i++ {
		_, err := parseCanonicalTime(input)
		if err != nil {
			b.Fatalf("Error on %v - %v", input, err)
		}
	}
}

func BenchmarkParseTimeCanonicalStdlib(b *testing.B) {
	input := "2012-08-28T21:24:35.37465188Z"
	for i := 0; i < b.N; i++ {
		_, err := time.Parse(time.RFC3339, input)
		if err != nil {
			b.Fatalf("Error on %v - %v", input, err)
		}
	}
}

func BenchmarkParseTimeCanonical(b *testing.B) {
	benchTimeParsing(b, "2012-08-28T21:24:35.37465188Z")
}

func BenchmarkParseTimeMisc(b *testing.B) {
	benchTimeParsing(b, "Tue, 28 Aug 2012 21:24:35 +0000")
}

func BenchmarkParseTimeIntNano(b *testing.B) {
	benchTimeParsing(b, "1346189075374651880")
}

func BenchmarkParseTimeIntMillis(b *testing.B) {
	benchTimeParsing(b, "1346189075374")
}

func BenchmarkParseTimeIntSecs(b *testing.B) {
	benchTimeParsing(b, "1346189075")
}
<commit_msg>Test error paths in canonical parser<commit_after>package main

import (
	"log"
	"testing"
	"time"
)

const exampleTimeString = "2012-08-28T21:24:35.37465188Z"
const milliAccuracy = "2012-08-28T21:24:35.374Z"
const secondAccuracy = "2012-08-28T21:24:35Z"

var exampleTime time.Time

func init() {
	var err error
	exampleTime, err = time.Parse(time.RFC3339, exampleTimeString)
	if err != nil {
		panic(err)
	}
	if exampleTimeString != exampleTime.UTC().Format(time.RFC3339Nano) {
		log.Panicf("Expected %v, got %v", exampleTimeString,
			exampleTime.UTC().Format(time.RFC3339Nano))
	}
}

func TestTimeParsing(t *testing.T) {
	tests := []struct {
		input string
		exp   string
	}{
		{"1346189075374651880", exampleTimeString},
		{"1346189075374", milliAccuracy},
		{"1346189075", secondAccuracy},
		{"2012-08-28T21:24:35.37465188Z", exampleTimeString},
		{secondAccuracy, secondAccuracy},
		{"Tue, 28 Aug 2012 21:24:35 +0000", secondAccuracy},
		{"Tue, 28 Aug 2012 21:24:35 UTC", secondAccuracy},
		{"Tue Aug 28 21:24:35 UTC 2012", secondAccuracy},
		{"Tue Aug 28 21:24:35 2012", secondAccuracy},
		{"Tue Aug 28 21:24:35 +0000 2012", secondAccuracy},
		{"2012-08-28T21:24", "2012-08-28T21:24:00Z"},
		{"2012-08-28T21", "2012-08-28T21:00:00Z"},
		{"2012-08-28", "2012-08-28T00:00:00Z"},
		{"2012-08", "2012-08-01T00:00:00Z"},
		{"2012", "2012-01-01T00:00:00Z"},
	}

	for _, x := range tests {
		tm, err := parseTime(x.input)
		if err != nil {
			t.Errorf("Error on %v - %v", x.input, err)
			t.Fail()
		}
		got := tm.UTC().Format(time.RFC3339Nano)
		if x.exp != got {
			t.Errorf("Expected %v for %v, got %v", x.exp, x.input, got)
			t.Fail()
		}
	}
}

func TestCanonicalParser(t *testing.T) {
	tests := []struct {
		input string
		exp   string
	}{
		{"2012-08-28T21:24:35.374651883Z", ""},
		{"2012-08-28T21:24:35.37465188Z", ""},
		{"2012-08-28T21:24:35.3746518Z", ""},
		{"2012-08-28T21:24:35.374651Z", ""},
		{"2012-08-28T21:24:35.37465Z", ""},
		{"2012-08-28T21:24:35.3746Z", ""},
		{"2012-08-28T21:24:35.374Z", ""},
		{"2012-08-28T21:24:35.37Z", ""},
		{"2012-08-28T21:24:35.3Z", ""},
		{"2012-08-28T21:24:35.0Z", "2012-08-28T21:24:35Z"},
		{"2012-08-28T21:24:35.Z", "2012-08-28T21:24:35Z"},
		{"2012-08-28T21:24:35Z", ""},
	}

	for _, x := range tests {
		tm, err := parseCanonicalTime(x.input)
		if err != nil {
			t.Errorf("Error on %v - %v", x.input, err)
			t.Fail()
		}
		got := tm.UTC().Format(time.RFC3339Nano)
		exp := x.exp
		if exp == "" {
			exp = x.input
		}
		if exp != got {
			t.Errorf("Expected %v for %v, got %v", x.exp, x.input, got)
			t.Fail()
		}
	}
}

func TestCanonicalParsingErrors(t *testing.T) {
	tests := []string{
		"ZZZZZZZZZZZZZZZZZZZZ",
		"ZZZZ-ZZ-ZZTZZ:ZZ:ZZZ",
		"2014-ZZ-ZZTZZ:ZZ:ZZZ",
		"2014-03-ZZTZZ:ZZ:ZZZ",
		"2014-03-14TZZ:ZZ:ZZZ",
		"2014-03-14T15:ZZ:ZZZ",
		"2014-03-14T15:09:ZZZ",
		"2014-03-14T15:09:26.S35897Z",
	}

	for _, test := range tests {
		tm, err := parseCanonicalTime(test)
		if err == nil {
			t.Errorf("No error on %q, got %v", test, tm)
		}
	}
}

func TestUnparseable(t *testing.T) {
	tm, err := parseTime("an hour ago")
	if err != errUnparseableTimestamp {
		t.Fatalf("Expected unparseable, got %v/%v", tm, err)
	}
}

func benchTimeParsing(b *testing.B, input string) {
	for i := 0; i < b.N; i++ {
		_, err := parseTime(input)
		if err != nil {
			b.Fatalf("Error on %v - %v", input, err)
		}
	}
}

func BenchmarkParseTimeCanonicalDirect(b *testing.B) {
	input := "2012-08-28T21:24:35.37465188Z"
	for i := 0; i < b.N; i++ {
		_, err := parseCanonicalTime(input)
		if err != nil {
			b.Fatalf("Error on %v - %v", input, err)
		}
	}
}

func BenchmarkParseTimeCanonicalStdlib(b *testing.B) {
	input := "2012-08-28T21:24:35.37465188Z"
	for i := 0; i < b.N; i++ {
		_, err := time.Parse(time.RFC3339, input)
		if err != nil {
			b.Fatalf("Error on %v - %v", input, err)
		}
	}
}

func BenchmarkParseTimeCanonical(b *testing.B) {
	benchTimeParsing(b, "2012-08-28T21:24:35.37465188Z")
}

func BenchmarkParseTimeMisc(b *testing.B) {
	benchTimeParsing(b, "Tue, 28 Aug 2012 21:24:35 +0000")
}

func BenchmarkParseTimeIntNano(b *testing.B) {
	benchTimeParsing(b, "1346189075374651880")
}

func BenchmarkParseTimeIntMillis(b *testing.B) {
	benchTimeParsing(b, "1346189075374")
}

func BenchmarkParseTimeIntSecs(b *testing.B) {
	benchTimeParsing(b, "1346189075")
}
<|endoftext|>


<commit_before>package tokenex

import "encoding/json"

type TokenExResponse struct {
	Error           string
	ReferenceNumber string
	Success         bool
}

type TokenResponse struct {
	TokenExResponse
	Token string
}

type ValueResponse struct {
	TokenExResponse
	Value string
}

type ValidateResponse struct {
	TokenExResponse
	Valid bool
}

type DeleteResponse struct {
	TokenExResponse
}

func Tokenize(data string, tokenScheme int) TokenResponse {
	tData := map[string]interface{}{
		"Data":        data,
		"TokenScheme": tokenScheme,
	}
	data = request("Tokenize", tData)
	response := TokenResponse{}
	json.Unmarshal([]byte(data), &response)
	return response
}

func Detokenize(token string) ValueResponse {
	tData := map[string]interface{}{
		"Token": token,
	}
	data := request("Detokenize", tData)
	response := ValueResponse{}
	json.Unmarshal([]byte(data), &response)
	return response
}

func Validate(token string) ValidateResponse {
	tData := map[string]interface{}{
		"Token": token,
	}
	data := request("ValidateToken", tData)
	response := ValidateResponse{}
	json.Unmarshal([]byte(data), &response)
	return response
}

func Delete(token string) DeleteResponse {
	tData := map[string]interface{}{
		"Token": token,
	}
	data := request("DeleteToken", tData)
	response := DeleteResponse{}
	json.Unmarshal([]byte(data), &response)
	return response
}
<commit_msg>:penguin: type cleanups<commit_after>package tokenex

import "encoding/json"

type (
	TokenExResponse struct {
		Error           string
		ReferenceNumber string
		Success         bool
	}

	TokenResponse struct {
		TokenExResponse
		Token string
	}

	ValueResponse struct {
		TokenExResponse
		Value string
	}

	ValidateResponse struct {
		TokenExResponse
		Valid bool
	}

	DeleteResponse struct {
		TokenExResponse
	}
)

func Tokenize(data string, tokenScheme int) TokenResponse {
	tData := map[string]interface{}{
		"Data":        data,
		"TokenScheme": tokenScheme,
	}
	data = request("Tokenize", tData)
	response := TokenResponse{}
	json.Unmarshal([]byte(data), &response)
	return response
}

func Detokenize(token string) ValueResponse {
	tData := map[string]interface{}{
		"Token": token,
	}
	data := request("Detokenize", tData)
	response := ValueResponse{}
	json.Unmarshal([]byte(data), &response)
	return response
}

func Validate(token string) ValidateResponse {
	tData := map[string]interface{}{
		"Token": token,
	}
	data := request("ValidateToken", tData)
	response := ValidateResponse{}
	json.Unmarshal([]byte(data), &response)
	return response
}

func Delete(token string) DeleteResponse {
	tData := map[string]interface{}{
		"Token": token,
	}
	data := request("DeleteToken", tData)
	response := DeleteResponse{}
	json.Unmarshal([]byte(data), &response)
	return response
}
<|endoftext|>