<commit_before>/*
Copyright 2018 The Kubernetes Authors.

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

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

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

package ipamperf

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"testing"
	"time"

	"github.com/golang/glog"

	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/informers"
	clientset "k8s.io/client-go/kubernetes"
	restclient "k8s.io/client-go/rest"
	"k8s.io/kubernetes/pkg/controller/nodeipam"
	"k8s.io/kubernetes/pkg/controller/nodeipam/ipam"
	"k8s.io/kubernetes/test/integration/util"
)

func setupAllocator(apiURL string, config *Config, clusterCIDR, serviceCIDR *net.IPNet, subnetMaskSize int) (*clientset.Clientset, util.ShutdownFunc, error) {
	controllerStopChan := make(chan struct{})
	shutdownFunc := func() {
		close(controllerStopChan)
	}

	clientSet := clientset.NewForConfigOrDie(&restclient.Config{
		Host:          apiURL,
		ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}},
		QPS:           float32(config.KubeQPS),
		Burst:         config.KubeQPS,
	})

	sharedInformer := informers.NewSharedInformerFactory(clientSet, 1*time.Hour)
	ipamController, err := nodeipam.NewNodeIpamController(
		sharedInformer.Core().V1().Nodes(), config.Cloud, clientSet,
		clusterCIDR, serviceCIDR, subnetMaskSize, config.AllocatorType,
	)
	if err != nil {
		return nil, shutdownFunc, err
	}
	go ipamController.Run(controllerStopChan)
	sharedInformer.Start(controllerStopChan)

	return clientSet, shutdownFunc, nil
}

func runTest(t *testing.T, apiURL string, config *Config, clusterCIDR, serviceCIDR *net.IPNet, subnetMaskSize int) (*Results, error) {
	t.Helper()
	glog.Infof("Running test %s", t.Name())

	defer deleteNodes(apiURL, config) // cleanup nodes on after controller shutdown

	clientSet, shutdownFunc, err := setupAllocator(apiURL, config, clusterCIDR, serviceCIDR, subnetMaskSize)
	if err != nil {
		t.Fatalf("Error starting IPAM allocator: %v", err)
	}
	defer shutdownFunc()

	o := NewObserver(clientSet, config.NumNodes)
	if err := o.StartObserving(); err != nil {
		t.Fatalf("Could not start test observer: %v", err)
	}

	if err := createNodes(apiURL, config); err != nil {
		t.Fatalf("Could not create nodes: %v", err)
	}

	results := o.Results(t.Name(), config)
	glog.Infof("Results: %s", results)
	if !results.Succeeded {
		t.Errorf("%s: Not allocations succeeded", t.Name())
	}
	return results, nil
}

func logResults(allResults []*Results) {
	jStr, err := json.MarshalIndent(allResults, "", "  ")
	if err != nil {
		glog.Errorf("Error formating results: %v", err)
		return
	}
	if resultsLogFile != "" {
		glog.Infof("Logging results to %s", resultsLogFile)
		if err := ioutil.WriteFile(resultsLogFile, jStr, os.FileMode(0644)); err != nil {
			glog.Errorf("Error logging results to %s: %v", resultsLogFile, err)
		}
	}
	glog.Infof("AllResults:\n%s", string(jStr))
}

func TestPerformance(t *testing.T) {
	if testing.Short() {
		// TODO (#61854) find why flakiness is caused by etcd connectivity before enabling always
		t.Skip("Skipping because we want to run short tests")
	}

	apiURL, masterShutdown := util.StartApiserver()
	defer masterShutdown()

	_, clusterCIDR, _ := net.ParseCIDR("10.96.0.0/11") // allows up to 8K nodes
	_, serviceCIDR, _ := net.ParseCIDR("10.94.0.0/24") // does not matter for test - pick upto  250 services
	subnetMaskSize := 24

	var (
		allResults []*Results
		tests      []*Config
	)

	if isCustom {
		tests = append(tests, customConfig)
	} else {
		for _, numNodes := range []int{10, 100} {
			for _, alloc := range []ipam.CIDRAllocatorType{ipam.RangeAllocatorType, ipam.CloudAllocatorType, ipam.IPAMFromClusterAllocatorType, ipam.IPAMFromCloudAllocatorType} {
				tests = append(tests, &Config{AllocatorType: alloc, NumNodes: numNodes, CreateQPS: numNodes, KubeQPS: 10, CloudQPS: 10})
			}
		}
	}

	for _, test := range tests {
		testName := fmt.Sprintf("%s-KubeQPS%d-Nodes%d", test.AllocatorType, test.KubeQPS, test.NumNodes)
		t.Run(testName, func(t *testing.T) {
			allocateCIDR := false
			if test.AllocatorType == ipam.IPAMFromCloudAllocatorType || test.AllocatorType == ipam.CloudAllocatorType {
				allocateCIDR = true
			}
			bil := newBaseInstanceList(allocateCIDR, clusterCIDR, subnetMaskSize)
			cloud, err := util.NewMockGCECloud(bil.newMockCloud())
			if err != nil {
				t.Fatalf("Unable to create mock cloud: %v", err)
			}
			test.Cloud = cloud
			if results, err := runTest(t, apiURL, test, clusterCIDR, serviceCIDR, subnetMaskSize); err == nil {
				allResults = append(allResults, results)
			}
		})
	}

	logResults(allResults)
}
<commit_msg>Typo fix in returned message: formating->formatting<commit_after>/*
Copyright 2018 The Kubernetes Authors.

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

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

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

package ipamperf

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net"
	"os"
	"testing"
	"time"

	"github.com/golang/glog"

	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/client-go/informers"
	clientset "k8s.io/client-go/kubernetes"
	restclient "k8s.io/client-go/rest"
	"k8s.io/kubernetes/pkg/controller/nodeipam"
	"k8s.io/kubernetes/pkg/controller/nodeipam/ipam"
	"k8s.io/kubernetes/test/integration/util"
)

func setupAllocator(apiURL string, config *Config, clusterCIDR, serviceCIDR *net.IPNet, subnetMaskSize int) (*clientset.Clientset, util.ShutdownFunc, error) {
	controllerStopChan := make(chan struct{})
	shutdownFunc := func() {
		close(controllerStopChan)
	}

	clientSet := clientset.NewForConfigOrDie(&restclient.Config{
		Host:          apiURL,
		ContentConfig: restclient.ContentConfig{GroupVersion: &schema.GroupVersion{Group: "", Version: "v1"}},
		QPS:           float32(config.KubeQPS),
		Burst:         config.KubeQPS,
	})

	sharedInformer := informers.NewSharedInformerFactory(clientSet, 1*time.Hour)
	ipamController, err := nodeipam.NewNodeIpamController(
		sharedInformer.Core().V1().Nodes(), config.Cloud, clientSet,
		clusterCIDR, serviceCIDR, subnetMaskSize, config.AllocatorType,
	)
	if err != nil {
		return nil, shutdownFunc, err
	}
	go ipamController.Run(controllerStopChan)
	sharedInformer.Start(controllerStopChan)

	return clientSet, shutdownFunc, nil
}

func runTest(t *testing.T, apiURL string, config *Config, clusterCIDR, serviceCIDR *net.IPNet, subnetMaskSize int) (*Results, error) {
	t.Helper()
	glog.Infof("Running test %s", t.Name())

	defer deleteNodes(apiURL, config) // cleanup nodes on after controller shutdown

	clientSet, shutdownFunc, err := setupAllocator(apiURL, config, clusterCIDR, serviceCIDR, subnetMaskSize)
	if err != nil {
		t.Fatalf("Error starting IPAM allocator: %v", err)
	}
	defer shutdownFunc()

	o := NewObserver(clientSet, config.NumNodes)
	if err := o.StartObserving(); err != nil {
		t.Fatalf("Could not start test observer: %v", err)
	}

	if err := createNodes(apiURL, config); err != nil {
		t.Fatalf("Could not create nodes: %v", err)
	}

	results := o.Results(t.Name(), config)
	glog.Infof("Results: %s", results)
	if !results.Succeeded {
		t.Errorf("%s: Not allocations succeeded", t.Name())
	}
	return results, nil
}

func logResults(allResults []*Results) {
	jStr, err := json.MarshalIndent(allResults, "", "  ")
	if err != nil {
		glog.Errorf("Error formatting results: %v", err)
		return
	}
	if resultsLogFile != "" {
		glog.Infof("Logging results to %s", resultsLogFile)
		if err := ioutil.WriteFile(resultsLogFile, jStr, os.FileMode(0644)); err != nil {
			glog.Errorf("Error logging results to %s: %v", resultsLogFile, err)
		}
	}
	glog.Infof("AllResults:\n%s", string(jStr))
}

func TestPerformance(t *testing.T) {
	if testing.Short() {
		// TODO (#61854) find why flakiness is caused by etcd connectivity before enabling always
		t.Skip("Skipping because we want to run short tests")
	}

	apiURL, masterShutdown := util.StartApiserver()
	defer masterShutdown()

	_, clusterCIDR, _ := net.ParseCIDR("10.96.0.0/11") // allows up to 8K nodes
	_, serviceCIDR, _ := net.ParseCIDR("10.94.0.0/24") // does not matter for test - pick upto  250 services
	subnetMaskSize := 24

	var (
		allResults []*Results
		tests      []*Config
	)

	if isCustom {
		tests = append(tests, customConfig)
	} else {
		for _, numNodes := range []int{10, 100} {
			for _, alloc := range []ipam.CIDRAllocatorType{ipam.RangeAllocatorType, ipam.CloudAllocatorType, ipam.IPAMFromClusterAllocatorType, ipam.IPAMFromCloudAllocatorType} {
				tests = append(tests, &Config{AllocatorType: alloc, NumNodes: numNodes, CreateQPS: numNodes, KubeQPS: 10, CloudQPS: 10})
			}
		}
	}

	for _, test := range tests {
		testName := fmt.Sprintf("%s-KubeQPS%d-Nodes%d", test.AllocatorType, test.KubeQPS, test.NumNodes)
		t.Run(testName, func(t *testing.T) {
			allocateCIDR := false
			if test.AllocatorType == ipam.IPAMFromCloudAllocatorType || test.AllocatorType == ipam.CloudAllocatorType {
				allocateCIDR = true
			}
			bil := newBaseInstanceList(allocateCIDR, clusterCIDR, subnetMaskSize)
			cloud, err := util.NewMockGCECloud(bil.newMockCloud())
			if err != nil {
				t.Fatalf("Unable to create mock cloud: %v", err)
			}
			test.Cloud = cloud
			if results, err := runTest(t, apiURL, test, clusterCIDR, serviceCIDR, subnetMaskSize); err == nil {
				allResults = append(allResults, results)
			}
		})
	}

	logResults(allResults)
}
<|endoftext|>


<commit_before>// Copyright 2022 Gravitational, Inc
//
// 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 alpnproxy

import (
	"bytes"
	"context"
	"crypto/tls"
	"errors"
	"fmt"
	"io"
	"math"
	"net"
	"testing"
	"time"

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

func TestPingConnection(t *testing.T) {
	t.Run("BufferSize", func(t *testing.T) {
		nWrites := 10
		dataWritten := []byte("message")

		for _, tt := range []struct {
			desc    string
			bufSize int
		}{
			{desc: "Same", bufSize: len(dataWritten)},
			{desc: "Large", bufSize: len(dataWritten) * 2},
			{desc: "Short", bufSize: len(dataWritten) / 2},
		} {
			t.Run(tt.desc, func(t *testing.T) {
				r, w := makePingConn(t)

				// Write routine
				errChan := make(chan error, 2)
				go func() {
					defer w.Close()

					for i := 0; i < nWrites; i++ {
						// Eventually write some pings.
						if i%2 == 0 {
							err := w.WritePing()
							if err != nil {
								errChan <- err
								return
							}
						}

						_, err := w.Write(dataWritten)
						if err != nil {
							errChan <- err
							return
						}
					}

					errChan <- nil
				}()

				// Read routine.
				go func() {
					defer r.Close()

					buf := make([]byte, tt.bufSize)

					for i := 0; i < nWrites; i++ {
						var (
							aggregator []byte
							n          int
							err        error
						)

						for n < len(dataWritten) {
							n, err = r.Read(buf)
							if err != nil {
								errChan <- err
								return
							}

							aggregator = append(aggregator, buf[:n]...)
						}

						if !bytes.Equal(dataWritten, aggregator) {
							errChan <- fmt.Errorf("wrong content read, expected '%s', got '%s'", string(dataWritten), string(buf[:n]))
							return
						}
					}

					errChan <- nil
				}()

				// Expect routines to finish.
				timer := time.NewTimer(10 * time.Second)
				defer timer.Stop()
				for i := 0; i < 1; i++ {
					select {
					case err := <-errChan:
						require.NoError(t, err)
					case <-timer.C:
						require.Fail(t, "routing didn't finished in time")
					}
				}
			})
		}
	})

	t.Run("ConcurrentReads", func(t *testing.T) {
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()

		// Number of writes performed.
		nWrites := 10
		// Data that is going to be written/read on the connection.
		dataWritten := []byte("message")
		// Size of each read call.
		readSize := 2
		// Number of reads necessary to read the full message
		readNum := int(math.Ceil(float64(len(dataWritten)) / float64(readSize)))

		r, w := makePingConn(t)
		defer r.Close()
		defer w.Close()

		readChan := make(chan []byte)

		// Write routine
		go func() {
			for i := 0; i < nWrites; i++ {
				_, err := w.Write(dataWritten)
				if err != nil {
					return
				}
			}
		}()

		// Read routines.
		for i := 0; i < nWrites/2; i++ {
			go func() {
				buf := make([]byte, readSize)
				for {
					n, err := r.Read(buf)
					if err != nil && !errors.Is(err, io.EOF) {
						require.Fail(t, "Failed to read from connection: %v", err)
					}

					chanBytes := make([]byte, n)
					copy(chanBytes, buf[:n])
					readChan <- chanBytes
				}
			}()
		}

		for i := 0; i < nWrites; i++ {
			var aggregator []byte
			for j := 0; j < readNum; j++ {
				select {
				case <-ctx.Done():
					require.Fail(t, "Failed to read message (context timeout)")
				case data := <-readChan:
					aggregator = append(aggregator, data...)
				}
			}

			require.Len(t, aggregator, len(dataWritten), "Wrong message read from connection")
		}
	})

	t.Run("ConcurrentWrites", func(t *testing.T) {
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()

		w, r := makeBufferedPingConn(t)
		defer w.Close()
		defer r.Close()

		nWrites := 10
		dataWritten := []byte("message")
		writeChan := make(chan error)

		// Start write routines.
		for i := 0; i < nWrites/2; i++ {
			go func() {
				for writes := 0; writes < 2; writes++ {
					err := w.WritePing()
					if err != nil {
						writeChan <- err
						return
					}

					_, err = w.Write(dataWritten)
					if err != nil {
						writeChan <- err
						return
					}
				}

				writeChan <- nil
			}()
		}

		// Expect all writes to succeed.
		for i := 0; i < nWrites/2; i++ {
			select {
			case <-ctx.Done():
				require.Fail(t, "timout write")
			case err := <-writeChan:
				require.NoError(t, err)
			}
		}

		// Read all messages.
		buf := make([]byte, len(dataWritten))
		for i := 0; i < nWrites; i++ {
			n, err := r.Read(buf)
			require.NoError(t, err)
			require.Equal(t, dataWritten, buf[:n])
		}
	})
}

// makePingConn creates a piped ping connection.
func makePingConn(t *testing.T) (*PingConn, *PingConn) {
	t.Helper()

	writer, reader := net.Pipe()
	tlsWriter, tlsReader := makeTLSConn(t, writer, reader)

	return NewPingConn(tlsWriter), NewPingConn(tlsReader)
}

// makeBufferedPingConn creates connections to have asynchronous writes.
func makeBufferedPingConn(t *testing.T) (*PingConn, *PingConn) {
	t.Helper()

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	l, err := net.Listen("tcp", "localhost:0")
	require.NoError(t, err)

	connChan := make(chan struct {
		net.Conn
		error
	}, 2)

	// Accept
	go func() {
		conn, err := l.Accept()
		connChan <- struct {
			net.Conn
			error
		}{conn, err}
	}()

	// Dial
	go func() {
		conn, err := net.Dial("tcp", l.Addr().String())
		connChan <- struct {
			net.Conn
			error
		}{conn, err}
	}()

	connSlice := make([]net.Conn, 2)
	for i := 0; i < 2; i++ {
		select {
		case <-ctx.Done():
			require.Fail(t, "failed waiting for connections")
		case res := <-connChan:
			require.NoError(t, res.error)
			connSlice[i] = res.Conn
		}
	}

	tlsConnA, tlsConnB := makeTLSConn(t, connSlice[0], connSlice[1])
	return NewPingConn(tlsConnA), NewPingConn(tlsConnB)
}

// makeTLSConn take two connections (client and server) and wrap them into TLS
// connections.
func makeTLSConn(t *testing.T, server, client net.Conn) (*tls.Conn, *tls.Conn) {
	tlsConnChan := make(chan struct {
		*tls.Conn
		error
	}, 2)
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	// Server
	go func() {
		tlsConn := tls.Server(server, &tls.Config{
			Certificates: []tls.Certificate{mustGenCertSignedWithCA(t, mustGenSelfSignedCert(t))},
		})
		tlsConnChan <- struct {
			*tls.Conn
			error
		}{tlsConn, tlsConn.Handshake()}
	}()

	// Client
	go func() {
		tlsConn := tls.Client(client, &tls.Config{InsecureSkipVerify: true})
		tlsConnChan <- struct {
			*tls.Conn
			error
		}{tlsConn, tlsConn.Handshake()}
	}()

	tlsConnSlice := make([]*tls.Conn, 2)
	for i := 0; i < 2; i++ {
		select {
		case <-ctx.Done():
			server.Close()
			client.Close()

			require.Fail(t, "failed waiting for TLS connections", "%d connections remaining", 2-i)
		case res := <-tlsConnChan:
			require.NoError(t, res.error)
			tlsConnSlice[i] = res.Conn
		}
	}

	return tlsConnSlice[0], tlsConnSlice[1]
}
<commit_msg>Change `TestPingConnection/ConcurrentReads` assertion. (#15969)<commit_after>// Copyright 2022 Gravitational, Inc
//
// 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 alpnproxy

import (
	"bytes"
	"context"
	"crypto/tls"
	"errors"
	"fmt"
	"io"
	"math"
	"net"
	"testing"
	"time"

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

func TestPingConnection(t *testing.T) {
	t.Run("BufferSize", func(t *testing.T) {
		nWrites := 10
		dataWritten := []byte("message")

		for _, tt := range []struct {
			desc    string
			bufSize int
		}{
			{desc: "Same", bufSize: len(dataWritten)},
			{desc: "Large", bufSize: len(dataWritten) * 2},
			{desc: "Short", bufSize: len(dataWritten) / 2},
		} {
			t.Run(tt.desc, func(t *testing.T) {
				r, w := makePingConn(t)

				// Write routine
				errChan := make(chan error, 2)
				go func() {
					defer w.Close()

					for i := 0; i < nWrites; i++ {
						// Eventually write some pings.
						if i%2 == 0 {
							err := w.WritePing()
							if err != nil {
								errChan <- err
								return
							}
						}

						_, err := w.Write(dataWritten)
						if err != nil {
							errChan <- err
							return
						}
					}

					errChan <- nil
				}()

				// Read routine.
				go func() {
					defer r.Close()

					buf := make([]byte, tt.bufSize)

					for i := 0; i < nWrites; i++ {
						var (
							aggregator []byte
							n          int
							err        error
						)

						for n < len(dataWritten) {
							n, err = r.Read(buf)
							if err != nil {
								errChan <- err
								return
							}

							aggregator = append(aggregator, buf[:n]...)
						}

						if !bytes.Equal(dataWritten, aggregator) {
							errChan <- fmt.Errorf("wrong content read, expected '%s', got '%s'", string(dataWritten), string(buf[:n]))
							return
						}
					}

					errChan <- nil
				}()

				// Expect routines to finish.
				timer := time.NewTimer(10 * time.Second)
				defer timer.Stop()
				for i := 0; i < 1; i++ {
					select {
					case err := <-errChan:
						require.NoError(t, err)
					case <-timer.C:
						require.Fail(t, "routing didn't finished in time")
					}
				}
			})
		}
	})

	// Given a connection, read from it concurrently, asserting all content
	// written is read.
	//
	// Messages can be out of order due to concurrent reads. Other tests must
	// guarantee message ordering.
	t.Run("ConcurrentReads", func(t *testing.T) {
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()

		// Number of writes performed.
		nWrites := 10
		// Data that is going to be written/read on the connection.
		dataWritten := []byte("message")
		// Size of each read call.
		readSize := 2
		// Number of reads necessary to read the full message
		readNum := int(math.Ceil(float64(len(dataWritten)) / float64(readSize)))

		r, w := makePingConn(t)
		defer r.Close()
		defer w.Close()

		readChan := make(chan []byte)

		// Write routine
		go func() {
			for i := 0; i < nWrites; i++ {
				_, err := w.Write(dataWritten)
				if err != nil {
					return
				}
			}
		}()

		// Read routines.
		for i := 0; i < nWrites/2; i++ {
			go func() {
				buf := make([]byte, readSize)
				for {
					n, err := r.Read(buf)
					if err != nil && !errors.Is(err, io.EOF) {
						require.Fail(t, "Failed to read from connection: %v", err)
					}

					chanBytes := make([]byte, n)
					copy(chanBytes, buf[:n])
					readChan <- chanBytes
				}
			}()
		}

		var aggregator []byte
		for i := 0; i < nWrites; i++ {
			for j := 0; j < readNum; j++ {
				select {
				case <-ctx.Done():
					require.Fail(t, "Failed to read message (context timeout)")
				case data := <-readChan:
					aggregator = append(aggregator, data...)
				}
			}
		}

		require.Len(t, aggregator, len(dataWritten)*nWrites, "Wrong messages written")
	})

	t.Run("ConcurrentWrites", func(t *testing.T) {
		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
		defer cancel()

		w, r := makeBufferedPingConn(t)
		defer w.Close()
		defer r.Close()

		nWrites := 10
		dataWritten := []byte("message")
		writeChan := make(chan error)

		// Start write routines.
		for i := 0; i < nWrites/2; i++ {
			go func() {
				for writes := 0; writes < 2; writes++ {
					err := w.WritePing()
					if err != nil {
						writeChan <- err
						return
					}

					_, err = w.Write(dataWritten)
					if err != nil {
						writeChan <- err
						return
					}
				}

				writeChan <- nil
			}()
		}

		// Expect all writes to succeed.
		for i := 0; i < nWrites/2; i++ {
			select {
			case <-ctx.Done():
				require.Fail(t, "timout write")
			case err := <-writeChan:
				require.NoError(t, err)
			}
		}

		// Read all messages.
		buf := make([]byte, len(dataWritten))
		for i := 0; i < nWrites; i++ {
			n, err := r.Read(buf)
			require.NoError(t, err)
			require.Equal(t, dataWritten, buf[:n])
		}
	})
}

// makePingConn creates a piped ping connection.
func makePingConn(t *testing.T) (*PingConn, *PingConn) {
	t.Helper()

	writer, reader := net.Pipe()
	tlsWriter, tlsReader := makeTLSConn(t, writer, reader)

	return NewPingConn(tlsWriter), NewPingConn(tlsReader)
}

// makeBufferedPingConn creates connections to have asynchronous writes.
func makeBufferedPingConn(t *testing.T) (*PingConn, *PingConn) {
	t.Helper()

	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	l, err := net.Listen("tcp", "localhost:0")
	require.NoError(t, err)

	connChan := make(chan struct {
		net.Conn
		error
	}, 2)

	// Accept
	go func() {
		conn, err := l.Accept()
		connChan <- struct {
			net.Conn
			error
		}{conn, err}
	}()

	// Dial
	go func() {
		conn, err := net.Dial("tcp", l.Addr().String())
		connChan <- struct {
			net.Conn
			error
		}{conn, err}
	}()

	connSlice := make([]net.Conn, 2)
	for i := 0; i < 2; i++ {
		select {
		case <-ctx.Done():
			require.Fail(t, "failed waiting for connections")
		case res := <-connChan:
			require.NoError(t, res.error)
			connSlice[i] = res.Conn
		}
	}

	tlsConnA, tlsConnB := makeTLSConn(t, connSlice[0], connSlice[1])
	return NewPingConn(tlsConnA), NewPingConn(tlsConnB)
}

// makeTLSConn take two connections (client and server) and wrap them into TLS
// connections.
func makeTLSConn(t *testing.T, server, client net.Conn) (*tls.Conn, *tls.Conn) {
	tlsConnChan := make(chan struct {
		*tls.Conn
		error
	}, 2)
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()

	// Server
	go func() {
		tlsConn := tls.Server(server, &tls.Config{
			Certificates: []tls.Certificate{mustGenCertSignedWithCA(t, mustGenSelfSignedCert(t))},
		})
		tlsConnChan <- struct {
			*tls.Conn
			error
		}{tlsConn, tlsConn.Handshake()}
	}()

	// Client
	go func() {
		tlsConn := tls.Client(client, &tls.Config{InsecureSkipVerify: true})
		tlsConnChan <- struct {
			*tls.Conn
			error
		}{tlsConn, tlsConn.Handshake()}
	}()

	tlsConnSlice := make([]*tls.Conn, 2)
	for i := 0; i < 2; i++ {
		select {
		case <-ctx.Done():
			server.Close()
			client.Close()

			require.Fail(t, "failed waiting for TLS connections", "%d connections remaining", 2-i)
		case res := <-tlsConnChan:
			require.NoError(t, res.error)
			tlsConnSlice[i] = res.Conn
		}
	}

	return tlsConnSlice[0], tlsConnSlice[1]
}
<|endoftext|>


<commit_before>package acmeagent_test

import (
	"os"
	"path/filepath"
	"testing"

	"github.com/lestrrat/go-cloud-acmeagent"
	"github.com/lestrrat/go-cloud-acmeagent/gcp"
	"github.com/lestrrat/go-cloud-acmeagent/localfs"
	"github.com/stretchr/testify/assert"
	"golang.org/x/net/context"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/dns/v1"
)

func TestAuthorizeGCP(t *testing.T) {
	email := os.Getenv("ACME_AGENT_TEST_EMAIL")
	if email == "" {
		t.Logf("ACME_AGENT_TEST_EMAIL environment variable is required for this test")
		return
	}
	domain := os.Getenv("ACME_AGENT_TEST_DOMAIN")
	if domain == "" {
		t.Logf("ACME_AGENT_TEST_DOMAIN environment variable is required for this test")
		return
	}
	gcpproj := os.Getenv("ACME_AGENT_TEST_GCP_PROJECT_ID")
	if gcpproj == "" {
		t.Logf("ACME_AGENT_TEST_GCP_PROJECT_ID environment variable is required for this test")
		return
	}
	gcpzone := os.Getenv("ACME_AGENT_TEST_GCP_ZONE_NAME")
	if gcpzone == "" {
		t.Logf("ACME_AGENT_TEST_GCP_ZONE_NAME environment variable is required for this test")
		return
	}

	cn := os.Getenv("ACME_AGENT_TEST_COMMON_NAME")
	if cn == "" {
		t.Logf("ACME_AGENT_TEST_COMMON_NAME environment variable is required for this test")
		return
	}

	wd, err := os.Getwd()
	if !assert.NoError(t, err, "Getting working directory should succeed") {
		return
	}

	store, err := localfs.New(localfs.StorageOptions{
		Root: filepath.Join(wd, "acme"),
		ID:   email,
	})
	if !assert.NoError(t, err, "Creating localfs state storage should succeed") {
		return
	}

	var authz acmeagent.Authorization
	if err := store.LoadAuthorization(domain, &authz); err == nil && !authz.IsExpired() {
		return // no auth necessary
	}

	// Get your challange fulfilling strategy ready. Here we're
	// getting an object that can create appropriate DNS entries
	// using Google CloudDNS to respond to dns-01 challenge
	ctx := context.Background()
	httpcl, err := google.DefaultClient(
		ctx,
		dns.NdevClouddnsReadwriteScope, // We need to be able to update CloudDNS
	)
	if !assert.NoError(t, err, "creating new Google oauth'ed client should succeed") {
		panic(err)
	}

	dnssvc, err := dns.New(httpcl)
	if !assert.NoError(t, err, "creating new DNS service should succeed") {
		return
	}

	// Tell the agent which challenges we can accept
	aa, err := acmeagent.New(acmeagent.AgentOptions{
		DNSCompleter: gcp.NewDNS(dnssvc, gcpproj, gcpzone),
		StateStorage: store,
	})

	var acct acmeagent.Account
	if err := store.LoadAccount(&acct); err != nil {
		if !assert.NoError(t, aa.Register(email), "Register should succeed") {
			return
		}
	}

	// With us so far? now fire the request, and let the authorization happen
	if !assert.NoError(t, aa.AuthorizeForDomain(cn + "." + domain), "authorize should succeed") {
		return
	}

	if !assert.NoError(t, aa.IssueCertificate(cn, domain, false), "IssueCertificate should succeed") {
		return
	}
}<commit_msg>more tweaks<commit_after>package acmeagent_test

import (
	"os"
	"path/filepath"
	"testing"

	"github.com/lestrrat/go-cloud-acmeagent"
	"github.com/lestrrat/go-cloud-acmeagent/gcp"
	"github.com/lestrrat/go-cloud-acmeagent/localfs"
	"github.com/stretchr/testify/assert"
	"golang.org/x/net/context"
	"golang.org/x/oauth2/google"
	"google.golang.org/api/dns/v1"
)

func TestAuthorizeGCP(t *testing.T) {
	email := os.Getenv("ACME_AGENT_TEST_EMAIL")
	if email == "" {
		t.Logf("ACME_AGENT_TEST_EMAIL environment variable is required for this test")
		return
	}
	domain := os.Getenv("ACME_AGENT_TEST_DOMAIN")
	if domain == "" {
		t.Logf("ACME_AGENT_TEST_DOMAIN environment variable is required for this test")
		return
	}
	gcpproj := os.Getenv("ACME_AGENT_TEST_GCP_PROJECT_ID")
	if gcpproj == "" {
		t.Logf("ACME_AGENT_TEST_GCP_PROJECT_ID environment variable is required for this test")
		return
	}
	gcpzone := os.Getenv("ACME_AGENT_TEST_GCP_ZONE_NAME")
	if gcpzone == "" {
		t.Logf("ACME_AGENT_TEST_GCP_ZONE_NAME environment variable is required for this test")
		return
	}

	cn := os.Getenv("ACME_AGENT_TEST_COMMON_NAME")
	if cn == "" {
		t.Logf("ACME_AGENT_TEST_COMMON_NAME environment variable is required for this test")
		return
	}

	wd, err := os.Getwd()
	if !assert.NoError(t, err, "Getting working directory should succeed") {
		return
	}

	store, err := localfs.New(localfs.StorageOptions{
		Root: filepath.Join(wd, "acme"),
		ID:   email,
	})
	if !assert.NoError(t, err, "Creating localfs state storage should succeed") {
		return
	}

	fqdn := cn + "." + domain

	var authz acmeagent.Authorization
	if err := store.LoadAuthorization(fqdn, &authz); err == nil && !authz.IsExpired() {
		return // no auth necessary
	}

	// Get your challange fulfilling strategy ready. Here we're
	// getting an object that can create appropriate DNS entries
	// using Google CloudDNS to respond to dns-01 challenge
	ctx := context.Background()
	httpcl, err := google.DefaultClient(
		ctx,
		dns.NdevClouddnsReadwriteScope, // We need to be able to update CloudDNS
	)
	if !assert.NoError(t, err, "creating new Google oauth'ed client should succeed") {
		panic(err)
	}

	dnssvc, err := dns.New(httpcl)
	if !assert.NoError(t, err, "creating new DNS service should succeed") {
		return
	}

	// Tell the agent which challenges we can accept
	aa, err := acmeagent.New(acmeagent.AgentOptions{
		DNSCompleter: gcp.NewDNS(dnssvc, gcpproj, gcpzone),
		StateStorage: store,
	})

	var acct acmeagent.Account
	if err := store.LoadAccount(&acct); err != nil {
		if !assert.NoError(t, aa.Register(email), "Register should succeed") {
			return
		}
	}

	// With us so far? now fire the request, and let the authorization happen
	if !assert.NoError(t, aa.AuthorizeForDomain(fqdn), "authorize should succeed") {
		return
	}

	if !assert.NoError(t, aa.IssueCertificate(cn, domain, false), "IssueCertificate should succeed") {
		return
	}
}<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)

package main

import (
	"fmt"
	"log"
	"os"
	"path"
	"sync"

	"github.com/jacobsa/gcloud/gcs"
	"golang.org/x/net/context"
	"google.golang.org/cloud/storage"

	"bazil.org/fuse"
	"bazil.org/fuse/fs"
)

const dirSeparator = '/'

// A "directory" in GCS, defined by an object name prefix. All prefixes end
// with dirSeparator except for the special case of the root directory, where
// the prefix is the empty string.
type dir struct {
	bucket       gcs.Bucket
	objectPrefix string

	mu sync.RWMutex

	// A map from (relative) names of children to nodes for those children,
	// initialized from GCS the first time it is needed for a ReadDir, Lookup,
	// etc. All nodes within the map are of type *dir or *file.
	children map[string]fs.Node // GUARDED_BY(mu)
}

// Initialize d.children from GCS if it has not already been populated.
func (d *dir) initChildren(ctx context.Context) error {
	d.mu.Lock()
	defer d.mu.Unlock()

	// Have we already initialized the map?
	if d.children != nil {
		return nil
	}

	children := make(map[string]fs.Node)

	// List repeatedly until there is no more to list.
	query := &storage.Query{
		Delimiter: string(dirSeparator),
		Prefix:    d.objectPrefix,
	}

	for query != nil {
		// Grab one set of results.
		objects, err := d.bucket.ListObjects(ctx, query)
		if err != nil {
			return fmt.Errorf("bucket.ListObjects: %v", err)
		}

		// Extract objects as files.
		for _, o := range objects.Results {
			// Special case: the GCS storage browser's "New folder" button causes an
			// object with a trailing slash to be created. For example, if you make a
			// folder called "bar" within a folder called "foo", that creates an
			// object called "foo/bar/". (It seems like the redundant ones may be
			// removed eventually, but that's not relevant.)
			//
			// When we list the directory "foo/", we don't want to return the object
			// named "foo/" as if it were a file within the directory. So skip it.
			if o.Name == d.objectPrefix {
				continue
			}

			children[path.Base(o.Name)] = &file{
				bucket:     d.bucket,
				objectName: o.Name,
				size:       uint64(o.Size),
			}
		}

		// Extract prefixes as directories.
		for _, p := range objects.Prefixes {
			children[path.Base(p)] = &dir{
				bucket:       d.bucket,
				objectPrefix: p,
			}
		}

		// Move on to the next set of results.
		query = objects.Next
	}

	// Save the map.
	d.children = children

	return nil
}

func (d *dir) Attr() fuse.Attr {
	return fuse.Attr{
		// TODO(jacobsa): Expose ACLs from GCS?
		Mode: os.ModeDir | 0500,
	}
}

func (d *dir) ReadDir(ctx context.Context) (
	ents []fuse.Dirent, err error) {
	log.Printf("ReadDir: [%s]/%s", d.bucket.Name(), d.objectPrefix)

	// Ensure that our cache of children has been initialized.
	if err := d.initChildren(ctx); err != nil {
		return nil, fmt.Errorf("d.initChildren: %v", err)
	}

	// Read out the contents of the cache.
	d.mu.RLock()
	defer d.mu.RUnlock()

	for name, node := range d.children {
		ent := fuse.Dirent{
			Name: name,
		}

		if _, ok := node.(*dir); ok {
			ent.Type = fuse.DT_Dir
		} else {
			ent.Type = fuse.DT_File
		}

		ents = append(ents, ent)
	}

	return
}

func (d *dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
	log.Printf("Lookup: ([%s]/%s) %s", d.bucket.Name(), d.objectPrefix, name)

	// Ensure that our cache of children has been initialized.
	if err := d.initChildren(ctx); err != nil {
		return nil, fmt.Errorf("d.initChildren: %v", err)
	}

	// Find the object within the map.
	if n, ok := d.children[name]; ok {
		return n, nil
	}

	return nil, fuse.ENOENT
}
<commit_msg>Fixed a ReadDir -> ReadDirAll regression.<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
// Author: jacobsa@google.com (Aaron Jacobs)

package main

import (
	"fmt"
	"log"
	"os"
	"path"
	"sync"

	"github.com/jacobsa/gcloud/gcs"
	"golang.org/x/net/context"
	"google.golang.org/cloud/storage"

	"bazil.org/fuse"
	"bazil.org/fuse/fs"
)

const dirSeparator = '/'

// A "directory" in GCS, defined by an object name prefix. All prefixes end
// with dirSeparator except for the special case of the root directory, where
// the prefix is the empty string.
type dir struct {
	bucket       gcs.Bucket
	objectPrefix string

	mu sync.RWMutex

	// A map from (relative) names of children to nodes for those children,
	// initialized from GCS the first time it is needed for a ReadDirAll, Lookup,
	// etc. All nodes within the map are of type *dir or *file.
	children map[string]fs.Node // GUARDED_BY(mu)
}

// Make sure dir implements the interfaces we thing it does.
var (
	_ fs.Node               = &dir{}
	_ fs.NodeStringLookuper = &dir{}

	_ fs.Handle             = &dir{}
	_ fs.HandleReadDirAller = &dir{}
)

// Initialize d.children from GCS if it has not already been populated.
func (d *dir) initChildren(ctx context.Context) error {
	d.mu.Lock()
	defer d.mu.Unlock()

	// Have we already initialized the map?
	if d.children != nil {
		return nil
	}

	children := make(map[string]fs.Node)

	// List repeatedly until there is no more to list.
	query := &storage.Query{
		Delimiter: string(dirSeparator),
		Prefix:    d.objectPrefix,
	}

	for query != nil {
		// Grab one set of results.
		objects, err := d.bucket.ListObjects(ctx, query)
		if err != nil {
			return fmt.Errorf("bucket.ListObjects: %v", err)
		}

		// Extract objects as files.
		for _, o := range objects.Results {
			// Special case: the GCS storage browser's "New folder" button causes an
			// object with a trailing slash to be created. For example, if you make a
			// folder called "bar" within a folder called "foo", that creates an
			// object called "foo/bar/". (It seems like the redundant ones may be
			// removed eventually, but that's not relevant.)
			//
			// When we list the directory "foo/", we don't want to return the object
			// named "foo/" as if it were a file within the directory. So skip it.
			if o.Name == d.objectPrefix {
				continue
			}

			children[path.Base(o.Name)] = &file{
				bucket:     d.bucket,
				objectName: o.Name,
				size:       uint64(o.Size),
			}
		}

		// Extract prefixes as directories.
		for _, p := range objects.Prefixes {
			children[path.Base(p)] = &dir{
				bucket:       d.bucket,
				objectPrefix: p,
			}
		}

		// Move on to the next set of results.
		query = objects.Next
	}

	// Save the map.
	d.children = children

	return nil
}

func (d *dir) Attr() fuse.Attr {
	return fuse.Attr{
		// TODO(jacobsa): Expose ACLs from GCS?
		Mode: os.ModeDir | 0500,
	}
}

func (d *dir) ReadDirAll(ctx context.Context) (
	ents []fuse.Dirent, err error) {
	log.Printf("ReadDirAll: [%s]/%s", d.bucket.Name(), d.objectPrefix)

	// Ensure that our cache of children has been initialized.
	if err := d.initChildren(ctx); err != nil {
		return nil, fmt.Errorf("d.initChildren: %v", err)
	}

	// Read out the contents of the cache.
	d.mu.RLock()
	defer d.mu.RUnlock()

	for name, node := range d.children {
		ent := fuse.Dirent{
			Name: name,
		}

		if _, ok := node.(*dir); ok {
			ent.Type = fuse.DT_Dir
		} else {
			ent.Type = fuse.DT_File
		}

		ents = append(ents, ent)
	}

	return
}

func (d *dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
	log.Printf("Lookup: ([%s]/%s) %s", d.bucket.Name(), d.objectPrefix, name)

	// Ensure that our cache of children has been initialized.
	if err := d.initChildren(ctx); err != nil {
		return nil, fmt.Errorf("d.initChildren: %v", err)
	}

	// Find the object within the map.
	if n, ok := d.children[name]; ok {
		return n, nil
	}

	return nil, fuse.ENOENT
}
<|endoftext|>


<commit_before>// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package filetesting

import (
	"io/ioutil"
	"os"
	"path/filepath"

	jc "github.com/juju/testing/checkers"
	gc "launchpad.net/gocheck"
)

type fileSuite struct{}

var _ = gc.Suite(&fileSuite{})

func (*fileSuite) TestIsNotExist(c *gc.C) {
	dir := c.MkDir()
	path := func(s string) string { return filepath.Join(dir, s) }
	err := ioutil.WriteFile(path("file"), []byte("blah"), 0644)
	c.Assert(err, gc.IsNil)

	_, err = os.Lstat(path("noexist"))
	c.Assert(err, jc.Satisfies, isNotExist)

	_, err = os.Lstat(path("file/parent-not-a-dir"))
	c.Assert(err, jc.Satisfies, isNotExist)
}
<commit_msg>Rename the test suite.<commit_after>// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package filetesting

import (
	"io/ioutil"
	"os"
	"path/filepath"

	jc "github.com/juju/testing/checkers"
	gc "launchpad.net/gocheck"
)

type isNotExistSuite struct{}

var _ = gc.Suite(&isNotExistSuite{})

func (*isNotExistSuite) TestIsNotExist(c *gc.C) {
	dir := c.MkDir()
	path := func(s string) string { return filepath.Join(dir, s) }
	err := ioutil.WriteFile(path("file"), []byte("blah"), 0644)
	c.Assert(err, gc.IsNil)

	_, err = os.Lstat(path("noexist"))
	c.Assert(err, jc.Satisfies, isNotExist)

	_, err = os.Lstat(path("file/parent-not-a-dir"))
	c.Assert(err, jc.Satisfies, isNotExist)
}
<|endoftext|>


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

// The oauth package provides support for making
// OAuth2-authenticated HTTP requests.
package oauth

// TODO(adg): A means of automatically saving credentials when updated.

import (
	"http"
	"json"
	"os"
	"time"
)

// Config is the configuration of an OAuth consumer.
type Config struct {
	ClientId     string
	ClientSecret string
	Scope        string
	AuthURL      string
	TokenURL     string
	RedirectURL  string // Defaults to out-of-band mode if empty.
}

func (c *Config) redirectURL() string {
	if c.RedirectURL != "" {
		return c.RedirectURL
	}
	return "oob"
}

// Token contains an end-user's tokens.
// This is the data you must store to persist authentication.
type Token struct {
	AccessToken  string "access_token"
	RefreshToken string "refresh_token"
	TokenExpiry  int64  "expires_in"
}

// Transport implements http.RoundTripper. When configured with a valid
// Config and Token it can be used to make authenticated HTTP requests.
//
//	t := &oauth.Transport{config}
//      t.Exchange(code)
//      // t now contains a valid Token
//	r, _, err := t.Client().Get("http://example.org/url/requiring/auth")
//
// It will automatically refresh the Token if it can,
// updating the supplied Token in place.
type Transport struct {
	*Config
	*Token

	// Transport is the HTTP transport to use when making requests.
	// It will default to http.DefaultTransport if nil.
	// (It should never be an oauth.Transport.)
	Transport http.RoundTripper
}

// Client returns an *http.Client that makes OAuth-authenticated requests.
func (t *Transport) Client() *http.Client {
	return &http.Client{t}
}

func (t *Transport) transport() http.RoundTripper {
	if t.Transport != nil {
		return t.Transport
	}
	return http.DefaultTransport
}

// AuthCodeURL returns a URL that the end-user should be redirected to,
// so that they may obtain an authorization code.
func (c *Config) AuthCodeURL(state string) string {
	url, err := http.ParseURL(c.AuthURL)
	if err != nil {
		panic("AuthURL malformed: " + err.String())
	}
	q := http.EncodeQuery(map[string][]string{
		"response_type": {"code"},
		"client_id":     {c.ClientId},
		"redirect_uri":  {c.redirectURL()},
		"scope":         {c.Scope},
		"state":         {state},
	})
	if url.RawQuery == "" {
		url.RawQuery = q
	} else {
		url.RawQuery += "&" + q
	}
	return url.String()
}

// Exchange takes a code and gets access Token from the remote server.
func (t *Transport) Exchange(code string) (tok *Token, err os.Error) {
	tok = new(Token)
	err = t.updateToken(tok, map[string]string{
		"grant_type":    "authorization_code",
		"client_id":     t.ClientId,
		"client_secret": t.ClientSecret,
		"redirect_uri":  t.redirectURL(),
		"scope":         t.Scope,
		"code":          code,
	})
	if err == nil {
		t.Token = tok
	}
	return
}

// RoundTrip executes a single HTTP transaction using the Transport's
// Token as authorization headers.
func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err os.Error) {
	if t.Config == nil {
		return nil, os.NewError("no Config supplied")
	}
	if t.Token == nil {
		return nil, os.NewError("no Token supplied")
	}

	// Make the HTTP request
	req.Header.Set("Authorization", "OAuth "+t.AccessToken)
	if resp, err = t.transport().RoundTrip(req); err != nil {
		return
	}

	// Refresh credentials if they're stale and try again
	if resp.StatusCode == 401 {
		if err = t.refresh(); err != nil {
			return
		}
		resp, err = t.transport().RoundTrip(req)
	}

	return
}

func (t *Transport) refresh() os.Error {
	return t.updateToken(t.Token, map[string]string{
		"grant_type":    "refresh_token",
		"client_id":     t.ClientId,
		"client_secret": t.ClientSecret,
		"refresh_token": t.RefreshToken,
	})
}

func (t *Transport) updateToken(tok *Token, form map[string]string) os.Error {
	r, err := (&http.Client{t.transport()}).PostForm(t.TokenURL, form)
	if err != nil {
		return err
	}
	defer r.Body.Close()
	if r.StatusCode != 200 {
		return os.NewError("invalid response: " + r.Status)
	}
	if err = json.NewDecoder(r.Body).Decode(tok); err != nil {
		return err
	}
	if tok.TokenExpiry != 0 {
		tok.TokenExpiry = time.Seconds() + tok.TokenExpiry
	}
	return nil
}
<commit_msg>check for config in Exchange<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// The oauth package provides support for making
// OAuth2-authenticated HTTP requests.
package oauth

// TODO(adg): A means of automatically saving credentials when updated.

import (
	"http"
	"json"
	"os"
	"time"
)

// Config is the configuration of an OAuth consumer.
type Config struct {
	ClientId     string
	ClientSecret string
	Scope        string
	AuthURL      string
	TokenURL     string
	RedirectURL  string // Defaults to out-of-band mode if empty.
}

func (c *Config) redirectURL() string {
	if c.RedirectURL != "" {
		return c.RedirectURL
	}
	return "oob"
}

// Token contains an end-user's tokens.
// This is the data you must store to persist authentication.
type Token struct {
	AccessToken  string "access_token"
	RefreshToken string "refresh_token"
	TokenExpiry  int64  "expires_in"
}

// Transport implements http.RoundTripper. When configured with a valid
// Config and Token it can be used to make authenticated HTTP requests.
//
//	t := &oauth.Transport{config}
//      t.Exchange(code)
//      // t now contains a valid Token
//	r, _, err := t.Client().Get("http://example.org/url/requiring/auth")
//
// It will automatically refresh the Token if it can,
// updating the supplied Token in place.
type Transport struct {
	*Config
	*Token

	// Transport is the HTTP transport to use when making requests.
	// It will default to http.DefaultTransport if nil.
	// (It should never be an oauth.Transport.)
	Transport http.RoundTripper
}

// Client returns an *http.Client that makes OAuth-authenticated requests.
func (t *Transport) Client() *http.Client {
	return &http.Client{t}
}

func (t *Transport) transport() http.RoundTripper {
	if t.Transport != nil {
		return t.Transport
	}
	return http.DefaultTransport
}

// AuthCodeURL returns a URL that the end-user should be redirected to,
// so that they may obtain an authorization code.
func (c *Config) AuthCodeURL(state string) string {
	url, err := http.ParseURL(c.AuthURL)
	if err != nil {
		panic("AuthURL malformed: " + err.String())
	}
	q := http.EncodeQuery(map[string][]string{
		"response_type": {"code"},
		"client_id":     {c.ClientId},
		"redirect_uri":  {c.redirectURL()},
		"scope":         {c.Scope},
		"state":         {state},
	})
	if url.RawQuery == "" {
		url.RawQuery = q
	} else {
		url.RawQuery += "&" + q
	}
	return url.String()
}

// Exchange takes a code and gets access Token from the remote server.
func (t *Transport) Exchange(code string) (tok *Token, err os.Error) {
	if t.Config == nil {
		return nil, os.NewError("no Config supplied")
	}
	tok = new(Token)
	err = t.updateToken(tok, map[string]string{
		"grant_type":    "authorization_code",
		"client_id":     t.ClientId,
		"client_secret": t.ClientSecret,
		"redirect_uri":  t.redirectURL(),
		"scope":         t.Scope,
		"code":          code,
	})
	if err == nil {
		t.Token = tok
	}
	return
}

// RoundTrip executes a single HTTP transaction using the Transport's
// Token as authorization headers.
func (t *Transport) RoundTrip(req *http.Request) (resp *http.Response, err os.Error) {
	if t.Config == nil {
		return nil, os.NewError("no Config supplied")
	}
	if t.Token == nil {
		return nil, os.NewError("no Token supplied")
	}

	// Make the HTTP request
	req.Header.Set("Authorization", "OAuth "+t.AccessToken)
	if resp, err = t.transport().RoundTrip(req); err != nil {
		return
	}

	// Refresh credentials if they're stale and try again
	if resp.StatusCode == 401 {
		if err = t.refresh(); err != nil {
			return
		}
		resp, err = t.transport().RoundTrip(req)
	}

	return
}

func (t *Transport) refresh() os.Error {
	return t.updateToken(t.Token, map[string]string{
		"grant_type":    "refresh_token",
		"client_id":     t.ClientId,
		"client_secret": t.ClientSecret,
		"refresh_token": t.RefreshToken,
	})
}

func (t *Transport) updateToken(tok *Token, form map[string]string) os.Error {
	r, err := (&http.Client{t.transport()}).PostForm(t.TokenURL, form)
	if err != nil {
		return err
	}
	defer r.Body.Close()
	if r.StatusCode != 200 {
		return os.NewError("invalid response: " + r.Status)
	}
	if err = json.NewDecoder(r.Body).Decode(tok); err != nil {
		return err
	}
	if tok.TokenExpiry != 0 {
		tok.TokenExpiry = time.Seconds() + tok.TokenExpiry
	}
	return nil
}
<|endoftext|>


<commit_before>package model

const (
	EventPush   = "push"
	EventPull   = "pull_request"
	EventTag    = "tag"
	EventDeploy = "deployment"
	EventBranch = "branch"
)

const (
	StatusSkipped = "skipped"
	StatusPending = "pending"
	StatusRunning = "running"
	StatusSuccess = "success"
	StatusFailure = "failure"
	StatusKilled  = "killed"
	StatusError   = "error"
)

const (
	RepoGit      = "git"
	RepoHg       = "hg"
	RepoFossil   = "fossil"
	RepoPerforce = "perforce"
)
<commit_msg>Suppression de EventBranch<commit_after>package model

const (
	EventPush   = "push"
	EventPull   = "pull_request"
	EventTag    = "tag"
	EventDeploy = "deployment"
)

const (
	StatusSkipped = "skipped"
	StatusPending = "pending"
	StatusRunning = "running"
	StatusSuccess = "success"
	StatusFailure = "failure"
	StatusKilled  = "killed"
	StatusError   = "error"
)

const (
	RepoGit      = "git"
	RepoHg       = "hg"
	RepoFossil   = "fossil"
	RepoPerforce = "perforce"
)
<|endoftext|>


<commit_before>/*
 NotifySemaphore - Simple "work available" notifications for consumers.
    http://godoc.org/github.com/johto/notifyutils/notifysemaphore
 */
package notifyutils
<commit_msg>Oops.  Looks like doc.go won't be necessary.<commit_after><|endoftext|>


<commit_before>package model

import (
	"fmt"
	MUtils "github.com/Cepave/common/utils"
	"math"
)

// DsType 即RRD中的Datasource的类型：GAUGE|COUNTER|DERIVE
type GraphItem struct {
	Endpoint  string            `json:"endpoint"`
	Metric    string            `json:"metric"`
	Tags      map[string]string `json:"tags"`
	Value     float64           `json:"value"`
	Timestamp int64             `json:"timestamp"`
	DsType    string            `json:"dstype"`
	Step      int               `json:"step"`
	Heartbeat int               `json:"heartbeat"`
	Min       string            `json:"min"`
	Max       string            `json:"max"`
}

func (this *GraphItem) String() string {
	return fmt.Sprintf(
		"<Endpoint:%s, Metric:%s, Tags:%v, Value:%v, TS:%d %v DsType:%s, Step:%d, Heartbeat:%d, Min:%s, Max:%s>",
		this.Endpoint,
		this.Metric,
		this.Tags,
		this.Value,
		this.Timestamp,
		MUtils.UnixTsFormat(this.Timestamp),
		this.DsType,
		this.Step,
		this.Heartbeat,
		this.Min,
		this.Max,
	)
}

func (this *GraphItem) PrimaryKey() string {
	return MUtils.PK(this.Endpoint, this.Metric, this.Tags)
}

func (t *GraphItem) Checksum() string {
	return MUtils.Checksum(t.Endpoint, t.Metric, t.Tags)
}

func (this *GraphItem) UUID() string {
	return MUtils.UUID(this.Endpoint, this.Metric, this.Tags, this.DsType, this.Step)
}

// ConsolFun 是RRD中的概念，比如：MIN|MAX|AVERAGE
type GraphQueryParam struct {
	Start     int64  `json:"start"`
	End       int64  `json:"end"`
	ConsolFun string `json:"consolFuc"`
	Endpoint  string `json:"endpoint"`
	Counter   string `json:"counter"`
}

type GraphQueryResponse struct {
	Endpoint string     `json:"endpoint"`
	Counter  string     `json:"counter"`
	DsType   string     `json:"dstype"`
	Step     int        `json:"step"`
	Values   []*RRDData `json:"Values"` //大写为了兼容已经再用这个api的用户
}

// 页面上已经可以看到DsType和Step了，直接带进查询条件，Graph更易处理
type GraphAccurateQueryParam struct {
	Checksum  string `json:"checksum"`
	Start     int64  `json:"start"`
	End       int64  `json:"end"`
	ConsolFun string `json:"consolFuc"`
	DsType    string `json:"dsType"`
	Step      int    `json:"step"`
}

type GraphAccurateQueryResponse struct {
	Values []*RRDData `json:"values"`
}

type JsonFloat float64

func (v JsonFloat) MarshalJSON() ([]byte, error) {
	f := float64(v)
	if math.IsNaN(f) || math.IsInf(f, 0) {
		return []byte("null"), nil
	} else {
		return []byte(fmt.Sprintf("%f", f)), nil
	}
}

type RRDData struct {
	Timestamp int64     `json:"timestamp"`
	Value     JsonFloat `json:"value"`
}

func NewRRDData(ts int64, val float64) *RRDData {
	return &RRDData{Timestamp: ts, Value: JsonFloat(val)}
}

func (this *RRDData) String() string {
	return fmt.Sprintf(
		"<RRDData:Value:%v TS:%d %v>",
		this.Value,
		this.Timestamp,
		MUtils.UnixTsFormat(this.Timestamp),
	)
}

type GraphInfoParam struct {
	Endpoint string `json:"endpoint"`
	Counter  string `json:"counter"`
}

type GraphInfoResp struct {
	ConsolFun string `json:"consolFun"`
	Step      int    `json:"step"`
	Filename  string `json:"filename"`
}

type GraphFullyInfo struct {
	Endpoint  string `json:"endpoint"`
	Counter   string `json:"counter"`
	ConsolFun string `json:"consolFun"`
	Step      int    `json:"step"`
	Filename  string `json:"filename"`
	Addr      string `json:"addr"`
}

type GraphLastParam struct {
	Endpoint string `json:"endpoint"`
	Counter  string `json:"counter"`
}

type GraphLastResp struct {
	Endpoint string   `json:"endpoint"`
	Counter  string   `json:"counter"`
	Value    *RRDData `json:"value"`
}
<commit_msg>add setp for graph query params for support query to specific the interval of timeseris data<commit_after>package model

import (
	"fmt"
	MUtils "github.com/Cepave/common/utils"
	"math"
)

// DsType 即RRD中的Datasource的类型：GAUGE|COUNTER|DERIVE
type GraphItem struct {
	Endpoint  string            `json:"endpoint"`
	Metric    string            `json:"metric"`
	Tags      map[string]string `json:"tags"`
	Value     float64           `json:"value"`
	Timestamp int64             `json:"timestamp"`
	DsType    string            `json:"dstype"`
	Step      int               `json:"step"`
	Heartbeat int               `json:"heartbeat"`
	Min       string            `json:"min"`
	Max       string            `json:"max"`
}

func (this *GraphItem) String() string {
	return fmt.Sprintf(
		"<Endpoint:%s, Metric:%s, Tags:%v, Value:%v, TS:%d %v DsType:%s, Step:%d, Heartbeat:%d, Min:%s, Max:%s>",
		this.Endpoint,
		this.Metric,
		this.Tags,
		this.Value,
		this.Timestamp,
		MUtils.UnixTsFormat(this.Timestamp),
		this.DsType,
		this.Step,
		this.Heartbeat,
		this.Min,
		this.Max,
	)
}

func (this *GraphItem) PrimaryKey() string {
	return MUtils.PK(this.Endpoint, this.Metric, this.Tags)
}

func (t *GraphItem) Checksum() string {
	return MUtils.Checksum(t.Endpoint, t.Metric, t.Tags)
}

func (this *GraphItem) UUID() string {
	return MUtils.UUID(this.Endpoint, this.Metric, this.Tags, this.DsType, this.Step)
}

// ConsolFun 是RRD中的概念，比如：MIN|MAX|AVERAGE
type GraphQueryParam struct {
	Start     int64  `json:"start"`
	End       int64  `json:"end"`
	ConsolFun string `json:"consolFuc"`
	Endpoint  string `json:"endpoint"`
	Counter   string `json:"counter"`
	Step      int    `json:"step"`
}

type GraphQueryResponse struct {
	Endpoint string     `json:"endpoint"`
	Counter  string     `json:"counter"`
	DsType   string     `json:"dstype"`
	Step     int        `json:"step"`
	Values   []*RRDData `json:"Values"` //大写为了兼容已经再用这个api的用户
}

// 页面上已经可以看到DsType和Step了，直接带进查询条件，Graph更易处理
type GraphAccurateQueryParam struct {
	Checksum  string `json:"checksum"`
	Start     int64  `json:"start"`
	End       int64  `json:"end"`
	ConsolFun string `json:"consolFuc"`
	DsType    string `json:"dsType"`
	Step      int    `json:"step"`
}

type GraphAccurateQueryResponse struct {
	Values []*RRDData `json:"values"`
}

type JsonFloat float64

func (v JsonFloat) MarshalJSON() ([]byte, error) {
	f := float64(v)
	if math.IsNaN(f) || math.IsInf(f, 0) {
		return []byte("null"), nil
	} else {
		return []byte(fmt.Sprintf("%f", f)), nil
	}
}

type RRDData struct {
	Timestamp int64     `json:"timestamp"`
	Value     JsonFloat `json:"value"`
}

func NewRRDData(ts int64, val float64) *RRDData {
	return &RRDData{Timestamp: ts, Value: JsonFloat(val)}
}

func (this *RRDData) String() string {
	return fmt.Sprintf(
		"<RRDData:Value:%v TS:%d %v>",
		this.Value,
		this.Timestamp,
		MUtils.UnixTsFormat(this.Timestamp),
	)
}

type GraphInfoParam struct {
	Endpoint string `json:"endpoint"`
	Counter  string `json:"counter"`
}

type GraphInfoResp struct {
	ConsolFun string `json:"consolFun"`
	Step      int    `json:"step"`
	Filename  string `json:"filename"`
}

type GraphFullyInfo struct {
	Endpoint  string `json:"endpoint"`
	Counter   string `json:"counter"`
	ConsolFun string `json:"consolFun"`
	Step      int    `json:"step"`
	Filename  string `json:"filename"`
	Addr      string `json:"addr"`
}

type GraphLastParam struct {
	Endpoint string `json:"endpoint"`
	Counter  string `json:"counter"`
}

type GraphLastResp struct {
	Endpoint string   `json:"endpoint"`
	Counter  string   `json:"counter"`
	Value    *RRDData `json:"value"`
}
<|endoftext|>


<commit_before>/*
Package rat, rest api testing in Go

This package provides a few simple helper types and functions to create
functional tests that call a running REST based WebService.
A test uses a rat Client that encapsulates a standard http.Client and the base url.
This can be created inside a function, as part of TestMain or as package variable.
Using the Client, you can send http requests and call expectation functions with the response.

Example

	// setup a shared client to your API
	var chatter = rat.NewClient("http://api.chatter.com", new(http.Client))

	func TestGetMessages(t *testing.T) {
		r := chatter.GET(t, rat.NewConfig("/v1/messages?user=zeus"))
		ExpectStatus(t,r,200)
		ExpectJsonArray(t,r,func(messages []interface{}){

			// in the callback you can validate the response structure
			if len(messages) == 0 {
				t.Error("expected messages, got none")
			}
		})
	}

If needed, implement the standard TestMain to do global setup and teardown.

	func TestMain(m *testing.M) {
		// there is no *testing.T available, use the failing one
		t := rat.FailingT

		// setup
		chatter.PUT(t, rat.NewConfig("/v1/messages/1").Body("<payload>"))
		ExpectStatus(t,r,204)

		exitCode := m.Run()

		// teardown
		chatter.DELETE(t, rat.NewConfig("/v1/messages/1"))
		ExpectStatus(t,r,204)

		os.Exit(exitCode)
	}

(c) 2015, http://ernestmicklei.com. MIT License
*/
package rat
<commit_msg>update doc<commit_after>/*
Package rat, rest api testing in Go

This package provides a few simple helper types and functions to create
functional tests that call a running REST based WebService.
A test uses a rat Client that encapsulates a standard http.Client and the base url.
This can be created inside a function, as part of TestMain or as package variable.
Using the Client, you can send http requests and call expectation functions with the response.

Example

	// setup a shared client to your API
	var chatter = rat.NewClient("http://api.chatter.com", new(http.Client))

	func TestGetMessages(t *testing.T) {
		r := chatter.GET(t, rat.NewConfig("/v1/messages?user=zeus"))
		ExpectStatus(t,r,200)
		ExpectJsonArray(t,r,func(messages []interface{}){

			// in the callback you can validate the response structure
			if len(messages) == 0 {
				t.Error("expected messages, got none")
			}
		})
	}

If needed, implement the standard TestMain to do global setup and teardown.

	func TestMain(m *testing.M) {
		// there is no *testing.T available, use an stdout implementation
		t := rat.TestingT

		// setup
		chatter.PUT(t, rat.NewConfig("/v1/messages/1").Body("<payload>"))
		ExpectStatus(t,r,204)

		exitCode := m.Run()

		// teardown
		chatter.DELETE(t, rat.NewConfig("/v1/messages/1"))
		ExpectStatus(t,r,204)

		os.Exit(exitCode)
	}

(c) 2015, http://ernestmicklei.com. MIT License
*/
package rat
<|endoftext|>


<commit_before>/*
Package sjson provides decoding of JSON Text as defined in ECMA-404.

Sjson is designed to be fast and simple, for now it supports only dynamic deserialization.
Simple benchmark test shows ~2x speedup against encoding/json standard parser.
	BenchmarkSimple   300000             10216 ns/op
	BenchmarkStd      200000             22413 ns/op

Links

Some useful links.
	* http://json.org - Info about JSON
	* http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf - ECMA-404 specification
	* https://metacpan.org/pod/JSON%3A%3AXS - JSON::XS Perl module

Thanks

Development of the project was sponsored by "Crazy Panda" (http://cpdecision.com)
as part of a project on processing statistical data.

Some ideas was borrowed from excellent Marc A. Lehmann's JSON::XS code.

*/
package sjson
<commit_msg>doc: use official name of the sponsor company.<commit_after>/*
Package sjson provides decoding of JSON Text as defined in ECMA-404.

Sjson is designed to be fast and simple, for now it supports only dynamic deserialization.
Simple benchmark test shows ~2x speedup against encoding/json standard parser.
	BenchmarkSimple   300000             10216 ns/op
	BenchmarkStd      200000             22413 ns/op

Links

Some useful links.
	* http://json.org - Info about JSON
	* http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf - ECMA-404 specification
	* https://metacpan.org/pod/JSON%3A%3AXS - JSON::XS Perl module

Thanks

Development of the project was sponsored by CP Decision LLC (http://cpdecision.com)
as part of a project on processing statistical data.

Some ideas was borrowed from excellent Marc A. Lehmann's JSON::XS code.

*/
package sjson
<|endoftext|>


<commit_before>package model

import (
    "time"
)

type (
	Order struct {
		Id       int     `json:"id"`
		Amount    float32 `json:"amount"`
        Remark string `json:"remark"`

        CreatedTime time.Time `json:"createdTime"`
        UpdatedTime time.Time `json:"updatedTime"`

        OrderStatus OrderStatus `json:"status"`
        Customer Customer `json:'customer'`
        Products []Product `json:"products"`

        ShippingAddress Address `json:'address'`
	}

    OrderStatus struct {
        Id int `json:"id"`
        Name string `json:"name"`
    }

)
<commit_msg>new Address struct in order model<commit_after>package model

import (
    "time"
)

type (
	Order struct {
		Id       int     `json:"id"`
		Amount    float32 `json:"amount"`
		Remark string `json:"remark"`

		CreatedTime time.Time `json:"createdTime"`
		UpdatedTime time.Time `json:"updatedTime"`

		OrderStatus OrderStatus `json:"status"`
		//Customer Customer `json:'customer'`
		Products []Product `json:"products"`

		ShippingAddress Address `json:'address'`
		BillingAddress Address `json:'address'`
	}

	OrderStatus struct {
		Id int `json:"id"`
		Name string `json:"name"`
	}

	Address struct {
		Company         string `json:"company"`
		FirstName       string `json:"firstname"`
		LastName        string `json:"lastname"`
		FullName        string `json:"fullname"`
		Street          string `json:"street"`
		StreetLine      string `json:"street_line2"`
		City            string `json:"city"`
		State           string `json:"state"`
		PostCode        string `json:"postcode"`
		Country         string `json:"country"`
	}

)
<|endoftext|>


<commit_before>/*
go-restful, a lean package for creating REST-style WebServices without magic.

Example WebService:

	package landscapeservice

	import (
	    "github.com/emicklei/go-restful"
	)

	type LandscapeService struct {
		restful.WebService
	}
	func New() *LandscapeService {
		ws := new(LandscapeService)
		ws.Path("/applications").Accept("application/xml").ContentType("application/xml")

		ws.Route(ws.GET("/{id}").To(GetApplication))
		ws.Route(ws.POST("/").To(SaveApplication))
		return ws
	}
	func GetApplication(request *Request, response *Response) {
		id := request.PathParameter("id")
		...
	}
	func SaveApplication(request *Request, response *Response) {
		...
	}

Example main:

	func main() {
		restful.Add(landscapeservice.New())
		log.Fatal(http.ListenAndServe(":8080", nil))
	}

[project]: https://github.com/emicklei/go-restful
[example]: http://ernestmicklei.com/2012/11/24/go-restful-first-working-example/
[design]:  http://ernestmicklei.com/2012/11/11/go-restful-api-design/
[1st use]: https://github.com/emicklei/landskape

(c) 2012, http://ernestmicklei.com. MIT License
*/
package restful
<commit_msg>updated doc<commit_after>/*
go-restful, a lean package for creating REST-style WebServices without magic.

Example WebService:

	package landscapeservice

	import (
	    "github.com/emicklei/go-restful"
	)

	type LandscapeService struct {
		restful.WebService
	}
	func New() *LandscapeService {
		ws := new(LandscapeService)
		ws.Path("/applications").Accept("application/xml").ContentType("application/xml")

		ws.Route(ws.GET("/{id}").To(GetApplication))
		ws.Route(ws.POST("/").To(SaveApplication))
		return ws
	}
	func GetApplication(request *Request, response *Response) {
		id := request.PathParameter("id")
		env := request.QueryParameter("environment")
	}
	func SaveApplication(request *Request, response *Response) {
	    // response.WriteEntity(anApp) , use Accept header to detect XML/JSON
		// response.WriterError(http.StatusInternalServerError,err
	}

Example main:

	func main() {
		restful.Add(landscapeservice.New())
		log.Fatal(http.ListenAndServe(":8080", nil))
	}

[project]: https://github.com/emicklei/go-restful

[example]: http://ernestmicklei.com/2012/11/24/go-restful-first-working-example/

[design]:  http://ernestmicklei.com/2012/11/11/go-restful-api-design/

[1st use]: https://github.com/emicklei/landskape

(c) 2012, http://ernestmicklei.com. MIT License
*/
package restful
<|endoftext|>


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

// Package errd simplifies error and defer handling.
//
// Overview
//
// Package errd allows returning form a block of code without using the usual if
// clauses, while properly intercepting errors and passing them to code called
// at defer time.
//
// The following piece of idiomatic Go writes the contents of a reader to a file
// on Google Cloud Storage:
//
//     func writeToGS(ctx context.Context, bucket, dst string, r io.Reader) (err error) {
//         client, err := storage.NewClient(ctx)
//         if err != nil {
//             return err
//         }
//         defer client.Close()
//
//         w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
//         defer func() {
//             if r := recover(); r != nil {
//                 w.CloseWithError(fmt.Errorf("panic: %v", r))
//                 panic(r)
//             }
//             if err != nil {
//                 _ = w.CloseWithError(err)
//             } else {
//                 err = w.Close()
//             }
//         }
//         _, err = io.Copy(w, r)
//         return err
//     }
//
// Google Cloud Storage allows files to be written atomically. This code
// minimizes the chance of writing a bad file by aborting the write, using
// CloseWithError, whenever any anomaly is encountered. This includes a
// panic that could occur in the reader.
//
// This code shows that error handling can be subtle and not the mindless
// check-decorate-return pattern it often seems to be. Does a Closer also
// support CloseWithError? Which panics need to be handled? Also note the
// subtle use of the return variable to convey an error in Copy to the last
// defer function.
// In practice, it is not unlikely that one would forget to handle the reader
// panicing, or even returning the error from Close,
// until this is discovered as a bug.
//
// Package errd aims to greatly reduce bugs resulting from such subtleties by
// making the default of having very strict error checking easy.
// The following code achieves the same as the above:
//
//     func writeToGS(ctx context.Context, bucket, dst, src string) error {
//         return errd.Run(func(e *errd.E) {
//             client, err := storage.NewClient(ctx)
//             e.Must(err)
//             e.DeferClose(client, errd.Discard)
//
//             w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
//             e.DeferCloseWithError(w)
//
//             _, err = io.Copy(w, r)
//             e.Must(err)
//         })
//     }
//
// The `Discard` handler is passed to mimic the behavior of the original code
// to ignore any error resulting from closing the client.
//
// Package `errd` also allows automatic selection of the defer method using the
// `Defer` and `MustDefer` method, where the later is a shorthand of calling
// `Must` and `Defer` in sequence.
//
//     func writeToGS(ctx context.Context, bucket, dst, src string) error {
//         return errd.Run(func(e *errd.E) {
//             client, err := storage.NewClient(ctx)
//             e.MustDefer(client, err, )
//
//             w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
//             e.Defer(w)
//
//             _, err = io.Copy(w, r)
//             e.Must(err)
//         })
//     }
//
// Using these implicit defers will ensure the most conservative defer method
// is picked by default, simplifying understanding the code without consulting
// the docs.
//
//
// Error Handlers
//
// In all of the code above we made the common faux pas of passing errors on
// without decorating them. Package errd defines a Handler type to simplify the
// task of decorating.
//
// Suppose we want to use github.com/pkg/errors to decorate errors. A simple
// handler can be defined as:
//
//     type msg string
//
//     func (m msg) Handle(s errd.State, err error) error {
//         return errors.WithMessage(err, string(m))
//     }
//
// This handler can then be used as follows:
//
//     func writeToGS(ctx context.Context, bucket, dst, src string) error {
//         return errd.Catch(func(e *errd.E) {
//             client, err := storage.NewClient(ctx)
//             e.Must(err, msg("error opening client"))
//             e.Defer(client)
//
//             w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
//             e.Defer(w)
//
//             _, err = io.Copy(w, r)
//             e.Must(err, msg("error copying contents"))
//         })
//     }
//
// The storage package used in this example defines the errors that are
// typically a result of user error. It would be possible to write a more
// generic storage writer that will add additional clarification when possible.
// Using such a handler as a default handler would look like:
//
//     var ecGS = errd.New(DefaultHandler(...))
//
//     func writeToGS(ctx context.Context, bucket, dst, src string) error {
//         return ecGS.Run(func(e *errd.E) {
//             client, err := storage.NewClient(ctx)
//             e.Must(err)
//             e.Defer(client)
//             ...
//         })
//     }
//
// Setting up a global config with a default handler and using that everywhere
// makes it easy to enforce decorating errors. Error handlers can also be used
// to pass up HTTP error codes, log errors, attach metrics, etc.
//
//
// Deferring
//
// Package errd includes predefined defer handlers for unlocking sync.Lockers
// and closing io.Closers and Closers that include a CloseWithError method.
// Users can define their own by passing a DeferFunc to the DeferFunc method.
//
// With AutoDefer or Auto, errd will automatically select the defer handler
// based on the type of the value. In case of Closing, this has the advantage
// that one will not mistakenly forget to use CloseWithError when appropriate.
// By default errd will select the most conservative error passing strategy.
// Users may provide support for additional types with the DeferHandler Option.
//
//
// Returning Values
//
// A function that is passed to Run does have any return values, not even an
// error. Users are supposed to set return values in the outer scope, for
// example by using named return variables.
//
//    func foo() (name string, err error) {
//        return name, Run(func(e *errd.E) {
//            //   Some fun code here.
//            //   Set name at the end.
//            name = "bar"
//        })
//    }
//
// If name is only set at the end, any error will force an early return from Run
// and leave name empty. Otherwise, name will be set and err will be nil.
package errd

// TODO
//
// - Examples
//
// - Add semantic versioning.
//
// Consider these API changes:
//
// - Option to chose error, where a newly encountered error may be returned
//   instead of a previously selected one. Could be an option Replace in State.
// - Allow functions of signature func(), func(error), func() error, and
//   func(error) error, to be passed to Defer.
//
// For v2, if performance allows::
// - make E an interface: this allows injecting with test simulator.
//   Would be great for such functionality. Godocs will not look as nice,
//   though.
<commit_msg>fixed type<commit_after>// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package errd simplifies error and defer handling.
//
// Overview
//
// Package errd allows returning form a block of code without using the usual if
// clauses, while properly intercepting errors and passing them to code called
// at defer time.
//
// The following piece of idiomatic Go writes the contents of a reader to a file
// on Google Cloud Storage:
//
//     func writeToGS(ctx context.Context, bucket, dst string, r io.Reader) (err error) {
//         client, err := storage.NewClient(ctx)
//         if err != nil {
//             return err
//         }
//         defer client.Close()
//
//         w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
//         defer func() {
//             if r := recover(); r != nil {
//                 w.CloseWithError(fmt.Errorf("panic: %v", r))
//                 panic(r)
//             }
//             if err != nil {
//                 _ = w.CloseWithError(err)
//             } else {
//                 err = w.Close()
//             }
//         }
//         _, err = io.Copy(w, r)
//         return err
//     }
//
// Google Cloud Storage allows files to be written atomically. This code
// minimizes the chance of writing a bad file by aborting the write, using
// CloseWithError, whenever any anomaly is encountered. This includes a
// panic that could occur in the reader.
//
// This code shows that error handling can be subtle and not the mindless
// check-decorate-return pattern it often seems to be. Does a Closer also
// support CloseWithError? Which panics need to be handled? Also note the
// subtle use of the return variable to convey an error in Copy to the last
// defer function.
// In practice, it is not unlikely that one would forget to handle the reader
// panicing, or even returning the error from Close,
// until this is discovered as a bug.
//
// Package errd aims to greatly reduce bugs resulting from such subtleties by
// making the default of having very strict error checking easy.
// The following code achieves the same as the above:
//
//     func writeToGS(ctx context.Context, bucket, dst, src string) error {
//         return errd.Run(func(e *errd.E) {
//             client, err := storage.NewClient(ctx)
//             e.Must(err)
//             e.DeferClose(client, errd.Discard)
//
//             w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
//             e.DeferCloseWithError(w)
//
//             _, err = io.Copy(w, r)
//             e.Must(err)
//         })
//     }
//
// The `Discard` handler is passed to mimic the behavior of the original code
// to ignore any error resulting from closing the client.
//
// Package `errd` also allows automatic selection of the defer method using the
// `Defer` and `MustDefer` method, where the later is a shorthand of calling
// `Must` and `Defer` in sequence.
//
//     func writeToGS(ctx context.Context, bucket, dst, src string) error {
//         return errd.Run(func(e *errd.E) {
//             client, err := storage.NewClient(ctx)
//             e.MustDefer(client, err)
//
//             w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
//             e.Defer(w)
//
//             _, err = io.Copy(w, r)
//             e.Must(err)
//         })
//     }
//
// Using these implicit defers will ensure the most conservative defer method
// is picked by default, simplifying understanding the code without consulting
// the docs.
//
//
// Error Handlers
//
// In all of the code above we made the common faux pas of passing errors on
// without decorating them. Package errd defines a Handler type to simplify the
// task of decorating.
//
// Suppose we want to use github.com/pkg/errors to decorate errors. A simple
// handler can be defined as:
//
//     type msg string
//
//     func (m msg) Handle(s errd.State, err error) error {
//         return errors.WithMessage(err, string(m))
//     }
//
// This handler can then be used as follows:
//
//     func writeToGS(ctx context.Context, bucket, dst, src string) error {
//         return errd.Catch(func(e *errd.E) {
//             client, err := storage.NewClient(ctx)
//             e.Must(err, msg("error opening client"))
//             e.Defer(client)
//
//             w := client.Bucket(bucket).Object(dst).NewWriter(ctx)
//             e.Defer(w)
//
//             _, err = io.Copy(w, r)
//             e.Must(err, msg("error copying contents"))
//         })
//     }
//
// The storage package used in this example defines the errors that are
// typically a result of user error. It would be possible to write a more
// generic storage writer that will add additional clarification when possible.
// Using such a handler as a default handler would look like:
//
//     var ecGS = errd.New(DefaultHandler(...))
//
//     func writeToGS(ctx context.Context, bucket, dst, src string) error {
//         return ecGS.Run(func(e *errd.E) {
//             client, err := storage.NewClient(ctx)
//             e.Must(err)
//             e.Defer(client)
//             ...
//         })
//     }
//
// Setting up a global config with a default handler and using that everywhere
// makes it easy to enforce decorating errors. Error handlers can also be used
// to pass up HTTP error codes, log errors, attach metrics, etc.
//
//
// Deferring
//
// Package errd includes predefined defer handlers for unlocking sync.Lockers
// and closing io.Closers and Closers that include a CloseWithError method.
// Users can define their own by passing a DeferFunc to the DeferFunc method.
//
// With AutoDefer or Auto, errd will automatically select the defer handler
// based on the type of the value. In case of Closing, this has the advantage
// that one will not mistakenly forget to use CloseWithError when appropriate.
// By default errd will select the most conservative error passing strategy.
// Users may provide support for additional types with the DeferHandler Option.
//
//
// Returning Values
//
// A function that is passed to Run does have any return values, not even an
// error. Users are supposed to set return values in the outer scope, for
// example by using named return variables.
//
//    func foo() (name string, err error) {
//        return name, Run(func(e *errd.E) {
//            //   Some fun code here.
//            //   Set name at the end.
//            name = "bar"
//        })
//    }
//
// If name is only set at the end, any error will force an early return from Run
// and leave name empty. Otherwise, name will be set and err will be nil.
package errd

// TODO
//
// - Examples
//
// - Add semantic versioning.
//
// Consider these API changes:
//
// - Option to chose error, where a newly encountered error may be returned
//   instead of a previously selected one. Could be an option Replace in State.
// - Allow functions of signature func(), func(error), func() error, and
//   func(error) error, to be passed to Defer.
//
// For v2, if performance allows::
// - make E an interface: this allows injecting with test simulator.
//   Would be great for such functionality. Godocs will not look as nice,
//   though.
<|endoftext|>


<commit_before>/*
Package selenium provider a WebDriver client.

Currently provides only WebDriver remote client.

This means you'll need to run the Selenium server by yourself (or use a service
like SauceLabs). The easiest way to do that is to grab the Selenium server jar
from http://www.seleniumhq.org/download/ and run it
	java -jar selenium-server-standalone-2.24.1.jar

To use the webdriver with firefox, you may (depending on versions) require the
gecko driver package. You can download it here
        https://github.com/mozilla/geckodriver/releases
and configure the webdriver in your Go code like this
        caps := selenium.Capabilities{
            "browserName":            "firefox",
            "webdriver.gecko.driver": "/path/to/downloaded/geckodriver",
        }
*/
package selenium
<commit_msg>Rewrite doc.go to remove stale information<commit_after>/*
Package selenium provides a client to drive web browser-based automation and
testing.

See the example below for how to get started with this API.

This package can depend on several binaries being available, depending on which
browsers will be used and how. To avoid needing to manage these dependencies,
use a cloud-based browser testing environment, like Sauce Labs, BrowserStack
or similar. Otherwise, use the methods provided by this API to specify the
paths to the dependencies, which will have to be downloaded separately.
*/
package selenium
<|endoftext|>


<commit_before>package hpcloud

import (
	"errors"
	"fmt"
	"net/http"
)

func (a Access) ObjectStoreUpload(filename, container, as string, header *http.Header) error {
	f, err := OpenAndHashFile(filename)
	if err != nil {
		return err
	}
	client := &http.Client{}
	path := fmt.Sprintf("%s%s/%s/%s", OBJECT_STORE, a.TenantID, container, as)
	req, err := http.NewRequest("PUT", path, f)
	if err != nil {
		return err
	}
	req.Header.Add("X-Auth-Token", a.AuthToken())
	if header != nil {
		for key, value := range *header {
			for _, s := range value {
				req.Header.Add(key, s)
			}
		}
	}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusCreated {
		return errors.New("Not created.")
	}
	return nil
}
<commit_msg>objectstore.go docstrings.<commit_after>package hpcloud

import (
	"errors"
	"fmt"
	"net/http"
)

/*
 ObjectStoreUpload allows you to upload a file onto the HPCloud, it will
 hash the file and check the returned hash to ensure end-to-end integrity.

 It also takes an optional header which will have it's contents added
 to the request.
*/
func (a Access) ObjectStoreUpload(filename, container, as string, header *http.Header) error {
	f, err := OpenAndHashFile(filename)
	if err != nil {
		return err
	}
	client := &http.Client{}
	path := fmt.Sprintf("%s%s/%s/%s", OBJECT_STORE, a.TenantID, container, as)
	req, err := http.NewRequest("PUT", path, f)
	if err != nil {
		return err
	}
	req.Header.Add("X-Auth-Token", a.AuthToken())
	if header != nil {
		for key, value := range *header {
			for _, s := range value {
				req.Header.Add(key, s)
			}
		}
	}
	resp, err := client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusCreated {
		return errors.New("Not created.")
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
// Licensed under the Mozilla Public License v2.0

package oci

import (
	"log"
)

const Version = "4.44.0"
const ReleaseDate = "2021-09-15"

func PrintVersion() {
	log.Printf("[INFO] terraform-provider-oci %s\n", Version)
}
<commit_msg>Finalize changelog and release for version v4.45.0<commit_after>// Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved.
// Licensed under the Mozilla Public License v2.0

package oci

import (
	"log"
)

const Version = "4.45.0"
const ReleaseDate = "2021-09-22"

func PrintVersion() {
	log.Printf("[INFO] terraform-provider-oci %s\n", Version)
}
<|endoftext|>


<commit_before>// Copyright 2020 Google Inc. All Rights Reserved.

package models

import (
	"errors"
	"fmt"
	"regexp"
	"time"

	rpc "apigov.dev/flame/rpc"
	ptypes "github.com/golang/protobuf/ptypes"
)

// File ...
type File struct {
	ProjectID   string    // Uniquely identifies a project.
	ProductID   string    // Uniquely identifies a product within a project.
	VersionID   string    // Uniquely identifies a version within a product.
	SpecID      string    // Uniquely identifies a spec within a version.
	FileID      string    // Uniquely identifies a file within a spec.
	DisplayName string    // A human-friendly name.
	Description string    // A detailed description.
	CreateTime  time.Time // Creation time.
	UpdateTime  time.Time // Time of last change.
	FileName    string    // Name of file.
	SizeInBytes int32     // Size of the file.
	Hash        string    // A hash of the file.
	SourceURI   string    // The original source URI of the file.
	Contents    []byte    `datastore:",noindex"` // The contents of the file.
}

// ParseParentSpec ...
func ParseParentSpec(parent string) ([]string, error) {
	r := regexp.MustCompile("^projects/" + nameRegex +
		"/products/" + nameRegex +
		"/versions/" + nameRegex +
		"/specs/" + nameRegex +
		"$")
	m := r.FindAllStringSubmatch(parent, -1)
	if m == nil {
		return nil, fmt.Errorf("invalid spec '%s'", parent)
	}
	return m[0], nil
}

// NewFileFromParentAndFileID returns an initialized file for a specified parent and fileID.
func NewFileFromParentAndFileID(parent string, fileID string) (*File, error) {
	r := regexp.MustCompile("^projects/" + nameRegex +
		"/products/" + nameRegex +
		"/versions/" + nameRegex +
		"/specs/" + nameRegex + "$")
	m := r.FindAllStringSubmatch(parent, -1)
	if m == nil {
		return nil, fmt.Errorf("invalid parent '%s'", parent)
	}
	if err := validateID(fileID); err != nil {
		return nil, err
	}
	file := &File{}
	file.ProjectID = m[0][1]
	file.ProductID = m[0][2]
	file.VersionID = m[0][3]
	file.SpecID = m[0][4]
	file.FileID = fileID
	return file, nil
}

// NewFileFromResourceName parses resource names and returns an initialized file.
func NewFileFromResourceName(name string) (*File, error) {
	file := &File{}
	r := regexp.MustCompile("^projects/" + nameRegex + "/products/" + nameRegex + "/versions/" + nameRegex + "/specs/" + nameRegex + "/files/" + nameRegex + "$")
	m := r.FindAllStringSubmatch(name, -1)
	if m == nil {
		return nil, errors.New("invalid file name")
	}
	file.ProjectID = m[0][1]
	file.ProductID = m[0][2]
	file.VersionID = m[0][3]
	file.SpecID = m[0][4]
	file.FileID = m[0][5]
	return file, nil
}

// NewFileFromMessage returns an initialized file from a message.
func NewFileFromMessage(message *rpc.File) (*File, error) {
	file, err := NewFileFromResourceName(message.GetName())
	if err != nil {
		return nil, err
	}
	file.DisplayName = message.GetDisplayName()
	file.Description = message.GetDescription()
	//file.Availability = message.GetAvailability()
	//file.RecommendedVersion = message.GetRecommendedVersion()
	return file, nil
}

// ResourceName generates the resource name of a file.
func (file *File) ResourceName() string {
	return fmt.Sprintf("projects/%s/products/%s/versions/%s/specs/%s/files/%s",
		file.ProjectID, file.ProductID, file.VersionID, file.SpecID, file.FileID)
}

// Message returns a message representing a file.
func (file *File) Message(view rpc.FileView) (message *rpc.File, err error) {
	message = &rpc.File{}
	message.Name = file.ResourceName()
	message.DisplayName = file.DisplayName
	message.Description = file.Description
	message.CreateTime, err = ptypes.TimestampProto(file.CreateTime)
	message.UpdateTime, err = ptypes.TimestampProto(file.UpdateTime)
	if view == rpc.FileView_FULL {
		message.Contents = file.Contents
	}
	return message, err
}

// Update modifies a file using the contents of a message.
func (file *File) Update(message *rpc.File) error {
	file.Contents = message.GetContents()
	file.UpdateTime = file.CreateTime
	return nil
}
<commit_msg>Compute hash and size for uploaded files.<commit_after>// Copyright 2020 Google Inc. All Rights Reserved.

package models

import (
	"crypto/sha1"
	"errors"
	"fmt"
	"regexp"
	"time"

	rpc "apigov.dev/flame/rpc"
	ptypes "github.com/golang/protobuf/ptypes"
)

// File ...
type File struct {
	ProjectID   string    // Uniquely identifies a project.
	ProductID   string    // Uniquely identifies a product within a project.
	VersionID   string    // Uniquely identifies a version within a product.
	SpecID      string    // Uniquely identifies a spec within a version.
	FileID      string    // Uniquely identifies a file within a spec.
	DisplayName string    // A human-friendly name.
	Description string    // A detailed description.
	CreateTime  time.Time // Creation time.
	UpdateTime  time.Time // Time of last change.
	FileName    string    // Name of file.
	SizeInBytes int32     // Size of the file.
	Hash        string    // A hash of the file.
	SourceURI   string    // The original source URI of the file.
	Contents    []byte    `datastore:",noindex"` // The contents of the file.
}

// ParseParentSpec ...
func ParseParentSpec(parent string) ([]string, error) {
	r := regexp.MustCompile("^projects/" + nameRegex +
		"/products/" + nameRegex +
		"/versions/" + nameRegex +
		"/specs/" + nameRegex +
		"$")
	m := r.FindAllStringSubmatch(parent, -1)
	if m == nil {
		return nil, fmt.Errorf("invalid spec '%s'", parent)
	}
	return m[0], nil
}

// NewFileFromParentAndFileID returns an initialized file for a specified parent and fileID.
func NewFileFromParentAndFileID(parent string, fileID string) (*File, error) {
	r := regexp.MustCompile("^projects/" + nameRegex +
		"/products/" + nameRegex +
		"/versions/" + nameRegex +
		"/specs/" + nameRegex + "$")
	m := r.FindAllStringSubmatch(parent, -1)
	if m == nil {
		return nil, fmt.Errorf("invalid parent '%s'", parent)
	}
	if err := validateID(fileID); err != nil {
		return nil, err
	}
	file := &File{}
	file.ProjectID = m[0][1]
	file.ProductID = m[0][2]
	file.VersionID = m[0][3]
	file.SpecID = m[0][4]
	file.FileID = fileID
	return file, nil
}

// NewFileFromResourceName parses resource names and returns an initialized file.
func NewFileFromResourceName(name string) (*File, error) {
	file := &File{}
	r := regexp.MustCompile("^projects/" + nameRegex + "/products/" + nameRegex + "/versions/" + nameRegex + "/specs/" + nameRegex + "/files/" + nameRegex + "$")
	m := r.FindAllStringSubmatch(name, -1)
	if m == nil {
		return nil, errors.New("invalid file name")
	}
	file.ProjectID = m[0][1]
	file.ProductID = m[0][2]
	file.VersionID = m[0][3]
	file.SpecID = m[0][4]
	file.FileID = m[0][5]
	return file, nil
}

// NewFileFromMessage returns an initialized file from a message.
func NewFileFromMessage(message *rpc.File) (*File, error) {
	file, err := NewFileFromResourceName(message.GetName())
	if err != nil {
		return nil, err
	}
	file.DisplayName = message.GetDisplayName()
	file.Description = message.GetDescription()
	return file, nil
}

// ResourceName generates the resource name of a file.
func (file *File) ResourceName() string {
	return fmt.Sprintf("projects/%s/products/%s/versions/%s/specs/%s/files/%s",
		file.ProjectID, file.ProductID, file.VersionID, file.SpecID, file.FileID)
}

// Message returns a message representing a file.
func (file *File) Message(view rpc.FileView) (message *rpc.File, err error) {
	message = &rpc.File{}
	message.Name = file.ResourceName()
	message.DisplayName = file.DisplayName
	message.Description = file.Description
	message.SizeBytes = file.SizeInBytes
	message.Hash = file.Hash
	message.CreateTime, err = ptypes.TimestampProto(file.CreateTime)
	message.UpdateTime, err = ptypes.TimestampProto(file.UpdateTime)
	if view == rpc.FileView_FULL {
		message.Contents = file.Contents
	}
	return message, err
}

// Update modifies a file using the contents of a message.
func (file *File) Update(message *rpc.File) error {
	contents := message.GetContents()
	file.Contents = contents
	file.SizeInBytes = int32(len(contents))
	h := sha1.New()
	h.Write(contents)
	bs := h.Sum(nil)
	file.Hash = fmt.Sprintf("%x", bs)
	file.UpdateTime = file.CreateTime
	return nil
}
<|endoftext|>