<commit_before>// Copyright 2015 The Chromium 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 tsmon

import (
	"fmt"
	"net/url"
	"strings"
	"sync"

	"github.com/luci/luci-go/common/logging"
	"github.com/luci/luci-go/common/tsmon/monitor"
	"github.com/luci/luci-go/common/tsmon/store"
	"github.com/luci/luci-go/common/tsmon/target"
	"github.com/luci/luci-go/common/tsmon/types"
	"golang.org/x/net/context"
)

var (
	// Target contains information about this process, and is included in all
	// metrics reported by this process.
	Target types.Target

	globalStore   store.Store
	globalMonitor = monitor.NewNilMonitor()

	registeredMetrics     = map[string]types.Metric{}
	registeredMetricsLock sync.RWMutex

	cancelAutoFlush context.CancelFunc
)

// Store returns the global metric store that contains all the metric values for
// this process.  Applications shouldn't need to access this directly - instead
// use the metric objects which provide type-safe accessors.
func Store() store.Store {
	return globalStore
}

// Monitor returns the global monitor that sends metrics to monitoring
// endpoints.  Defaults to a nil monitor, but changed by InitializeFromFlags.
func Monitor() monitor.Monitor {
	return globalMonitor
}

// Register is called by metric objects to register themselves.  This will panic
// if another metric with the same name is already registered.
func Register(m types.Metric) {
	registeredMetricsLock.Lock()
	defer registeredMetricsLock.Unlock()

	if _, ok := registeredMetrics[m.Info().Name]; ok {
		panic(fmt.Sprintf("A metric with the name '%s' was already registered", m.Info().Name))
	}

	registeredMetrics[m.Info().Name] = m

	if globalStore != nil {
		globalStore.Register(m)
	}
}

// Unregister is called by metric objects to unregister themselves.
func Unregister(m types.Metric) {
	registeredMetricsLock.Lock()
	defer registeredMetricsLock.Unlock()

	delete(registeredMetrics, m.Info().Name)

	if globalStore != nil {
		globalStore.Unregister(m)
	}
}

// SetStore changes the global metric store.  All metrics that were registered
// with the old store will be re-registered on the new store.
func SetStore(s store.Store) {
	if s == globalStore {
		return
	}

	registeredMetricsLock.RLock()
	defer registeredMetricsLock.RUnlock()

	// Register metrics on the new store.
	for _, m := range registeredMetrics {
		s.Register(m)
	}

	oldStore := globalStore
	globalStore = s

	// Unregister metrics from the old store.
	if oldStore != nil {
		for _, m := range registeredMetrics {
			globalStore.Unregister(m)
		}
	}
}

// InitializeFromFlags configures the tsmon library from flag values.
// This will set a Target (information about what's reporting metrics) and a
// Monitor (where to send the metrics to).
func InitializeFromFlags(c context.Context, fl *Flags) error {
	logger := logging.Get(c)

	// Load the config file, and override its values with flags.
	config, err := loadConfig(fl.ConfigFile)
	if err != nil {
		return err
	}

	if fl.Endpoint != "" {
		config.Endpoint = fl.Endpoint
	}
	if fl.Credentials != "" {
		config.Credentials = fl.Credentials
	}

	if config.Endpoint != "" {
		endpointURL, err := url.Parse(config.Endpoint)
		if err != nil {
			return err
		}

		switch endpointURL.Scheme {
		case "file":
			globalMonitor = monitor.NewDebugMonitor(logger, endpointURL.Path)
		case "pubsub":
			m, err := monitor.NewPubsubMonitor(
				config.Credentials, endpointURL.Host, strings.TrimPrefix(endpointURL.Path, "/"))
			if err != nil {
				return err
			}
			globalMonitor = m
		default:
			return fmt.Errorf("unknown tsmon endpoint url: %s", config.Endpoint)
		}

		// Monitoring is enabled, so get the expensive default values for hostname,
		// etc.
		fl.Target.SetDefaultsFromHostname()
	} else {
		logger.Warningf("Monitoring is disabled because no endpoint is configured")
	}

	t, err := target.NewFromFlags(&fl.Target)
	if err != nil {
		return err
	}
	Target = t

	SetStore(store.NewInMemory())

	if cancelAutoFlush != nil {
		logger.Infof("Cancelling previous tsmon auto flush")
		cancelAutoFlush()
		cancelAutoFlush = nil
	}

	if fl.Flush == "auto" {
		var flushCtx context.Context
		flushCtx, cancelAutoFlush = context.WithCancel(c)
		go autoFlush(flushCtx, fl.FlushInterval)
	}

	return nil
}
<commit_msg>Install in-memory store in tsmon by default.<commit_after>// Copyright 2015 The Chromium 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 tsmon

import (
	"fmt"
	"net/url"
	"strings"
	"sync"

	"github.com/luci/luci-go/common/logging"
	"github.com/luci/luci-go/common/tsmon/monitor"
	"github.com/luci/luci-go/common/tsmon/store"
	"github.com/luci/luci-go/common/tsmon/target"
	"github.com/luci/luci-go/common/tsmon/types"
	"golang.org/x/net/context"
)

var (
	// Target contains information about this process, and is included in all
	// metrics reported by this process.
	Target types.Target

	globalStore   = store.NewInMemory()
	globalMonitor = monitor.NewNilMonitor()

	registeredMetrics     = map[string]types.Metric{}
	registeredMetricsLock sync.RWMutex

	cancelAutoFlush context.CancelFunc
)

// Store returns the global metric store that contains all the metric values for
// this process.  Applications shouldn't need to access this directly - instead
// use the metric objects which provide type-safe accessors.
func Store() store.Store {
	return globalStore
}

// Monitor returns the global monitor that sends metrics to monitoring
// endpoints.  Defaults to a nil monitor, but changed by InitializeFromFlags.
func Monitor() monitor.Monitor {
	return globalMonitor
}

// Register is called by metric objects to register themselves.  This will panic
// if another metric with the same name is already registered.
func Register(m types.Metric) {
	registeredMetricsLock.Lock()
	defer registeredMetricsLock.Unlock()

	if _, ok := registeredMetrics[m.Info().Name]; ok {
		panic(fmt.Sprintf("A metric with the name '%s' was already registered", m.Info().Name))
	}

	registeredMetrics[m.Info().Name] = m

	if globalStore != nil {
		globalStore.Register(m)
	}
}

// Unregister is called by metric objects to unregister themselves.
func Unregister(m types.Metric) {
	registeredMetricsLock.Lock()
	defer registeredMetricsLock.Unlock()

	delete(registeredMetrics, m.Info().Name)

	if globalStore != nil {
		globalStore.Unregister(m)
	}
}

// SetStore changes the global metric store.  All metrics that were registered
// with the old store will be re-registered on the new store.
func SetStore(s store.Store) {
	if s == globalStore {
		return
	}

	registeredMetricsLock.RLock()
	defer registeredMetricsLock.RUnlock()

	// Register metrics on the new store.
	for _, m := range registeredMetrics {
		s.Register(m)
	}

	oldStore := globalStore
	globalStore = s

	// Unregister metrics from the old store.
	if oldStore != nil {
		for _, m := range registeredMetrics {
			globalStore.Unregister(m)
		}
	}
}

// InitializeFromFlags configures the tsmon library from flag values.
// This will set a Target (information about what's reporting metrics) and a
// Monitor (where to send the metrics to).
func InitializeFromFlags(c context.Context, fl *Flags) error {
	logger := logging.Get(c)

	// Load the config file, and override its values with flags.
	config, err := loadConfig(fl.ConfigFile)
	if err != nil {
		return err
	}

	if fl.Endpoint != "" {
		config.Endpoint = fl.Endpoint
	}
	if fl.Credentials != "" {
		config.Credentials = fl.Credentials
	}

	if config.Endpoint != "" {
		endpointURL, err := url.Parse(config.Endpoint)
		if err != nil {
			return err
		}

		switch endpointURL.Scheme {
		case "file":
			globalMonitor = monitor.NewDebugMonitor(logger, endpointURL.Path)
		case "pubsub":
			m, err := monitor.NewPubsubMonitor(
				config.Credentials, endpointURL.Host, strings.TrimPrefix(endpointURL.Path, "/"))
			if err != nil {
				return err
			}
			globalMonitor = m
		default:
			return fmt.Errorf("unknown tsmon endpoint url: %s", config.Endpoint)
		}

		// Monitoring is enabled, so get the expensive default values for hostname,
		// etc.
		fl.Target.SetDefaultsFromHostname()
	} else {
		logger.Warningf("Monitoring is disabled because no endpoint is configured")
	}

	t, err := target.NewFromFlags(&fl.Target)
	if err != nil {
		return err
	}
	Target = t

	SetStore(store.NewInMemory())

	if cancelAutoFlush != nil {
		logger.Infof("Cancelling previous tsmon auto flush")
		cancelAutoFlush()
		cancelAutoFlush = nil
	}

	if fl.Flush == "auto" {
		var flushCtx context.Context
		flushCtx, cancelAutoFlush = context.WithCancel(c)
		go autoFlush(flushCtx, fl.FlushInterval)
	}

	return nil
}
<|endoftext|>


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

package commands

import (
	"encoding/json"
	"fmt"
	"os/exec"

	"github.com/garyburd/neovim-go/vim"
	"github.com/garyburd/neovim-go/vim/plugin"

	"nvim-go/context"
	"nvim-go/nvim"
	"nvim-go/config"
)

func init() {
	plugin.HandleCommand("Gometalinter",
		&plugin.CommandOptions{
			Eval: "getcwd()"},
		cmdMetalinter)
}

func cmdMetalinter(v *vim.Vim, cwd string) {
	go Metalinter(v, cwd)
}

type metalinterResult struct {
	Linter   string `json:"linter"`   // name of linter tool
	Severity string `json:"severity"` // result of type
	Path     string `json:"path"`     // path of file
	Line     int    `json:"line"`     // line of file
	Col      int    `json:"col"`      // col of file
	Message  string `json:"message"`  // description of linter message
}

// Metalinter lint the Go sources from current buffer's package use gometalinter tool.
func Metalinter(v *vim.Vim, cwd string) error {
	defer context.WithGoBuildForPath(cwd)()

	var (
		loclist []*nvim.ErrorlistData
		b       vim.Buffer
		w       vim.Window
	)

	p := v.NewPipeline()
	p.CurrentBuffer(&b)
	p.CurrentWindow(&w)
	if err := p.Wait(); err != nil {
		return err
	}

	args := []string{cwd + "/...", "--json", "--disable-all", "--deadline", config.MetalinterDeadline}
	for _, t := range config.MetalinterTools {
		args = append(args, "--enable", t)
	}

	cmd := exec.Command("gometalinter", args...)
	cmd.Dir = cwd
	stdout, _ := cmd.Output()
	cmd.Run()

	var result = []metalinterResult{}
	if err := json.Unmarshal(stdout, &result); err != nil {
		fmt.Println(err)
	}

	for _, r := range result {
		var errorType string
		switch r.Severity {
		case "error":
			errorType = "E"
		case "warning":
			errorType = "W"
		}
		loclist = append(loclist, &nvim.ErrorlistData{
			FileName: r.Path,
			LNum:     r.Line,
			Col:      r.Col,
			Text:     r.Linter + ": " + r.Message,
			Type:     errorType,
		})
	}

	if err := nvim.SetLoclist(p, loclist); err != nil {
		return nvim.Echomsg(v, "Gometalinter: %v", err)
	}
	return nvim.OpenLoclist(p, w, loclist, true)
}
<commit_msg>Fix import sort order<commit_after>// Copyright 2016 Koichi Shiraishi. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package commands

import (
	"encoding/json"
	"fmt"
	"os/exec"

	"github.com/garyburd/neovim-go/vim"
	"github.com/garyburd/neovim-go/vim/plugin"

	"nvim-go/config"
	"nvim-go/context"
	"nvim-go/nvim"
)

func init() {
	plugin.HandleCommand("Gometalinter",
		&plugin.CommandOptions{
			Eval: "getcwd()"},
		cmdMetalinter)
}

func cmdMetalinter(v *vim.Vim, cwd string) {
	go Metalinter(v, cwd)
}

type metalinterResult struct {
	Linter   string `json:"linter"`   // name of linter tool
	Severity string `json:"severity"` // result of type
	Path     string `json:"path"`     // path of file
	Line     int    `json:"line"`     // line of file
	Col      int    `json:"col"`      // col of file
	Message  string `json:"message"`  // description of linter message
}

// Metalinter lint the Go sources from current buffer's package use gometalinter tool.
func Metalinter(v *vim.Vim, cwd string) error {
	defer context.WithGoBuildForPath(cwd)()

	var (
		loclist []*nvim.ErrorlistData
		b       vim.Buffer
		w       vim.Window
	)

	p := v.NewPipeline()
	p.CurrentBuffer(&b)
	p.CurrentWindow(&w)
	if err := p.Wait(); err != nil {
		return err
	}

	args := []string{cwd + "/...", "--json", "--disable-all", "--deadline", config.MetalinterDeadline}
	for _, t := range config.MetalinterTools {
		args = append(args, "--enable", t)
	}

	cmd := exec.Command("gometalinter", args...)
	cmd.Dir = cwd
	stdout, _ := cmd.Output()
	cmd.Run()

	var result = []metalinterResult{}
	if err := json.Unmarshal(stdout, &result); err != nil {
		fmt.Println(err)
	}

	for _, r := range result {
		var errorType string
		switch r.Severity {
		case "error":
			errorType = "E"
		case "warning":
			errorType = "W"
		}
		loclist = append(loclist, &nvim.ErrorlistData{
			FileName: r.Path,
			LNum:     r.Line,
			Col:      r.Col,
			Text:     r.Linter + ": " + r.Message,
			Type:     errorType,
		})
	}

	if err := nvim.SetLoclist(p, loclist); err != nil {
		return nvim.Echomsg(v, "Gometalinter: %v", err)
	}
	return nvim.OpenLoclist(p, w, loclist, true)
}
<|endoftext|>


<commit_before>package pack

import (
	"bytes"
	"encoding/binary"
	"errors"
	"io"
)

var (
	// ErrShortFanout is an error representing situations where the entire
	// fanout table could not be read, and is thus too short.
	ErrShortFanout = errors.New("git/odb/pack: too short fanout table")

	// indexHeader is the first four "magic" bytes of index files version 2
	// or newer.
	indexHeader = []byte{0xff, 0x74, 0x4f, 0x63}
)

// DecodeIndex decodes an index whose underlying data is supplied by "r".
//
// DecodeIndex reads only the header and fanout table, and does not eagerly
// parse index entries.
//
// If there was an error parsing, it will be returned immediately.
func DecodeIndex(r io.ReaderAt) (*Index, error) {
	version, err := decodeIndexHeader(r)
	if err != nil {
		return nil, err
	}

	fanout, err := decodeIndexFanout(r, version.Width())
	if err != nil {
		return nil, err
	}

	return &Index{
		version: version,
		fanout:  fanout,

		f: r,
	}, nil
}

// decodeIndexHeader determines which version the index given by "r" is.
func decodeIndexHeader(r io.ReaderAt) (IndexVersion, error) {
	hdr := make([]byte, 4)
	if _, err := r.ReadAt(hdr, 0); err != nil {
		return VersionUnknown, err
	}

	if bytes.Equal(hdr, indexHeader) {
		vb := make([]byte, 4)
		if _, err := r.ReadAt(vb, 4); err != nil {
			return VersionUnknown, err
		}

		version := IndexVersion(binary.BigEndian.Uint32(vb))

		return version, &UnsupportedVersionErr{uint32(version)}
	}
	return IndexVersion(0), nil
}

// decodeIndexFanout decodes the fanout table given by "r" and beginning at the
// given offset.
func decodeIndexFanout(r io.ReaderAt, offset int64) ([]uint32, error) {
	b := make([]byte, 256*4)
	if _, err := r.ReadAt(b, offset); err != nil {
		if err == io.EOF {
			return nil, ErrShortFanout
		}
		return nil, err
	}

	fanout := make([]uint32, 256)
	for i, _ := range fanout {
		fanout[i] = binary.BigEndian.Uint32(b[(i * 4):])
	}

	return fanout, nil
}
<commit_msg>git/odb/pack: assign V1Width<commit_after>package pack

import (
	"bytes"
	"encoding/binary"
	"errors"
	"io"
)

const (
	// V1Width is the total width of the header in V1.
	V1Width = 0
)

var (
	// ErrShortFanout is an error representing situations where the entire
	// fanout table could not be read, and is thus too short.
	ErrShortFanout = errors.New("git/odb/pack: too short fanout table")

	// indexHeader is the first four "magic" bytes of index files version 2
	// or newer.
	indexHeader = []byte{0xff, 0x74, 0x4f, 0x63}
)

// DecodeIndex decodes an index whose underlying data is supplied by "r".
//
// DecodeIndex reads only the header and fanout table, and does not eagerly
// parse index entries.
//
// If there was an error parsing, it will be returned immediately.
func DecodeIndex(r io.ReaderAt) (*Index, error) {
	version, err := decodeIndexHeader(r)
	if err != nil {
		return nil, err
	}

	fanout, err := decodeIndexFanout(r, version.Width())
	if err != nil {
		return nil, err
	}

	return &Index{
		version: version,
		fanout:  fanout,

		f: r,
	}, nil
}

// decodeIndexHeader determines which version the index given by "r" is.
func decodeIndexHeader(r io.ReaderAt) (IndexVersion, error) {
	hdr := make([]byte, 4)
	if _, err := r.ReadAt(hdr, 0); err != nil {
		return VersionUnknown, err
	}

	if bytes.Equal(hdr, indexHeader) {
		vb := make([]byte, 4)
		if _, err := r.ReadAt(vb, 4); err != nil {
			return VersionUnknown, err
		}

		version := IndexVersion(binary.BigEndian.Uint32(vb))

		return version, &UnsupportedVersionErr{uint32(version)}
	}
	return IndexVersion(0), nil
}

// decodeIndexFanout decodes the fanout table given by "r" and beginning at the
// given offset.
func decodeIndexFanout(r io.ReaderAt, offset int64) ([]uint32, error) {
	b := make([]byte, 256*4)
	if _, err := r.ReadAt(b, offset); err != nil {
		if err == io.EOF {
			return nil, ErrShortFanout
		}
		return nil, err
	}

	fanout := make([]uint32, 256)
	for i, _ := range fanout {
		fanout[i] = binary.BigEndian.Uint32(b[(i * 4):])
	}

	return fanout, nil
}
<|endoftext|>


<commit_before>package eparser

import (
	"testing"
)

func TestLex(t *testing.T) {
	l := newLexer()
	res, errs := l.Lex("a **= (7 ** (3 + 4 - 2)) << 1.23 % 0.3")
	expected := []tokenType{
		IDENT, POW_EQ, LPAREN, INT, POW, LPAREN, INT, ADD, INT, SUB, INT,
		RPAREN, RPAREN, LSH, FLOAT, REM, FLOAT, EOL,
	}

	if errs != nil {
		t.Error("lexer error(s) found")
	}

	for k, v := range res {
		if expected[k] != v.Type {
			t.Error("mismatched token")
		}
	}
}

func TestUTF8(t *testing.T) {
	if !isIdent('Å') || !isIdent('Ś') {
		t.Error("isIdent doesn't recognize unicode characters")
	}
}
<commit_msg>Test identifier reader inside lexer test<commit_after>package eparser

import (
	"testing"
)

func TestLex(t *testing.T) {
	l := newLexer()
	res, errs := l.Lex("some_var123 **= (7 ** (3 + 4 - 2)) << 1.23 % 0.3")
	expected := []tokenType{
		IDENT, POW_EQ, LPAREN, INT, POW, LPAREN, INT, ADD, INT, SUB, INT,
		RPAREN, RPAREN, LSH, FLOAT, REM, FLOAT, EOL,
	}

	if errs != nil {
		t.Error("lexer error(s) found")
	}

	for k, v := range res {
		if expected[k] != v.Type {
			t.Error("mismatched token")
		}
	}
}

func TestUTF8(t *testing.T) {
	if !isIdent('Å') || !isIdent('Ś') {
		t.Error("isIdent doesn't recognize unicode characters")
	}
}
<|endoftext|>


<commit_before>package lfs

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/cheggaaa/pb"
	"github.com/rubyist/tracerx"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
)

const (
	mediaType = "application/vnd.git-lfs+json; charset-utf-8"
)

var (
	lfsMediaTypeRE             = regexp.MustCompile(`\Aapplication/vnd\.git\-lfs\+json(;|\z)`)
	jsonMediaTypeRE            = regexp.MustCompile(`\Aapplication/json(;|\z)`)
	objectRelationDoesNotExist = errors.New("relation does not exist")
	hiddenHeaders              = map[string]bool{
		"Authorization": true,
	}

	// 401 and 403 print the same default error message
	defaultErrors = map[int]string{
		400: "Client error: %s",
		401: "Authorization error: %s\nCheck that you have proper access to the repository",
		404: "Repository or object not found: %s\nCheck that it exists and that you have proper access to it",
		500: "Server error: %s",
	}
)

type objectResource struct {
	Oid   string                   `json:"oid,omitempty"`
	Size  int64                    `json:"size,omitempty"`
	Links map[string]*linkRelation `json:"_links,omitempty"`
}

func (o *objectResource) NewRequest(relation, method string) (*http.Request, Creds, error) {
	rel, ok := o.Rel(relation)
	if !ok {
		return nil, nil, objectRelationDoesNotExist
	}

	req, creds, err := newClientRequest(method, rel.Href)
	if err != nil {
		return nil, nil, err
	}

	for h, v := range rel.Header {
		req.Header.Set(h, v)
	}

	return req, creds, nil
}

func (o *objectResource) Rel(name string) (*linkRelation, bool) {
	if o.Links == nil {
		return nil, false
	}

	rel, ok := o.Links[name]
	return rel, ok
}

type linkRelation struct {
	Href   string            `json:"href"`
	Header map[string]string `json:"header,omitempty"`
}

type ClientError struct {
	Message          string `json:"message"`
	DocumentationUrl string `json:"documentation_url,omitempty"`
	RequestId        string `json:"request_id,omitempty"`
}

func (e *ClientError) Error() string {
	msg := e.Message
	if len(e.DocumentationUrl) > 0 {
		msg += "\nDocs: " + e.DocumentationUrl
	}
	if len(e.RequestId) > 0 {
		msg += "\nRequest ID: " + e.RequestId
	}
	return msg
}

func Download(oid string) (io.ReadCloser, int64, *WrappedError) {
	req, creds, err := newApiRequest("GET", oid)
	if err != nil {
		return nil, 0, Error(err)
	}

	res, obj, wErr := doApiRequest(req, creds)
	if wErr != nil {
		return nil, 0, wErr
	}

	req, creds, err = obj.NewRequest("download", "GET")
	if err != nil {
		return nil, 0, Error(err)
	}

	res, wErr = doHttpRequest(req, creds)
	if wErr != nil {
		return nil, 0, wErr
	}

	return res.Body, res.ContentLength, nil
}

type byteCloser struct {
	*bytes.Reader
}

func (b *byteCloser) Close() error {
	return nil
}

func Upload(oidPath, filename string, cb CopyCallback) *WrappedError {
	oid := filepath.Base(oidPath)
	file, err := os.Open(oidPath)
	if err != nil {
		return Error(err)
	}
	defer file.Close()

	stat, err := file.Stat()
	if err != nil {
		return Error(err)
	}

	reqObj := &objectResource{
		Oid:  oid,
		Size: stat.Size(),
	}

	by, err := json.Marshal(reqObj)
	if err != nil {
		return Error(err)
	}

	req, creds, err := newApiRequest("POST", "")
	if err != nil {
		return Error(err)
	}

	req.Header.Set("Content-Type", mediaType)
	req.Header.Set("Content-Length", strconv.Itoa(len(by)))
	req.ContentLength = int64(len(by))
	req.Body = &byteCloser{bytes.NewReader(by)}

	tracerx.Printf("api: uploading %s (%s)", filename, oid)
	res, obj, wErr := doApiRequest(req, creds)
	if wErr != nil {
		return wErr
	}

	if res.StatusCode == 200 {
		return nil
	}

	req, creds, err = obj.NewRequest("upload", "PUT")
	if err != nil {
		return Error(err)
	}

	if len(req.Header.Get("Content-Type")) == 0 {
		req.Header.Set("Content-Type", "application/octet-stream")
	}
	req.Header.Set("Content-Length", strconv.FormatInt(reqObj.Size, 10))
	req.ContentLength = reqObj.Size

	reader := &CallbackReader{
		C:         cb,
		TotalSize: reqObj.Size,
		Reader:    file,
	}

	bar := pb.New64(reqObj.Size)
	bar.SetUnits(pb.U_BYTES)
	bar.Start()

	req.Body = ioutil.NopCloser(bar.NewProxyReader(reader))

	res, wErr = doHttpRequest(req, creds)
	if wErr != nil {
		return wErr
	}

	if res.StatusCode > 299 {
		return Errorf(nil, "Invalid status for %s %s: %d", req.Method, req.URL, res.StatusCode)
	}

	io.Copy(ioutil.Discard, res.Body)
	res.Body.Close()

	req, creds, err = obj.NewRequest("verify", "POST")
	if err == objectRelationDoesNotExist {
		return nil
	} else if err != nil {
		return Error(err)
	}

	req.Header.Set("Content-Type", mediaType)
	req.Header.Set("Content-Length", strconv.Itoa(len(by)))
	req.ContentLength = int64(len(by))
	req.Body = ioutil.NopCloser(bytes.NewReader(by))
	res, wErr = doHttpRequest(req, creds)

	io.Copy(ioutil.Discard, res.Body)
	res.Body.Close()

	return wErr
}

func doHttpRequest(req *http.Request, creds Creds) (*http.Response, *WrappedError) {
	res, err := DoHTTP(Config, req)

	var wErr *WrappedError

	if err != nil {
		wErr = Errorf(err, "Error for %s %s", res.Request.Method, res.Request.URL)
	} else {
		if creds != nil {
			saveCredentials(creds, res)
		}

		wErr = handleResponse(res)
	}

	if wErr != nil {
		if res != nil {
			setErrorResponseContext(wErr, res)
		} else {
			setErrorRequestContext(wErr, req)
		}
	}

	return res, wErr
}

func doApiRequestWithRedirects(req *http.Request, creds Creds, via []*http.Request) (*http.Response, *WrappedError) {
	fmt.Println("doApiRequest:", req)
	res, wErr := doHttpRequest(req, creds)
	if wErr != nil {
		return res, wErr
	}

	if res.StatusCode == 307 {
		redirectedReq, redirectedCreds, err := newClientRequest(req.Method, res.Header.Get("Location"))
		if err != nil {
			return res, Errorf(err, err.Error())
		}

		via = append(via, req)
		fmt.Println("via:", via)
		if seeker, ok := req.Body.(io.Seeker); ok {
			_, err := seeker.Seek(0, 0)
			if err != nil {
				return res, Error(err)
			}
			redirectedReq.Body = req.Body
			redirectedReq.ContentLength = req.ContentLength
		} else {
			return res, Errorf(nil, "Request body needs to be an io.Seeker to handle redirects.")
		}

		if err = checkRedirect(redirectedReq, via); err != nil {
			return res, Errorf(err, err.Error())
		}

		return doApiRequestWithRedirects(redirectedReq, redirectedCreds, via)
	}

	return res, wErr
}

func doApiRequest(req *http.Request, creds Creds) (*http.Response, *objectResource, *WrappedError) {
	via := make([]*http.Request, 0, 4)
	res, wErr := doApiRequestWithRedirects(req, creds, via)
	if wErr != nil {
		return res, nil, wErr
	}

	obj := &objectResource{}
	wErr = decodeApiResponse(res, obj)

	if wErr != nil {
		setErrorResponseContext(wErr, res)
	}

	return res, obj, wErr
}

func handleResponse(res *http.Response) *WrappedError {
	if res.StatusCode < 400 {
		return nil
	}

	defer func() {
		io.Copy(ioutil.Discard, res.Body)
		res.Body.Close()
	}()

	cliErr := &ClientError{}
	wErr := decodeApiResponse(res, cliErr)
	if wErr == nil {
		if len(cliErr.Message) == 0 {
			wErr = defaultError(res)
		} else {
			wErr = Error(cliErr)
		}
	}

	wErr.Panic = res.StatusCode > 499 && res.StatusCode != 501 && res.StatusCode != 509
	return wErr
}

func decodeApiResponse(res *http.Response, obj interface{}) *WrappedError {
	ctype := res.Header.Get("Content-Type")
	if !(lfsMediaTypeRE.MatchString(ctype) || jsonMediaTypeRE.MatchString(ctype)) {
		return nil
	}

	err := json.NewDecoder(res.Body).Decode(obj)
	io.Copy(ioutil.Discard, res.Body)
	res.Body.Close()

	if err != nil {
		return Errorf(err, "Unable to parse HTTP response for %s %s", res.Request.Method, res.Request.URL)
	}

	return nil
}

func defaultError(res *http.Response) *WrappedError {
	var msgFmt string

	if f, ok := defaultErrors[res.StatusCode]; ok {
		msgFmt = f
	} else if res.StatusCode < 500 {
		msgFmt = defaultErrors[400] + fmt.Sprintf(" from HTTP %d", res.StatusCode)
	} else {
		msgFmt = defaultErrors[500] + fmt.Sprintf(" from HTTP %d", res.StatusCode)
	}

	return Error(fmt.Errorf(msgFmt, res.Request.URL))
}

func saveCredentials(creds Creds, res *http.Response) {
	if creds == nil {
		return
	}

	if res.StatusCode < 300 {
		execCreds(creds, "approve")
	} else if res.StatusCode == 401 {
		execCreds(creds, "reject")
	}
}

func newApiRequest(method, oid string) (*http.Request, Creds, error) {
	u, err := Config.ObjectUrl(oid)
	if err != nil {
		return nil, nil, err
	}

	req, creds, err := newClientRequest(method, u.String())
	if err == nil {
		req.Header.Set("Accept", mediaType)
	}
	return req, creds, err
}

func newClientRequest(method, rawurl string) (*http.Request, Creds, error) {
	req, err := http.NewRequest(method, rawurl, nil)
	if err != nil {
		return req, nil, err
	}

	req.Header.Set("User-Agent", UserAgent)
	creds, err := getCreds(req)
	return req, creds, err
}

func getCreds(req *http.Request) (Creds, error) {
	if len(req.Header.Get("Authorization")) > 0 {
		return nil, nil
	}

	apiUrl, err := Config.ObjectUrl("")
	if err != nil {
		return nil, err
	}

	if req.URL.Scheme == apiUrl.Scheme &&
		req.URL.Host == apiUrl.Host {
		creds, err := credentials(req.URL)
		if err != nil {
			return nil, err
		}

		token := fmt.Sprintf("%s:%s", creds["username"], creds["password"])
		auth := "Basic " + base64.URLEncoding.EncodeToString([]byte(token))
		req.Header.Set("Authorization", auth)
		return creds, nil
	}

	return nil, nil
}

func setErrorRequestContext(err *WrappedError, req *http.Request) {
	err.Set("Endpoint", Config.Endpoint())
	err.Set("URL", fmt.Sprintf("%s %s", req.Method, req.URL.String()))
	setErrorHeaderContext(err, "Response", req.Header)
}

func setErrorResponseContext(err *WrappedError, res *http.Response) {
	err.Set("Status", res.Status)
	setErrorHeaderContext(err, "Request", res.Header)
	setErrorRequestContext(err, res.Request)
}

func setErrorHeaderContext(err *WrappedError, prefix string, head http.Header) {
	for key, _ := range head {
		contextKey := fmt.Sprintf("%s:%s", prefix, key)
		if _, skip := hiddenHeaders[key]; skip {
			err.Set(contextKey, "--")
		} else {
			err.Set(contextKey, head.Get(key))
		}
	}
}

func init() {
	defaultErrors[403] = defaultErrors[401]
}
<commit_msg>ラララララ ラー ウウウ フフフ<commit_after>package lfs

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/cheggaaa/pb"
	"github.com/rubyist/tracerx"
	"io"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
)

const (
	mediaType = "application/vnd.git-lfs+json; charset-utf-8"
)

var (
	lfsMediaTypeRE             = regexp.MustCompile(`\Aapplication/vnd\.git\-lfs\+json(;|\z)`)
	jsonMediaTypeRE            = regexp.MustCompile(`\Aapplication/json(;|\z)`)
	objectRelationDoesNotExist = errors.New("relation does not exist")
	hiddenHeaders              = map[string]bool{
		"Authorization": true,
	}

	// 401 and 403 print the same default error message
	defaultErrors = map[int]string{
		400: "Client error: %s",
		401: "Authorization error: %s\nCheck that you have proper access to the repository",
		404: "Repository or object not found: %s\nCheck that it exists and that you have proper access to it",
		500: "Server error: %s",
	}
)

type objectResource struct {
	Oid   string                   `json:"oid,omitempty"`
	Size  int64                    `json:"size,omitempty"`
	Links map[string]*linkRelation `json:"_links,omitempty"`
}

func (o *objectResource) NewRequest(relation, method string) (*http.Request, Creds, error) {
	rel, ok := o.Rel(relation)
	if !ok {
		return nil, nil, objectRelationDoesNotExist
	}

	req, creds, err := newClientRequest(method, rel.Href)
	if err != nil {
		return nil, nil, err
	}

	for h, v := range rel.Header {
		req.Header.Set(h, v)
	}

	return req, creds, nil
}

func (o *objectResource) Rel(name string) (*linkRelation, bool) {
	if o.Links == nil {
		return nil, false
	}

	rel, ok := o.Links[name]
	return rel, ok
}

type linkRelation struct {
	Href   string            `json:"href"`
	Header map[string]string `json:"header,omitempty"`
}

type ClientError struct {
	Message          string `json:"message"`
	DocumentationUrl string `json:"documentation_url,omitempty"`
	RequestId        string `json:"request_id,omitempty"`
}

func (e *ClientError) Error() string {
	msg := e.Message
	if len(e.DocumentationUrl) > 0 {
		msg += "\nDocs: " + e.DocumentationUrl
	}
	if len(e.RequestId) > 0 {
		msg += "\nRequest ID: " + e.RequestId
	}
	return msg
}

func Download(oid string) (io.ReadCloser, int64, *WrappedError) {
	req, creds, err := newApiRequest("GET", oid)
	if err != nil {
		return nil, 0, Error(err)
	}

	res, obj, wErr := doApiRequest(req, creds)
	if wErr != nil {
		return nil, 0, wErr
	}

	req, creds, err = obj.NewRequest("download", "GET")
	if err != nil {
		return nil, 0, Error(err)
	}

	res, wErr = doHttpRequest(req, creds)
	if wErr != nil {
		return nil, 0, wErr
	}

	return res.Body, res.ContentLength, nil
}

type byteCloser struct {
	*bytes.Reader
}

func (b *byteCloser) Close() error {
	return nil
}

func Upload(oidPath, filename string, cb CopyCallback) *WrappedError {
	oid := filepath.Base(oidPath)
	file, err := os.Open(oidPath)
	if err != nil {
		return Error(err)
	}
	defer file.Close()

	stat, err := file.Stat()
	if err != nil {
		return Error(err)
	}

	reqObj := &objectResource{
		Oid:  oid,
		Size: stat.Size(),
	}

	by, err := json.Marshal(reqObj)
	if err != nil {
		return Error(err)
	}

	req, creds, err := newApiRequest("POST", "")
	if err != nil {
		return Error(err)
	}

	req.Header.Set("Content-Type", mediaType)
	req.Header.Set("Content-Length", strconv.Itoa(len(by)))
	req.ContentLength = int64(len(by))
	req.Body = &byteCloser{bytes.NewReader(by)}

	tracerx.Printf("api: uploading %s (%s)", filename, oid)
	res, obj, wErr := doApiRequest(req, creds)
	if wErr != nil {
		return wErr
	}

	if res.StatusCode == 200 {
		return nil
	}

	req, creds, err = obj.NewRequest("upload", "PUT")
	if err != nil {
		return Error(err)
	}

	if len(req.Header.Get("Content-Type")) == 0 {
		req.Header.Set("Content-Type", "application/octet-stream")
	}
	req.Header.Set("Content-Length", strconv.FormatInt(reqObj.Size, 10))
	req.ContentLength = reqObj.Size

	reader := &CallbackReader{
		C:         cb,
		TotalSize: reqObj.Size,
		Reader:    file,
	}

	bar := pb.New64(reqObj.Size)
	bar.SetUnits(pb.U_BYTES)
	bar.Start()

	req.Body = ioutil.NopCloser(bar.NewProxyReader(reader))

	res, wErr = doHttpRequest(req, creds)
	if wErr != nil {
		return wErr
	}

	if res.StatusCode > 299 {
		return Errorf(nil, "Invalid status for %s %s: %d", req.Method, req.URL, res.StatusCode)
	}

	io.Copy(ioutil.Discard, res.Body)
	res.Body.Close()

	req, creds, err = obj.NewRequest("verify", "POST")
	if err == objectRelationDoesNotExist {
		return nil
	} else if err != nil {
		return Error(err)
	}

	req.Header.Set("Content-Type", mediaType)
	req.Header.Set("Content-Length", strconv.Itoa(len(by)))
	req.ContentLength = int64(len(by))
	req.Body = ioutil.NopCloser(bytes.NewReader(by))
	res, wErr = doHttpRequest(req, creds)

	io.Copy(ioutil.Discard, res.Body)
	res.Body.Close()

	return wErr
}

func doHttpRequest(req *http.Request, creds Creds) (*http.Response, *WrappedError) {
	res, err := DoHTTP(Config, req)

	var wErr *WrappedError

	if err != nil {
		wErr = Errorf(err, "Error for %s %s", res.Request.Method, res.Request.URL)
	} else {
		if creds != nil {
			saveCredentials(creds, res)
		}

		wErr = handleResponse(res)
	}

	if wErr != nil {
		if res != nil {
			setErrorResponseContext(wErr, res)
		} else {
			setErrorRequestContext(wErr, req)
		}
	}

	return res, wErr
}

func doApiRequestWithRedirects(req *http.Request, creds Creds, via []*http.Request) (*http.Response, *WrappedError) {
	res, wErr := doHttpRequest(req, creds)
	if wErr != nil {
		return res, wErr
	}

	if res.StatusCode == 307 {
		redirectedReq, redirectedCreds, err := newClientRequest(req.Method, res.Header.Get("Location"))
		if err != nil {
			return res, Errorf(err, err.Error())
		}

		via = append(via, req)
		if seeker, ok := req.Body.(io.Seeker); ok {
			_, err := seeker.Seek(0, 0)
			if err != nil {
				return res, Error(err)
			}
			redirectedReq.Body = req.Body
			redirectedReq.ContentLength = req.ContentLength
		} else {
			return res, Errorf(nil, "Request body needs to be an io.Seeker to handle redirects.")
		}

		if err = checkRedirect(redirectedReq, via); err != nil {
			return res, Errorf(err, err.Error())
		}

		return doApiRequestWithRedirects(redirectedReq, redirectedCreds, via)
	}

	return res, wErr
}

func doApiRequest(req *http.Request, creds Creds) (*http.Response, *objectResource, *WrappedError) {
	via := make([]*http.Request, 0, 4)
	res, wErr := doApiRequestWithRedirects(req, creds, via)
	if wErr != nil {
		return res, nil, wErr
	}

	obj := &objectResource{}
	wErr = decodeApiResponse(res, obj)

	if wErr != nil {
		setErrorResponseContext(wErr, res)
	}

	return res, obj, wErr
}

func handleResponse(res *http.Response) *WrappedError {
	if res.StatusCode < 400 {
		return nil
	}

	defer func() {
		io.Copy(ioutil.Discard, res.Body)
		res.Body.Close()
	}()

	cliErr := &ClientError{}
	wErr := decodeApiResponse(res, cliErr)
	if wErr == nil {
		if len(cliErr.Message) == 0 {
			wErr = defaultError(res)
		} else {
			wErr = Error(cliErr)
		}
	}

	wErr.Panic = res.StatusCode > 499 && res.StatusCode != 501 && res.StatusCode != 509
	return wErr
}

func decodeApiResponse(res *http.Response, obj interface{}) *WrappedError {
	ctype := res.Header.Get("Content-Type")
	if !(lfsMediaTypeRE.MatchString(ctype) || jsonMediaTypeRE.MatchString(ctype)) {
		return nil
	}

	err := json.NewDecoder(res.Body).Decode(obj)
	io.Copy(ioutil.Discard, res.Body)
	res.Body.Close()

	if err != nil {
		return Errorf(err, "Unable to parse HTTP response for %s %s", res.Request.Method, res.Request.URL)
	}

	return nil
}

func defaultError(res *http.Response) *WrappedError {
	var msgFmt string

	if f, ok := defaultErrors[res.StatusCode]; ok {
		msgFmt = f
	} else if res.StatusCode < 500 {
		msgFmt = defaultErrors[400] + fmt.Sprintf(" from HTTP %d", res.StatusCode)
	} else {
		msgFmt = defaultErrors[500] + fmt.Sprintf(" from HTTP %d", res.StatusCode)
	}

	return Error(fmt.Errorf(msgFmt, res.Request.URL))
}

func saveCredentials(creds Creds, res *http.Response) {
	if creds == nil {
		return
	}

	if res.StatusCode < 300 {
		execCreds(creds, "approve")
	} else if res.StatusCode == 401 {
		execCreds(creds, "reject")
	}
}

func newApiRequest(method, oid string) (*http.Request, Creds, error) {
	u, err := Config.ObjectUrl(oid)
	if err != nil {
		return nil, nil, err
	}

	req, creds, err := newClientRequest(method, u.String())
	if err == nil {
		req.Header.Set("Accept", mediaType)
	}
	return req, creds, err
}

func newClientRequest(method, rawurl string) (*http.Request, Creds, error) {
	req, err := http.NewRequest(method, rawurl, nil)
	if err != nil {
		return req, nil, err
	}

	req.Header.Set("User-Agent", UserAgent)
	creds, err := getCreds(req)
	return req, creds, err
}

func getCreds(req *http.Request) (Creds, error) {
	if len(req.Header.Get("Authorization")) > 0 {
		return nil, nil
	}

	apiUrl, err := Config.ObjectUrl("")
	if err != nil {
		return nil, err
	}

	if req.URL.Scheme == apiUrl.Scheme &&
		req.URL.Host == apiUrl.Host {
		creds, err := credentials(req.URL)
		if err != nil {
			return nil, err
		}

		token := fmt.Sprintf("%s:%s", creds["username"], creds["password"])
		auth := "Basic " + base64.URLEncoding.EncodeToString([]byte(token))
		req.Header.Set("Authorization", auth)
		return creds, nil
	}

	return nil, nil
}

func setErrorRequestContext(err *WrappedError, req *http.Request) {
	err.Set("Endpoint", Config.Endpoint())
	err.Set("URL", fmt.Sprintf("%s %s", req.Method, req.URL.String()))
	setErrorHeaderContext(err, "Response", req.Header)
}

func setErrorResponseContext(err *WrappedError, res *http.Response) {
	err.Set("Status", res.Status)
	setErrorHeaderContext(err, "Request", res.Header)
	setErrorRequestContext(err, res.Request)
}

func setErrorHeaderContext(err *WrappedError, prefix string, head http.Header) {
	for key, _ := range head {
		contextKey := fmt.Sprintf("%s:%s", prefix, key)
		if _, skip := hiddenHeaders[key]; skip {
			err.Set(contextKey, "--")
		} else {
			err.Set(contextKey, head.Get(key))
		}
	}
}

func init() {
	defaultErrors[403] = defaultErrors[401]
}
<|endoftext|>


<commit_before>// Copyright 2016 The go-github 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 github

import (
	"context"
	"fmt"
	"net/http"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
)

func TestRepositoriesService_ListTrafficReferrers(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	mux.HandleFunc("/repos/o/r/traffic/popular/referrers", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		fmt.Fprintf(w, `[{
			"referrer": "Google",
			"count": 4,
			"uniques": 3
 		}]`)
	})
	ctx := context.Background()
	got, _, err := client.Repositories.ListTrafficReferrers(ctx, "o", "r")
	if err != nil {
		t.Errorf("Repositories.ListTrafficReferrers returned error: %+v", err)
	}

	want := []*TrafficReferrer{{
		Referrer: String("Google"),
		Count:    Int(4),
		Uniques:  Int(3),
	}}
	if !cmp.Equal(got, want) {
		t.Errorf("Repositories.ListTrafficReferrers returned %+v, want %+v", got, want)
	}

	const methodName = "ListTrafficReferrers"
	testBadOptions(t, methodName, func() (err error) {
		_, _, err = client.Repositories.ListTrafficReferrers(ctx, "\n", "\n")
		return err
	})

	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
		got, resp, err := client.Repositories.ListTrafficReferrers(ctx, "o", "r")
		if got != nil {
			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
		}
		return resp, err
	})
}

func TestRepositoriesService_ListTrafficPaths(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	mux.HandleFunc("/repos/o/r/traffic/popular/paths", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		fmt.Fprintf(w, `[{
			"path": "/github/hubot",
			"title": "github/hubot: A customizable life embetterment robot.",
			"count": 3542,
			"uniques": 2225
 		}]`)
	})
	ctx := context.Background()
	got, _, err := client.Repositories.ListTrafficPaths(ctx, "o", "r")
	if err != nil {
		t.Errorf("Repositories.ListTrafficPaths returned error: %+v", err)
	}

	want := []*TrafficPath{{
		Path:    String("/github/hubot"),
		Title:   String("github/hubot: A customizable life embetterment robot."),
		Count:   Int(3542),
		Uniques: Int(2225),
	}}
	if !cmp.Equal(got, want) {
		t.Errorf("Repositories.ListTrafficPaths returned %+v, want %+v", got, want)
	}

	const methodName = "ListTrafficPaths"
	testBadOptions(t, methodName, func() (err error) {
		_, _, err = client.Repositories.ListTrafficPaths(ctx, "\n", "\n")
		return err
	})

	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
		got, resp, err := client.Repositories.ListTrafficPaths(ctx, "o", "r")
		if got != nil {
			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
		}
		return resp, err
	})
}

func TestRepositoriesService_ListTrafficViews(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	mux.HandleFunc("/repos/o/r/traffic/views", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		fmt.Fprintf(w, `{"count": 7,
			"uniques": 6,
			"views": [{
				"timestamp": "2016-05-31T16:00:00.000Z",
				"count": 7,
				"uniques": 6
		}]}`)
	})

	ctx := context.Background()
	got, _, err := client.Repositories.ListTrafficViews(ctx, "o", "r", nil)
	if err != nil {
		t.Errorf("Repositories.ListTrafficViews returned error: %+v", err)
	}

	want := &TrafficViews{
		Views: []*TrafficData{{
			Timestamp: &Timestamp{time.Date(2016, time.May, 31, 16, 0, 0, 0, time.UTC)},
			Count:     Int(7),
			Uniques:   Int(6),
		}},
		Count:   Int(7),
		Uniques: Int(6),
	}

	if !cmp.Equal(got, want) {
		t.Errorf("Repositories.ListTrafficViews returned %+v, want %+v", got, want)
	}

	const methodName = "ListTrafficViews"
	testBadOptions(t, methodName, func() (err error) {
		_, _, err = client.Repositories.ListTrafficViews(ctx, "\n", "\n", &TrafficBreakdownOptions{})
		return err
	})

	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
		got, resp, err := client.Repositories.ListTrafficViews(ctx, "o", "r", nil)
		if got != nil {
			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
		}
		return resp, err
	})
}

func TestRepositoriesService_ListTrafficClones(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	mux.HandleFunc("/repos/o/r/traffic/clones", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		fmt.Fprintf(w, `{"count": 7,
			"uniques": 6,
			"clones": [{
				"timestamp": "2016-05-31T16:00:00.00Z",
				"count": 7,
				"uniques": 6
		}]}`)
	})

	ctx := context.Background()
	got, _, err := client.Repositories.ListTrafficClones(ctx, "o", "r", nil)
	if err != nil {
		t.Errorf("Repositories.ListTrafficClones returned error: %+v", err)
	}

	want := &TrafficClones{
		Clones: []*TrafficData{{
			Timestamp: &Timestamp{time.Date(2016, time.May, 31, 16, 0, 0, 0, time.UTC)},
			Count:     Int(7),
			Uniques:   Int(6),
		}},
		Count:   Int(7),
		Uniques: Int(6),
	}

	if !cmp.Equal(got, want) {
		t.Errorf("Repositories.ListTrafficClones returned %+v, want %+v", got, want)
	}

	const methodName = "ListTrafficClones"
	testBadOptions(t, methodName, func() (err error) {
		_, _, err = client.Repositories.ListTrafficClones(ctx, "\n", "\n", &TrafficBreakdownOptions{})
		return err
	})

	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
		got, resp, err := client.Repositories.ListTrafficClones(ctx, "o", "r", nil)
		if got != nil {
			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
		}
		return resp, err
	})
}

func TestTrafficReferrer_Marshal(t *testing.T) {
	testJSONMarshal(t, &TrafficReferrer{}, "{}")

	u := &TrafficReferrer{
		Referrer: String("referrer"),
		Count:    Int(0),
		Uniques:  Int(0),
	}

	want := `{
		"referrer" : "referrer",
		"count" : 0,
		"uniques" : 0
	}`

	testJSONMarshal(t, u, want)
}

func TestTrafficViews_Marshal(t *testing.T) {
	testJSONMarshal(t, &TrafficViews{}, "{}")

	u := &TrafficViews{
		Views: []*TrafficData{{
			Timestamp: &Timestamp{time.Date(2016, time.May, 31, 16, 0, 0, 0, time.UTC)},
			Count:     Int(7),
			Uniques:   Int(6),
		}},
		Count:   Int(0),
		Uniques: Int(0),
	}

	want := `{
		"views": [{
			"timestamp": "2016-05-31T16:00:00.000Z",
			"count": 7,
			"uniques": 6
		}],
		"count" : 0,
		"uniques" : 0
	}`

	testJSONMarshal(t, u, want)
}

func TestTrafficClones_Marshal(t *testing.T) {
	testJSONMarshal(t, &TrafficClones{}, "{}")

	u := &TrafficClones{
		Clones: []*TrafficData{{
			Timestamp: &Timestamp{time.Date(2021, time.October, 29, 16, 0, 0, 0, time.UTC)},
			Count:     Int(1),
			Uniques:   Int(1),
		}},
		Count:   Int(0),
		Uniques: Int(0),
	}

	want := `{
		"clones": [{
			"timestamp": "2021-10-29T16:00:00.000Z",
			"count": 1,
			"uniques": 1
		}],
		"count" : 0,
		"uniques" : 0
	}`

	testJSONMarshal(t, u, want)
}

func TestTrafficPath_Marshal(t *testing.T) {
	testJSONMarshal(t, &TrafficPath{}, "{}")

	u := &TrafficPath{
		Path:    String("test/path"),
		Title:   String("test"),
		Count:   Int(2),
		Uniques: Int(3),
	}

	want := `{
		"path" : "test/path",
		"title": "test",
		"count": 2,
		"uniques": 3
	}`

	testJSONMarshal(t, u, want)
}

func TestTrafficData_Marshal(t *testing.T) {
	testJSONMarshal(t, &TrafficData{}, "{}")

	u := &TrafficData{
		Timestamp: &Timestamp{time.Date(2016, time.May, 31, 16, 0, 0, 0, time.UTC)},
		Count:     Int(7),
		Uniques:   Int(6),
	}

	want := `{
			"timestamp": "2016-05-31T16:00:00.000Z",
			"count": 7,
			"uniques": 6
      }`

	testJSONMarshal(t, u, want)
}
<commit_msg>Add test for resource JSON marshaling (#2538)<commit_after>// Copyright 2016 The go-github 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 github

import (
	"context"
	"fmt"
	"net/http"
	"testing"
	"time"

	"github.com/google/go-cmp/cmp"
)

func TestRepositoriesService_ListTrafficReferrers(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	mux.HandleFunc("/repos/o/r/traffic/popular/referrers", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		fmt.Fprintf(w, `[{
			"referrer": "Google",
			"count": 4,
			"uniques": 3
 		}]`)
	})
	ctx := context.Background()
	got, _, err := client.Repositories.ListTrafficReferrers(ctx, "o", "r")
	if err != nil {
		t.Errorf("Repositories.ListTrafficReferrers returned error: %+v", err)
	}

	want := []*TrafficReferrer{{
		Referrer: String("Google"),
		Count:    Int(4),
		Uniques:  Int(3),
	}}
	if !cmp.Equal(got, want) {
		t.Errorf("Repositories.ListTrafficReferrers returned %+v, want %+v", got, want)
	}

	const methodName = "ListTrafficReferrers"
	testBadOptions(t, methodName, func() (err error) {
		_, _, err = client.Repositories.ListTrafficReferrers(ctx, "\n", "\n")
		return err
	})

	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
		got, resp, err := client.Repositories.ListTrafficReferrers(ctx, "o", "r")
		if got != nil {
			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
		}
		return resp, err
	})
}

func TestRepositoriesService_ListTrafficPaths(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	mux.HandleFunc("/repos/o/r/traffic/popular/paths", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		fmt.Fprintf(w, `[{
			"path": "/github/hubot",
			"title": "github/hubot: A customizable life embetterment robot.",
			"count": 3542,
			"uniques": 2225
 		}]`)
	})
	ctx := context.Background()
	got, _, err := client.Repositories.ListTrafficPaths(ctx, "o", "r")
	if err != nil {
		t.Errorf("Repositories.ListTrafficPaths returned error: %+v", err)
	}

	want := []*TrafficPath{{
		Path:    String("/github/hubot"),
		Title:   String("github/hubot: A customizable life embetterment robot."),
		Count:   Int(3542),
		Uniques: Int(2225),
	}}
	if !cmp.Equal(got, want) {
		t.Errorf("Repositories.ListTrafficPaths returned %+v, want %+v", got, want)
	}

	const methodName = "ListTrafficPaths"
	testBadOptions(t, methodName, func() (err error) {
		_, _, err = client.Repositories.ListTrafficPaths(ctx, "\n", "\n")
		return err
	})

	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
		got, resp, err := client.Repositories.ListTrafficPaths(ctx, "o", "r")
		if got != nil {
			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
		}
		return resp, err
	})
}

func TestRepositoriesService_ListTrafficViews(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	mux.HandleFunc("/repos/o/r/traffic/views", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		fmt.Fprintf(w, `{"count": 7,
			"uniques": 6,
			"views": [{
				"timestamp": "2016-05-31T16:00:00.000Z",
				"count": 7,
				"uniques": 6
		}]}`)
	})

	ctx := context.Background()
	got, _, err := client.Repositories.ListTrafficViews(ctx, "o", "r", nil)
	if err != nil {
		t.Errorf("Repositories.ListTrafficViews returned error: %+v", err)
	}

	want := &TrafficViews{
		Views: []*TrafficData{{
			Timestamp: &Timestamp{time.Date(2016, time.May, 31, 16, 0, 0, 0, time.UTC)},
			Count:     Int(7),
			Uniques:   Int(6),
		}},
		Count:   Int(7),
		Uniques: Int(6),
	}

	if !cmp.Equal(got, want) {
		t.Errorf("Repositories.ListTrafficViews returned %+v, want %+v", got, want)
	}

	const methodName = "ListTrafficViews"
	testBadOptions(t, methodName, func() (err error) {
		_, _, err = client.Repositories.ListTrafficViews(ctx, "\n", "\n", &TrafficBreakdownOptions{})
		return err
	})

	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
		got, resp, err := client.Repositories.ListTrafficViews(ctx, "o", "r", nil)
		if got != nil {
			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
		}
		return resp, err
	})
}

func TestRepositoriesService_ListTrafficClones(t *testing.T) {
	client, mux, _, teardown := setup()
	defer teardown()

	mux.HandleFunc("/repos/o/r/traffic/clones", func(w http.ResponseWriter, r *http.Request) {
		testMethod(t, r, "GET")
		fmt.Fprintf(w, `{"count": 7,
			"uniques": 6,
			"clones": [{
				"timestamp": "2016-05-31T16:00:00.00Z",
				"count": 7,
				"uniques": 6
		}]}`)
	})

	ctx := context.Background()
	got, _, err := client.Repositories.ListTrafficClones(ctx, "o", "r", nil)
	if err != nil {
		t.Errorf("Repositories.ListTrafficClones returned error: %+v", err)
	}

	want := &TrafficClones{
		Clones: []*TrafficData{{
			Timestamp: &Timestamp{time.Date(2016, time.May, 31, 16, 0, 0, 0, time.UTC)},
			Count:     Int(7),
			Uniques:   Int(6),
		}},
		Count:   Int(7),
		Uniques: Int(6),
	}

	if !cmp.Equal(got, want) {
		t.Errorf("Repositories.ListTrafficClones returned %+v, want %+v", got, want)
	}

	const methodName = "ListTrafficClones"
	testBadOptions(t, methodName, func() (err error) {
		_, _, err = client.Repositories.ListTrafficClones(ctx, "\n", "\n", &TrafficBreakdownOptions{})
		return err
	})

	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
		got, resp, err := client.Repositories.ListTrafficClones(ctx, "o", "r", nil)
		if got != nil {
			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
		}
		return resp, err
	})
}

func TestTrafficReferrer_Marshal(t *testing.T) {
	testJSONMarshal(t, &TrafficReferrer{}, "{}")

	u := &TrafficReferrer{
		Referrer: String("referrer"),
		Count:    Int(0),
		Uniques:  Int(0),
	}

	want := `{
		"referrer" : "referrer",
		"count" : 0,
		"uniques" : 0
	}`

	testJSONMarshal(t, u, want)
}

func TestTrafficViews_Marshal(t *testing.T) {
	testJSONMarshal(t, &TrafficViews{}, "{}")

	u := &TrafficViews{
		Views: []*TrafficData{{
			Timestamp: &Timestamp{time.Date(2016, time.May, 31, 16, 0, 0, 0, time.UTC)},
			Count:     Int(7),
			Uniques:   Int(6),
		}},
		Count:   Int(0),
		Uniques: Int(0),
	}

	want := `{
		"views": [{
			"timestamp": "2016-05-31T16:00:00.000Z",
			"count": 7,
			"uniques": 6
		}],
		"count" : 0,
		"uniques" : 0
	}`

	testJSONMarshal(t, u, want)
}

func TestTrafficClones_Marshal(t *testing.T) {
	testJSONMarshal(t, &TrafficClones{}, "{}")

	u := &TrafficClones{
		Clones: []*TrafficData{{
			Timestamp: &Timestamp{time.Date(2021, time.October, 29, 16, 0, 0, 0, time.UTC)},
			Count:     Int(1),
			Uniques:   Int(1),
		}},
		Count:   Int(0),
		Uniques: Int(0),
	}

	want := `{
		"clones": [{
			"timestamp": "2021-10-29T16:00:00.000Z",
			"count": 1,
			"uniques": 1
		}],
		"count" : 0,
		"uniques" : 0
	}`

	testJSONMarshal(t, u, want)
}

func TestTrafficPath_Marshal(t *testing.T) {
	testJSONMarshal(t, &TrafficPath{}, "{}")

	u := &TrafficPath{
		Path:    String("test/path"),
		Title:   String("test"),
		Count:   Int(2),
		Uniques: Int(3),
	}

	want := `{
		"path" : "test/path",
		"title": "test",
		"count": 2,
		"uniques": 3
	}`

	testJSONMarshal(t, u, want)
}

func TestTrafficData_Marshal(t *testing.T) {
	testJSONMarshal(t, &TrafficData{}, "{}")

	u := &TrafficData{
		Timestamp: &Timestamp{time.Date(2016, time.May, 31, 16, 0, 0, 0, time.UTC)},
		Count:     Int(7),
		Uniques:   Int(6),
	}

	want := `{
			"timestamp": "2016-05-31T16:00:00.000Z",
			"count": 7,
			"uniques": 6
      }`

	testJSONMarshal(t, u, want)
}

func TestTrafficBreakdownOptions_Marshal(t *testing.T) {
	testJSONMarshal(t, &TrafficBreakdownOptions{}, "{}")

	u := &TrafficBreakdownOptions{
		Per: "day",
	}

	want := `{
		"per": "day"
	}`

	testJSONMarshal(t, u, want)
}
<|endoftext|>


<commit_before>package main

import "fmt"
import "time"

// Used to time other functions to compare speed
func timeTrack(start time.Time, name string) {
	elapsed := time.Since(start)
	fmt.Printf("%s took %s \n", name, elapsed)
}

func someName() {
	defer timeTrack(time.Now(), "Count1") // Timer function

	// Code body

}

func main() {
	someName() // call the function being tested
}
<commit_msg>Added additonal solutions<commit_after>/*
Each new term in the Fibonacci sequence is generated by adding the previous
two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

By considering the terms in the Fibonacci sequence whose values do not exceed
four million, find the sum of the even-valued terms.
*/

package main

import (
	"fmt"
	"time"
)

// Used to time other functions to compare speed
func timeTrack(start time.Time, name string) {
	elapsed := time.Since(start)
	fmt.Printf("%s took %s \n", name, elapsed)
}

// Returns the nth fibonacci number
func fib(num int) int {
	// defer timeTrack(time.Now(), "fib") // Timer function
	if num == 1 {
		return 1
	}
	if num == 2 {
		return 2
	}

	a, b := 1, 2
	for i := 1; i <= num-2; i++ {
		a, b = b, a+b
	}
	// fmt.Printf("Fibonacci(%d) = %d\n", num, b)
	return b
}

func countFibEven1(num int) int {
	defer timeTrack(time.Now(), "CountFibEven1") // Timer function

	sum := 0
	fibnum := 0
	for i := 1; i < num; i++ { // Use some big number to limit the loop
		fibnum = fib(i)
		if fibnum > num {
			return sum
		}
		if fibnum%2 == 0 { // If fibnum is even
			sum += fibnum
		}
	}
	return 0
}

func countFibEven2(num int) int {
	defer timeTrack(time.Now(), "CountFibEven2") // Timer function

	sum := 0
	fibnum := 0
	for i := 2; i < num; i += 3 { // Use some big number to limit the loop
		fibnum = fib(i)
		if fibnum > num {
			return sum
		}
		if fibnum%2 == 0 { // If fibnum is even
			sum += fibnum
		}
	}
	return 0
}

func countFibEven3(num int) int {
	defer timeTrack(time.Now(), "CountFibEven3") // Timer function

	sum := 0
	i := 2
	for fibnum := fib(i); fibnum < num; fibnum = fib(i) { // Use some big number to limit the loop
		sum += fibnum
		i += 3
	}
	return sum
}

func main() {
	fmt.Printf("fib = %d\n", fib(50))
	fmt.Printf("CountFibEven1 = %d\n", countFibEven1(4e6))
	fmt.Printf("CountFibEven2 = %d\n", countFibEven2(4e6))
	fmt.Printf("CountFibEven3 = %d\n", countFibEven3(4e6))
}
<|endoftext|>


<commit_before>// Copyright 2013 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 gccgoimporter implements Import for gccgo-generated object files.
package gccgoimporter

import (
	"debug/elf"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"

	"code.google.com/p/go.tools/go/types"
)

// Locate the file from which to read export data.
// This is intended to replicate the logic in gofrontend.
func findExportFile(searchpaths []string, pkgpath string) (string, error) {
	for _, spath := range searchpaths {
		pkgfullpath := filepath.Join(spath, pkgpath)
		pkgdir, name := filepath.Split(pkgfullpath)

		for _, filepath := range [...]string{
			pkgfullpath,
			pkgfullpath + ".gox",
			pkgdir + "lib" + name + ".so",
			pkgdir + "lib" + name + ".a",
			pkgfullpath + ".o",
		} {
			fi, err := os.Stat(filepath)
			if err == nil && !fi.IsDir() {
				return filepath, nil
			}
		}
	}

	return "", fmt.Errorf("%s: could not find export data (tried %s)", pkgpath, strings.Join(searchpaths, ":"))
}

// Opens the export data file at the given path. If this is an ELF file,
// searches for and opens the .go_export section.
// This is intended to replicate the logic in gofrontend, although it doesn't handle archive files yet.
func openExportFile(fpath string) (reader io.ReadSeeker, closer io.Closer, err error) {
	f, err := os.Open(fpath)
	if err != nil {
		return
	}
	closer = f

	var magic [4]byte
	_, err = f.ReadAt(magic[:], 0)
	if err != nil {
		f.Close()
		return
	}

	if string(magic[:]) == "v1;\n" {
		// Raw export data.
		reader = f
		return
	}

	ef, err := elf.NewFile(f)
	if err != nil {
		f.Close()
		return
	}

	sec := ef.Section(".go_export")
	if sec == nil {
		err = fmt.Errorf("%s: .go_export section not found", fpath)
		f.Close()
		return
	}

	reader = sec.Open()
	return
}

func GetImporter(searchpaths []string) types.Importer {
	return func(imports map[string]*types.Package, pkgpath string) (pkg *types.Package, err error) {
		if pkgpath == "unsafe" {
			return types.Unsafe, nil
		}

		fpath, err := findExportFile(searchpaths, pkgpath)
		if err != nil {
			return
		}

		reader, closer, err := openExportFile(fpath)
		if err != nil {
			return
		}
		defer closer.Close()

		var p parser
		p.init(fpath, reader, imports)
		pkg = p.parsePackage()
		return
	}
}
<commit_msg>go.tools/go/gccgoimporter: backported some changes from godex implementation<commit_after>// Copyright 2013 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 gccgoimporter implements Import for gccgo-generated object files.
package gccgoimporter

import (
	"debug/elf"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"

	"code.google.com/p/go.tools/go/types"
)

// Locate the file from which to read export data.
// This is intended to replicate the logic in gofrontend.
func findExportFile(searchpaths []string, pkgpath string) (string, error) {
	for _, spath := range searchpaths {
		pkgfullpath := filepath.Join(spath, pkgpath)
		pkgdir, name := filepath.Split(pkgfullpath)

		for _, filepath := range [...]string{
			pkgfullpath,
			pkgfullpath + ".gox",
			pkgdir + "lib" + name + ".so",
			pkgdir + "lib" + name + ".a",
			pkgfullpath + ".o",
		} {
			fi, err := os.Stat(filepath)
			if err == nil && !fi.IsDir() {
				return filepath, nil
			}
		}
	}

	return "", fmt.Errorf("%s: could not find export data (tried %s)", pkgpath, strings.Join(searchpaths, ":"))
}

// Opens the export data file at the given path. If this is an ELF file,
// searches for and opens the .go_export section.
// This is intended to replicate the logic in gofrontend, although it doesn't handle archive files yet.
func openExportFile(fpath string) (reader io.ReadSeeker, closer io.Closer, err error) {
	f, err := os.Open(fpath)
	if err != nil {
		return
	}
	defer func() {
		if err != nil {
			f.Close()
		}
	}()
	closer = f

	var magic [4]byte
	_, err = f.ReadAt(magic[:], 0)
	if err != nil {
		return
	}

	if string(magic[:]) == "v1;\n" {
		// Raw export data.
		reader = f
		return
	}

	ef, err := elf.NewFile(f)
	if err != nil {
		return
	}

	sec := ef.Section(".go_export")
	if sec == nil {
		err = fmt.Errorf("%s: .go_export section not found", fpath)
		return
	}

	reader = sec.Open()
	return
}

func GetImporter(searchpaths []string) types.Importer {
	return func(imports map[string]*types.Package, pkgpath string) (pkg *types.Package, err error) {
		if pkgpath == "unsafe" {
			return types.Unsafe, nil
		}

		fpath, err := findExportFile(searchpaths, pkgpath)
		if err != nil {
			return
		}

		reader, closer, err := openExportFile(fpath)
		if err != nil {
			return
		}
		defer closer.Close()

		var p parser
		p.init(fpath, reader, imports)
		pkg = p.parsePackage()
		return
	}
}
<|endoftext|>


<commit_before>package collector_test

import (
	"autoscaler/cf"
	. "autoscaler/metricscollector/collector"
	"autoscaler/metricscollector/fakes"
	"autoscaler/metricscollector/noaa"
	"autoscaler/models"

	"code.cloudfoundry.org/clock/fakeclock"
	"code.cloudfoundry.org/lager/lagertest"
	"github.com/cloudfoundry/sonde-go/events"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"

	"errors"
	"time"
)

var _ = Describe("AppStreamer", func() {

	var (
		cfc          *fakes.FakeCfClient
		noaaConsumer *fakes.FakeNoaaConsumer
		database     *fakes.FakeInstanceMetricsDB
		streamer     AppStreamer
		buffer       *gbytes.Buffer
		msgChan      chan *events.Envelope
		errChan      chan error
		fclock       *fakeclock.FakeClock
	)

	BeforeEach(func() {
		cfc = &fakes.FakeCfClient{}
		noaaConsumer = &fakes.FakeNoaaConsumer{}
		database = &fakes.FakeInstanceMetricsDB{}

		logger := lagertest.NewTestLogger("AppStreamer-test")
		buffer = logger.Buffer()
		fclock = fakeclock.NewFakeClock(time.Now())

		streamer = NewAppStreamer(logger, "an-app-id", TestCollectInterval, cfc, noaaConsumer, database, fclock)

		msgChan = make(chan *events.Envelope)
		errChan = make(chan error, 1)
	})

	Describe("Start", func() {

		JustBeforeEach(func() {
			streamer.Start()
		})

		AfterEach(func() {
			streamer.Stop()
		})

		BeforeEach(func() {
			cfc.GetTokensReturns(cf.Tokens{AccessToken: "test-access-token"})
			noaaConsumer.StreamStub = func(appId string, authToken string) (outputChan <-chan *events.Envelope, errorChan <-chan error) {
				Expect(appId).To(Equal("an-app-id"))
				Expect(authToken).To(Equal("test-access-token"))
				return msgChan, errChan
			}
		})

		Context("when there are containermetric events", func() {
			BeforeEach(func() {
				go func() {
					msgChan <- noaa.NewContainerEnvelope(111111, "an-app-id", 0, 12.8, 12345678, 987654321)
					msgChan <- noaa.NewContainerEnvelope(222222, "an-app-id", 1, 12.8, 23563212, 987654321)
				}()
			})
			It("Saves metrics to database", func() {
				Eventually(database.SaveMetricCallCount).Should(Equal(2))
				Expect(database.SaveMetricArgsForCall(0)).To(Equal(&models.AppInstanceMetric{
					AppId:         "an-app-id",
					InstanceIndex: 0,
					CollectedAt:   fclock.Now().UnixNano(),
					Name:          models.MetricNameMemory,
					Unit:          models.UnitMegaBytes,
					Value:         "12",
					Timestamp:     111111,
				}))
				Expect(database.SaveMetricArgsForCall(1)).To(Equal(&models.AppInstanceMetric{
					AppId:         "an-app-id",
					InstanceIndex: 1,
					CollectedAt:   fclock.Now().UnixNano(),
					Name:          models.MetricNameMemory,
					Unit:          models.UnitMegaBytes,
					Value:         "22",
					Timestamp:     222222,
				}))

			})
			Context("when database fails", func() {
				BeforeEach(func() {
					database.SaveMetricReturns(errors.New("an error"))
				})
				It("logs the errors", func() {
					Eventually(buffer).Should(gbytes.Say("process-event-save-metric"))
					Eventually(buffer).Should(gbytes.Say("an error"))
				})
			})
		})

		Context("when there are httpstartstop events", func() {
			It("Saves metrics to database with the given time interval", func() {
				go func() {
					msgChan <- noaa.NewHttpStartStopEnvelope(111111, 100000000, 200000000, 0)
					msgChan <- noaa.NewHttpStartStopEnvelope(222222, 300000000, 600000000, 0)
				}()

				By("collecting and computing througput and responsetime for first interval")
				Consistently(database.SaveMetricCallCount).Should(Equal(0))

				By("save throughput and responsetime metric after the first collect interval")
				fclock.WaitForWatcherAndIncrement(TestCollectInterval)
				Eventually(database.SaveMetricCallCount).Should(Equal(2))

				Expect(database.SaveMetricArgsForCall(0)).To(Equal(&models.AppInstanceMetric{
					AppId:         "an-app-id",
					InstanceIndex: 0,
					CollectedAt:   fclock.Now().UnixNano(),
					Name:          models.MetricNameThroughput,
					Unit:          models.UnitRPS,
					Value:         "2.0",
					Timestamp:     fclock.Now().UnixNano(),
				}))
				Expect(database.SaveMetricArgsForCall(1)).To(Equal(&models.AppInstanceMetric{
					AppId:         "an-app-id",
					InstanceIndex: 0,
					CollectedAt:   fclock.Now().UnixNano(),
					Name:          models.MetricNameResponseTime,
					Unit:          models.UnitMilliseconds,
					Value:         "200",
					Timestamp:     fclock.Now().UnixNano(),
				}))

				go func() {
					msgChan <- noaa.NewHttpStartStopEnvelope(333333, 100000000, 300000000, 1)
					msgChan <- noaa.NewHttpStartStopEnvelope(555555, 300000000, 600000000, 1)
					msgChan <- noaa.NewHttpStartStopEnvelope(666666, 300000000, 700000000, 1)
				}()

				By("collecting and computing througput and responsetime for second interval")
				Consistently(database.SaveMetricCallCount).Should(Equal(2))

				By("save throughput and responsetime metric after the second collect interval")
				fclock.Increment(TestCollectInterval)
				Eventually(database.SaveMetricCallCount).Should(Equal(4))

				Expect(database.SaveMetricArgsForCall(2)).To(Equal(&models.AppInstanceMetric{
					AppId:         "an-app-id",
					InstanceIndex: 1,
					CollectedAt:   fclock.Now().UnixNano(),
					Name:          models.MetricNameThroughput,
					Unit:          models.UnitRPS,
					Value:         "3.0",
					Timestamp:     fclock.Now().UnixNano(),
				}))
				Expect(database.SaveMetricArgsForCall(3)).To(Equal(&models.AppInstanceMetric{
					AppId:         "an-app-id",
					InstanceIndex: 1,
					CollectedAt:   fclock.Now().UnixNano(),
					Name:          models.MetricNameResponseTime,
					Unit:          models.UnitMilliseconds,
					Value:         "300",
					Timestamp:     fclock.Now().UnixNano(),
				}))
			})

			Context("when the app has multiple instances", func() {
				BeforeEach(func() {
					go func() {
						msgChan <- noaa.NewHttpStartStopEnvelope(111111, 100000000, 200000000, 0)
						msgChan <- noaa.NewHttpStartStopEnvelope(222222, 300000000, 500000000, 1)
						msgChan <- noaa.NewHttpStartStopEnvelope(333333, 200000000, 600000000, 2)
						msgChan <- noaa.NewHttpStartStopEnvelope(555555, 300000000, 500000000, 2)
					}()

				})
				It("saves throughput and responsetime metrics of multiple instances", func() {
					Consistently(database.SaveMetricCallCount).Should(Equal(0))
					fclock.WaitForWatcherAndIncrement(TestCollectInterval)
					Eventually(database.SaveMetricCallCount).Should(Equal(6))
				})
			})

			Context("when database fails", func() {
				BeforeEach(func() {
					database.SaveMetricReturns(errors.New("an error"))
					go func() {
						msgChan <- noaa.NewHttpStartStopEnvelope(111111, 100000000, 200000000, 0)
					}()
				})
				It("logs the errors", func() {
					Consistently(database.SaveMetricCallCount).Should(Equal(0))

					fclock.WaitForWatcherAndIncrement(TestCollectInterval)
					Eventually(buffer).Should(gbytes.Say("save-metric-to-database"))
					Eventually(buffer).Should(gbytes.Say("an error"))
					Eventually(buffer).Should(gbytes.Say("throughput"))

					Eventually(buffer).Should(gbytes.Say("save-metric-to-database"))
					Eventually(buffer).Should(gbytes.Say("an error"))
					Eventually(buffer).Should(gbytes.Say("responsetime"))
				})
			})

		})

		Context("when there is no conatinermetrics or httpstartstop event", func() {
			BeforeEach(func() {
				go func() {
					eventType := events.Envelope_CounterEvent
					msgChan <- &events.Envelope{EventType: &eventType}
				}()
			})
			It("Saves nothing to database", func() {
				Consistently(database.SaveMetricCallCount).Should(BeZero())
			})
		})
		Context("when there is error  streaming events", func() {
			BeforeEach(func() {
				errChan <- errors.New("an error")
			})
			It("logs the error", func() {
				Eventually(buffer).Should(gbytes.Say("stream-metrics"))
				Eventually(buffer).Should(gbytes.Say("an-app-id"))
				Eventually(buffer).Should(gbytes.Say("an error"))
			})
		})
	})

	Describe("Stop", func() {
		BeforeEach(func() {
			streamer.Start()
		})
		JustBeforeEach(func() {
			streamer.Stop()
		})
		It("stops the streaming", func() {
			Eventually(buffer).Should(gbytes.Say("app-streamer-stopped"))
			Eventually(buffer).Should(gbytes.Say("an-app-id"))
		})
		Context("when error occurs closing the connection", func() {
			BeforeEach(func() {
				noaaConsumer.CloseReturns(errors.New("an error"))
			})
			It("logs the error", func() {
				Eventually(buffer).Should(gbytes.Say("close-noaa-connections"))
				Eventually(buffer).Should(gbytes.Say("an-app-id"))
				Eventually(buffer).Should(gbytes.Say("an error"))
			})
		})
		Context("when closing the connection succeeds", func() {
			It("logs the message", func() {
				Eventually(buffer).Should(gbytes.Say("noaa-connections-closed"))
				Eventually(buffer).Should(gbytes.Say("an-app-id"))
			})
		})

	})

})
<commit_msg>fix typo and test case of app streamer when there is no container metrics and httpstartstop event<commit_after>package collector_test

import (
	"autoscaler/cf"
	. "autoscaler/metricscollector/collector"
	"autoscaler/metricscollector/fakes"
	"autoscaler/metricscollector/noaa"
	"autoscaler/models"

	"code.cloudfoundry.org/clock/fakeclock"
	"code.cloudfoundry.org/lager/lagertest"
	"github.com/cloudfoundry/sonde-go/events"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/onsi/gomega/gbytes"

	"errors"
	"time"
)

var _ = Describe("AppStreamer", func() {

	var (
		cfc          *fakes.FakeCfClient
		noaaConsumer *fakes.FakeNoaaConsumer
		database     *fakes.FakeInstanceMetricsDB
		streamer     AppStreamer
		buffer       *gbytes.Buffer
		msgChan      chan *events.Envelope
		errChan      chan error
		fclock       *fakeclock.FakeClock
	)

	BeforeEach(func() {
		cfc = &fakes.FakeCfClient{}
		noaaConsumer = &fakes.FakeNoaaConsumer{}
		database = &fakes.FakeInstanceMetricsDB{}

		logger := lagertest.NewTestLogger("AppStreamer-test")
		buffer = logger.Buffer()
		fclock = fakeclock.NewFakeClock(time.Now())

		streamer = NewAppStreamer(logger, "an-app-id", TestCollectInterval, cfc, noaaConsumer, database, fclock)

		msgChan = make(chan *events.Envelope)
		errChan = make(chan error, 1)
	})

	Describe("Start", func() {

		JustBeforeEach(func() {
			streamer.Start()
		})

		AfterEach(func() {
			streamer.Stop()
		})

		BeforeEach(func() {
			cfc.GetTokensReturns(cf.Tokens{AccessToken: "test-access-token"})
			noaaConsumer.StreamStub = func(appId string, authToken string) (outputChan <-chan *events.Envelope, errorChan <-chan error) {
				Expect(appId).To(Equal("an-app-id"))
				Expect(authToken).To(Equal("test-access-token"))
				return msgChan, errChan
			}
		})

		Context("when there are containermetric events", func() {
			BeforeEach(func() {
				go func() {
					msgChan <- noaa.NewContainerEnvelope(111111, "an-app-id", 0, 12.8, 12345678, 987654321)
					msgChan <- noaa.NewContainerEnvelope(222222, "an-app-id", 1, 12.8, 23563212, 987654321)
				}()
			})
			It("Saves metrics to database", func() {
				Eventually(database.SaveMetricCallCount).Should(Equal(2))
				Expect(database.SaveMetricArgsForCall(0)).To(Equal(&models.AppInstanceMetric{
					AppId:         "an-app-id",
					InstanceIndex: 0,
					CollectedAt:   fclock.Now().UnixNano(),
					Name:          models.MetricNameMemory,
					Unit:          models.UnitMegaBytes,
					Value:         "12",
					Timestamp:     111111,
				}))
				Expect(database.SaveMetricArgsForCall(1)).To(Equal(&models.AppInstanceMetric{
					AppId:         "an-app-id",
					InstanceIndex: 1,
					CollectedAt:   fclock.Now().UnixNano(),
					Name:          models.MetricNameMemory,
					Unit:          models.UnitMegaBytes,
					Value:         "22",
					Timestamp:     222222,
				}))

			})
			Context("when saving to database fails", func() {
				BeforeEach(func() {
					database.SaveMetricReturns(errors.New("an error"))
				})
				It("logs the errors", func() {
					Eventually(buffer).Should(gbytes.Say("process-event-save-metric"))
					Eventually(buffer).Should(gbytes.Say("an error"))
				})
			})
		})

		Context("when there are httpstartstop events", func() {
			It("Saves metrics to database with the given time interval", func() {
				go func() {
					msgChan <- noaa.NewHttpStartStopEnvelope(111111, 100000000, 200000000, 0)
					msgChan <- noaa.NewHttpStartStopEnvelope(222222, 300000000, 600000000, 0)
				}()

				By("collecting and computing throughput and responsetime for first interval")
				Consistently(database.SaveMetricCallCount).Should(Equal(0))

				By("save throughput and responsetime metric after the first collect interval")
				fclock.WaitForWatcherAndIncrement(TestCollectInterval)
				Eventually(database.SaveMetricCallCount).Should(Equal(2))

				Expect(database.SaveMetricArgsForCall(0)).To(Equal(&models.AppInstanceMetric{
					AppId:         "an-app-id",
					InstanceIndex: 0,
					CollectedAt:   fclock.Now().UnixNano(),
					Name:          models.MetricNameThroughput,
					Unit:          models.UnitRPS,
					Value:         "2.0",
					Timestamp:     fclock.Now().UnixNano(),
				}))
				Expect(database.SaveMetricArgsForCall(1)).To(Equal(&models.AppInstanceMetric{
					AppId:         "an-app-id",
					InstanceIndex: 0,
					CollectedAt:   fclock.Now().UnixNano(),
					Name:          models.MetricNameResponseTime,
					Unit:          models.UnitMilliseconds,
					Value:         "200",
					Timestamp:     fclock.Now().UnixNano(),
				}))

				go func() {
					msgChan <- noaa.NewHttpStartStopEnvelope(333333, 100000000, 300000000, 1)
					msgChan <- noaa.NewHttpStartStopEnvelope(555555, 300000000, 600000000, 1)
					msgChan <- noaa.NewHttpStartStopEnvelope(666666, 300000000, 700000000, 1)
				}()

				By("collecting and computing throughput and responsetime for second interval")
				Consistently(database.SaveMetricCallCount).Should(Equal(2))

				By("save throughput and responsetime metric after the second collect interval")
				fclock.Increment(TestCollectInterval)
				Eventually(database.SaveMetricCallCount).Should(Equal(4))

				Expect(database.SaveMetricArgsForCall(2)).To(Equal(&models.AppInstanceMetric{
					AppId:         "an-app-id",
					InstanceIndex: 1,
					CollectedAt:   fclock.Now().UnixNano(),
					Name:          models.MetricNameThroughput,
					Unit:          models.UnitRPS,
					Value:         "3.0",
					Timestamp:     fclock.Now().UnixNano(),
				}))
				Expect(database.SaveMetricArgsForCall(3)).To(Equal(&models.AppInstanceMetric{
					AppId:         "an-app-id",
					InstanceIndex: 1,
					CollectedAt:   fclock.Now().UnixNano(),
					Name:          models.MetricNameResponseTime,
					Unit:          models.UnitMilliseconds,
					Value:         "300",
					Timestamp:     fclock.Now().UnixNano(),
				}))
			})

			Context("when the app has multiple instances", func() {
				BeforeEach(func() {
					go func() {
						msgChan <- noaa.NewHttpStartStopEnvelope(111111, 100000000, 200000000, 0)
						msgChan <- noaa.NewHttpStartStopEnvelope(222222, 300000000, 500000000, 1)
						msgChan <- noaa.NewHttpStartStopEnvelope(333333, 200000000, 600000000, 2)
						msgChan <- noaa.NewHttpStartStopEnvelope(555555, 300000000, 500000000, 2)
					}()

				})
				It("saves throughput and responsetime metrics of multiple instances", func() {
					Consistently(database.SaveMetricCallCount).Should(Equal(0))
					fclock.WaitForWatcherAndIncrement(TestCollectInterval)
					Eventually(database.SaveMetricCallCount).Should(Equal(6))
				})
			})

			Context("when database fails", func() {
				BeforeEach(func() {
					database.SaveMetricReturns(errors.New("an error"))
					go func() {
						msgChan <- noaa.NewHttpStartStopEnvelope(111111, 100000000, 200000000, 0)
					}()
				})
				It("logs the errors", func() {
					Consistently(database.SaveMetricCallCount).Should(Equal(0))

					fclock.WaitForWatcherAndIncrement(TestCollectInterval)
					Eventually(buffer).Should(gbytes.Say("save-metric-to-database"))
					Eventually(buffer).Should(gbytes.Say("an error"))
					Eventually(buffer).Should(gbytes.Say("throughput"))

					Eventually(buffer).Should(gbytes.Say("save-metric-to-database"))
					Eventually(buffer).Should(gbytes.Say("an error"))
					Eventually(buffer).Should(gbytes.Say("responsetime"))
				})
			})

		})

		Context("when there is no containermetrics or httpstartstop event", func() {
			BeforeEach(func() {
				go func() {
					eventType := events.Envelope_CounterEvent
					msgChan <- &events.Envelope{EventType: &eventType}
				}()
			})
			It("Saves nothing to database", func() {
				fclock.WaitForWatcherAndIncrement(TestCollectInterval)
				Consistently(database.SaveMetricCallCount).Should(BeZero())
			})
		})
		Context("when there is error  streaming events", func() {
			BeforeEach(func() {
				errChan <- errors.New("an error")
			})
			It("logs the error", func() {
				Eventually(buffer).Should(gbytes.Say("stream-metrics"))
				Eventually(buffer).Should(gbytes.Say("an-app-id"))
				Eventually(buffer).Should(gbytes.Say("an error"))
			})
		})
	})

	Describe("Stop", func() {
		BeforeEach(func() {
			streamer.Start()
		})
		JustBeforeEach(func() {
			streamer.Stop()
		})
		It("stops the streaming", func() {
			Eventually(buffer).Should(gbytes.Say("app-streamer-stopped"))
			Eventually(buffer).Should(gbytes.Say("an-app-id"))
		})
		Context("when error occurs closing the connection", func() {
			BeforeEach(func() {
				noaaConsumer.CloseReturns(errors.New("an error"))
			})
			It("logs the error", func() {
				Eventually(buffer).Should(gbytes.Say("close-noaa-connections"))
				Eventually(buffer).Should(gbytes.Say("an-app-id"))
				Eventually(buffer).Should(gbytes.Say("an error"))
			})
		})
		Context("when closing the connection succeeds", func() {
			It("logs the message", func() {
				Eventually(buffer).Should(gbytes.Say("noaa-connections-closed"))
				Eventually(buffer).Should(gbytes.Say("an-app-id"))
			})
		})

	})

})
<|endoftext|>


<commit_before>// +build ignore

package PACKAGE
<commit_msg>cmd/compile: delete the runtime_internal_atomic.go builtin defs file<commit_after><|endoftext|>


<commit_before>// Copyright 2017 The casbin Authors. All Rights Reserved.
//
// 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 casbin

// GetUsersForRoleInDomain gets the users that has a role inside a domain. Add by Gordon
func (e *Enforcer) GetUsersForRoleInDomain(name string, domain string) []string {
	res, _ := e.model["g"]["g"].RM.GetUsers(name, domain)
	return res
}

// GetRolesForUserInDomain gets the roles that a user has inside a domain.
func (e *Enforcer) GetRolesForUserInDomain(name string, domain string) []string {
	res, _ := e.model["g"]["g"].RM.GetRoles(name, domain)
	return res
}

// GetPermissionsForUserInDomain gets permissions for a user or role inside a domain.
func (e *Enforcer) GetPermissionsForUserInDomain(user string, domain string) [][]string {
	return e.GetFilteredPolicy(0, user, domain)
}

// AddRoleForUserInDomain adds a role for a user inside a domain.
// Returns false if the user already has the role (aka not affected).
func (e *Enforcer) AddRoleForUserInDomain(user string, role string, domain string) (bool, error) {
	return e.AddGroupingPolicy(user, role, domain)
}

// DeleteRoleForUserInDomain deletes a role for a user inside a domain.
// Returns false if the user does not have the role (aka not affected).
func (e *Enforcer) DeleteRoleForUserInDomain(user string, role string, domain string) (bool, error) {
	return e.RemoveGroupingPolicy(user, role, domain)
}

// DeleteRolesForUserInDomain deletes all roles for a user inside a domain.
// Returns false if the user does not have any roles (aka not affected).
func (e *Enforcer) DeleteRolesForUserInDomain(user string, domain string) (bool, error) {
	roles, err := e.model["g"]["g"].RM.GetRoles(user, domain)
	if err != nil {
		return false, err
	}

	var rules [][]string
	for _, role := range roles {
		rules = append(rules, []string{user, role, domain})
	}

	return e.RemoveGroupingPolicies(rules)
}
<commit_msg>feat: add new rbac api<commit_after>// Copyright 2017 The casbin Authors. All Rights Reserved.
//
// 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 casbin

// GetUsersForRoleInDomain gets the users that has a role inside a domain. Add by Gordon
func (e *Enforcer) GetUsersForRoleInDomain(name string, domain string) []string {
	res, _ := e.model["g"]["g"].RM.GetUsers(name, domain)
	return res
}

// GetRolesForUserInDomain gets the roles that a user has inside a domain.
func (e *Enforcer) GetRolesForUserInDomain(name string, domain string) []string {
	res, _ := e.model["g"]["g"].RM.GetRoles(name, domain)
	return res
}

// GetPermissionsForUserInDomain gets permissions for a user or role inside a domain.
func (e *Enforcer) GetPermissionsForUserInDomain(user string, domain string) [][]string {
	return e.GetFilteredPolicy(0, user, domain)
}

// AddRoleForUserInDomain adds a role for a user inside a domain.
// Returns false if the user already has the role (aka not affected).
func (e *Enforcer) AddRoleForUserInDomain(user string, role string, domain string) (bool, error) {
	return e.AddGroupingPolicy(user, role, domain)
}

// DeleteRoleForUserInDomain deletes a role for a user inside a domain.
// Returns false if the user does not have the role (aka not affected).
func (e *Enforcer) DeleteRoleForUserInDomain(user string, role string, domain string) (bool, error) {
	return e.RemoveGroupingPolicy(user, role, domain)
}

// DeleteRolesForUserInDomain deletes all roles for a user inside a domain.
// Returns false if the user does not have any roles (aka not affected).
func (e *Enforcer) DeleteRolesForUserInDomain(user string, domain string) (bool, error) {
	roles, err := e.model["g"]["g"].RM.GetRoles(user, domain)
	if err != nil {
		return false, err
	}

	var rules [][]string
	for _, role := range roles {
		rules = append(rules, []string{user, role, domain})
	}

	return e.RemoveGroupingPolicies(rules)
}

// GetAllUsersByDomain would get all users associated with the domain.
func (e *Enforcer) GetAllUsersByDomain(domain string) []string {
	m := make(map[string]struct{})
	g := e.model["g"]["g"]
	if len(g.Tokens) != 3 {
		return []string{}
	}
	users := make([]string, 0)
	for _, policy := range g.Policy {
		if _, ok := m[policy[2]]; policy[2] == domain && ok {
			users = append(users, policy[0])
		}
	}
	return users
}

// DeleteAllUsersByDomain would delete all users associated with the domain.
func (e *Enforcer) DeleteAllUsersByDomain(domain string) (bool, error) {
	g := e.model["g"]["g"]
	if len(g.Tokens) != 3 {
		return false, nil
	}
	policies := make([][]string, 0)
	for _, policy := range g.Policy {
		if policy[3] == domain {
			policies = append(policies, policy)
		}
	}
	return e.RemoveGroupingPolicies(policies)
}

// DeleteDomains would delete all associated users and roles.
// It would delete all domains if parameter is not provided.
func (e *Enforcer) DeleteDomains(domains ...string) (bool, error) {
	g := e.model["g"]["g"]
	if len(g.Tokens) != 3 {
		return false, nil
	}
	if len(domains) == 0 {
		return e.RemoveGroupingPolicies(g.Policy)
	}
	m := make(map[string]struct{})
	for _, domain := range domains {
		m[domain] = struct{}{}
	}
	policies := make([][]string, 0)
	for _, policy := range g.Policy {
		if _, ok := m[policy[2]]; ok {
			policies = append(policies, policy)
		}
	}
	return e.RemoveGroupingPolicies(policies)
}
<|endoftext|>