<commit_before>package sql

import (
	"database/sql"
	"fmt"
	"math/rand"
	"strconv"
	"strings"
)

type ShardSet struct {
	username     string
	password     string
	host         string
	port         int
	dbNamePrefix string
	numShards    int
	maxShards    int
	maxConns     int
	shards       []*shard
}

func NewShardSet(username string, password string, host string, port int, dbNamePrefix string, numShards int, maxShards int, maxConns int) *ShardSet {
	return &ShardSet{
		username:     username,
		password:     password,
		host:         host,
		port:         port,
		dbNamePrefix: dbNamePrefix,
		numShards:    numShards,
		maxShards:    maxShards,
		maxConns:     maxConns,
	}
}

func (s *ShardSet) Connect() (err error) {
	s.shards = make([]*shard, s.numShards)
	for i := 0; i < s.numShards; i++ {
		err = s.addShard(i)
		if err != nil {
			return
		}
	}
	return
}

func (s *ShardSet) Shard(id int64) Conn {
	if id == 0 {
		panic("Bad shard index id 0")
	}
	shardIndex := ((id - 1) % int64(s.maxShards)) // 1->0, 2->1, 3->2 ..., 65000->65000, 65001->0, 65002->1
	return s.shards[shardIndex]
}

func (s *ShardSet) All() []Conn {
	all := make([]Conn, len(s.shards))
	for i, shard := range s.shards {
		all[i] = Conn(shard)
	}
	return all
}

func (s *ShardSet) RandomShard() Conn {
	return s.shards[randomBetween(0, len(s.shards))]
}

func (s *ShardSet) addShard(i int) (err error) {
	autoIncrementOffset := i + 1
	dbName := fmt.Sprint(s.dbNamePrefix, autoIncrementOffset)
	s.shards[i], err = newShard(s, dbName, autoIncrementOffset)
	if err != nil {
		return
	}
	return
}

func newShard(s *ShardSet, dbName string, autoIncrementOffset int) (*shard, error) {
	connVars := ConnVariables{
		"autocommit":               "true",
		"clientFoundRows":          "true",
		"auto_increment_increment": strconv.Itoa(s.maxShards),
		"auto_increment_offset":    strconv.Itoa(autoIncrementOffset),
		"sql_mode":                 "STRICT_ALL_TABLES",
	}

	db, err := dbOpener(s.username, s.password, dbName, s.host, s.port, connVars)
	if err != nil {
		return nil, err
	}

	db.SetMaxOpenConns(s.maxConns)
	// db.SetMaxIdleConns(n)
	err = db.Ping()
	if err != nil {
		return nil, err
	}
	return &shard{db, shardConn{db}}, nil
}

func SetOpener(opener Opener) {
	if dbOpener != nil {
		panic("Opener already set - did you import two driver adapters?")
	}
	dbOpener = opener
}

type ConnVariables map[string]string

func (connVars ConnVariables) Join(sep string) string {
	kvps := make([]string, len(connVars))
	i := 0
	for param, val := range connVars {
		kvps[i] = param + "=" + val
		i += 1
	}
	return strings.Join(kvps, sep)
}

type Opener func(username, password, dbName, host string, port int, connVars ConnVariables) (*sql.DB, error)

var dbOpener Opener

func randomBetween(min, max int) int {
	return rand.Intn(max-min) + min // random int in [min, max)
}
<commit_msg>Handle emojis<commit_after>package sql

import (
	"database/sql"
	"fmt"
	"math/rand"
	"strconv"
	"strings"
)

type ShardSet struct {
	username     string
	password     string
	host         string
	port         int
	dbNamePrefix string
	numShards    int
	maxShards    int
	maxConns     int
	shards       []*shard
}

func NewShardSet(username string, password string, host string, port int, dbNamePrefix string, numShards int, maxShards int, maxConns int) *ShardSet {
	return &ShardSet{
		username:     username,
		password:     password,
		host:         host,
		port:         port,
		dbNamePrefix: dbNamePrefix,
		numShards:    numShards,
		maxShards:    maxShards,
		maxConns:     maxConns,
	}
}

func (s *ShardSet) Connect() (err error) {
	s.shards = make([]*shard, s.numShards)
	for i := 0; i < s.numShards; i++ {
		err = s.addShard(i)
		if err != nil {
			return
		}
	}
	return
}

func (s *ShardSet) Shard(id int64) Conn {
	if id == 0 {
		panic("Bad shard index id 0")
	}
	shardIndex := ((id - 1) % int64(s.maxShards)) // 1->0, 2->1, 3->2 ..., 65000->65000, 65001->0, 65002->1
	return s.shards[shardIndex]
}

func (s *ShardSet) All() []Conn {
	all := make([]Conn, len(s.shards))
	for i, shard := range s.shards {
		all[i] = Conn(shard)
	}
	return all
}

func (s *ShardSet) RandomShard() Conn {
	return s.shards[randomBetween(0, len(s.shards))]
}

func (s *ShardSet) addShard(i int) (err error) {
	autoIncrementOffset := i + 1
	dbName := fmt.Sprint(s.dbNamePrefix, autoIncrementOffset)
	s.shards[i], err = newShard(s, dbName, autoIncrementOffset)
	if err != nil {
		return
	}
	return
}

func newShard(s *ShardSet, dbName string, autoIncrementOffset int) (*shard, error) {
	connVars := ConnVariables{
		"autocommit":               "true",
		"clientFoundRows":          "true",
		"charset":                  "utf8mb4",
		"collation":                "utf8_unicode_ci",
		"auto_increment_increment": strconv.Itoa(s.maxShards),
		"auto_increment_offset":    strconv.Itoa(autoIncrementOffset),
		"sql_mode":                 "STRICT_ALL_TABLES",
	}

	db, err := dbOpener(s.username, s.password, dbName, s.host, s.port, connVars)
	if err != nil {
		return nil, err
	}

	db.SetMaxOpenConns(s.maxConns)
	// db.SetMaxIdleConns(n)
	err = db.Ping()
	if err != nil {
		return nil, err
	}
	return &shard{db, shardConn{db}}, nil
}

func SetOpener(opener Opener) {
	if dbOpener != nil {
		panic("Opener already set - did you import two driver adapters?")
	}
	dbOpener = opener
}

type ConnVariables map[string]string

func (connVars ConnVariables) Join(sep string) string {
	kvps := make([]string, len(connVars))
	i := 0
	for param, val := range connVars {
		kvps[i] = param + "=" + val
		i += 1
	}
	return strings.Join(kvps, sep)
}

type Opener func(username, password, dbName, host string, port int, connVars ConnVariables) (*sql.DB, error)

var dbOpener Opener

func randomBetween(min, max int) int {
	return rand.Intn(max-min) + min // random int in [min, max)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"github.com/PandoCloud/pando-cloud/pkg/models"
	"github.com/PandoCloud/pando-cloud/pkg/productconfig"
	"github.com/PandoCloud/pando-cloud/pkg/protocol"
	"github.com/PandoCloud/pando-cloud/pkg/queue"
	"github.com/PandoCloud/pando-cloud/pkg/rpcs"
	"github.com/PandoCloud/pando-cloud/pkg/server"
	"github.com/PandoCloud/pando-cloud/pkg/utils"
	"time"
)

const (
	topicEvents = "events"
	topicStatus = "status"
)

// report structure
type ReportPack struct {
	Tag        string                   `json:"tag"`
	Identifier string                   `json:"identifier"`
	TimeStamp  int64                    `json:"timestamp"`
	Data       map[string][]interface{} `json:"data"`
}

var notifier *Notifier

type Notifier struct {
	eventsQueue *queue.Queue
	statusQueue *queue.Queue
	apps        []*models.Application
}

func NewNotifier(rabbithost string) (*Notifier, error) {
	eq, err := queue.New(rabbithost, topicEvents)
	if err != nil {
		return nil, err
	}

	sq, err := queue.New(rabbithost, topicStatus)
	if err != nil {
		return nil, err
	}

	return &Notifier{
		eventsQueue: eq,
		statusQueue: sq,
	}, nil
}

// TODO
func (n *Notifier) reportStatus(event rpcs.ArgsOnStatus) error {
	return nil
}

// TODO
func (n *Notifier) processStatus() error {
	return nil
}

func (n *Notifier) updateApplications() error {
	for {

		err := server.RPCCallByName("registry", "Registry.GetApplications", 0, &n.apps)
		if err != nil {
			server.Log.Errorf("get applications error : %v", err)
		}

		time.Sleep(time.Minute)
	}
}

func (n *Notifier) reportEvent(event rpcs.ArgsOnEvent) error {
	server.Log.Debugf("reporting event %v", event)

	device := &models.Device{}
	err := server.RPCCallByName("registry", "Registry.FindDeviceById", int64(event.DeviceId), device)
	if err != nil {
		server.Log.Errorf("find device error : %v", err)
		return err
	}

	product := &models.Product{}
	err = server.RPCCallByName("registry", "Registry.FindProduct", device.ProductID, product)
	if err != nil {
		server.Log.Errorf("find product error : %v", err)
		return err
	}

	c, err := productconfig.New(product.ProductConfig)
	if err != nil {
		server.Log.Errorf("product config error : %v", err)
		return err
	}

	ev := &protocol.Event{}
	ev.Head.No = event.No
	ev.Head.SubDeviceid = event.SubDevice
	ev.Params = event.Params

	m, err := c.EventToMap(ev)
	if err != nil {
		server.Log.Errorf("gen event json error : %v", err)
		return err
	}

	res := ReportPack{
		Tag:        "event",
		Identifier: device.DeviceIdentifier,
		Data:       m,
	}

	jsonRes, err := json.Marshal(res)
	if err != nil {
		server.Log.Errorf("json marshal error : %v", err)
		return err
	}

	reqHead := map[string]string{}
	reqHead["Content-Type"] = "application/json"

	for _, app := range n.apps {
		if nil == checkAppDomain(app.AppDomain, device.DeviceIdentifier) {
			reqHead["App-Token"] = app.AppToken
			_, err := utils.SendHttpRequest(app.ReportUrl, string(jsonRes), "POST", reqHead)
			if err != nil {
				server.Log.Errorf("http post json error : %v", err)
			}
			server.Log.Debugf("http post json succ : %v", string(jsonRes))
		}
	}

	return nil
}

func (n *Notifier) processEvents() error {
	for {
		event := rpcs.ArgsOnEvent{}
		err := n.eventsQueue.Receive(&event)
		if err != nil {
			server.Log.Errorf("error when receiving from queue : %v", err)
			return err
		}
		go n.reportEvent(event)
	}

	return nil
}

func (n *Notifier) Run() error {
	go n.updateApplications()
	go n.processEvents()
	go n.processStatus()

	return nil
}

func RunNotifier() error {
	if notifier == nil {
		notifier, err := NewNotifier(*confRabbitHost)
		if err != nil {
			server.Log.Error(err)
		}
		err = notifier.Run()
		if err != nil {
			server.Log.Error(err)
		}
	}
	return nil
}
<commit_msg>fix apiprovider crash bug.<commit_after>package main

import (
	"encoding/json"
	"github.com/PandoCloud/pando-cloud/pkg/models"
	"github.com/PandoCloud/pando-cloud/pkg/productconfig"
	"github.com/PandoCloud/pando-cloud/pkg/protocol"
	"github.com/PandoCloud/pando-cloud/pkg/queue"
	"github.com/PandoCloud/pando-cloud/pkg/rpcs"
	"github.com/PandoCloud/pando-cloud/pkg/server"
	"github.com/PandoCloud/pando-cloud/pkg/utils"
	"time"
)

const (
	topicEvents = "events"
	topicStatus = "status"
)

// report structure
type ReportPack struct {
	Tag        string                   `json:"tag"`
	Identifier string                   `json:"identifier"`
	TimeStamp  int64                    `json:"timestamp"`
	Data       map[string][]interface{} `json:"data"`
}

var notifier *Notifier

type Notifier struct {
	eventsQueue *queue.Queue
	statusQueue *queue.Queue
	apps        []*models.Application
}

func NewNotifier(rabbithost string) (*Notifier, error) {
	eq, err := queue.New(rabbithost, topicEvents)
	if err != nil {
		return nil, err
	}

	sq, err := queue.New(rabbithost, topicStatus)
	if err != nil {
		return nil, err
	}

	return &Notifier{
		eventsQueue: eq,
		statusQueue: sq,
		apps:        []*models.Application{},
	}, nil
}

// TODO
func (n *Notifier) reportStatus(event rpcs.ArgsOnStatus) error {
	return nil
}

// TODO
func (n *Notifier) processStatus() error {
	return nil
}

func (n *Notifier) updateApplications() error {
	for {

		err := server.RPCCallByName("registry", "Registry.GetApplications", 0, &n.apps)
		if err != nil {
			server.Log.Errorf("get applications error : %v", err)
		}

		time.Sleep(time.Minute)
	}
}

func (n *Notifier) reportEvent(event rpcs.ArgsOnEvent) error {
	server.Log.Debugf("reporting event %v", event)

	device := &models.Device{}
	err := server.RPCCallByName("registry", "Registry.FindDeviceById", int64(event.DeviceId), device)
	if err != nil {
		server.Log.Errorf("find device error : %v", err)
		return err
	}

	product := &models.Product{}
	err = server.RPCCallByName("registry", "Registry.FindProduct", device.ProductID, product)
	if err != nil {
		server.Log.Errorf("find product error : %v", err)
		return err
	}

	c, err := productconfig.New(product.ProductConfig)
	if err != nil {
		server.Log.Errorf("product config error : %v", err)
		return err
	}

	ev := &protocol.Event{}
	ev.Head.No = event.No
	ev.Head.SubDeviceid = event.SubDevice
	ev.Params = event.Params

	m, err := c.EventToMap(ev)
	if err != nil {
		server.Log.Errorf("gen event json error : %v", err)
		return err
	}

	res := ReportPack{
		Tag:        "event",
		Identifier: device.DeviceIdentifier,
		Data:       m,
	}

	jsonRes, err := json.Marshal(res)
	if err != nil {
		server.Log.Errorf("json marshal error : %v", err)
		return err
	}

	reqHead := map[string]string{}
	reqHead["Content-Type"] = "application/json"

	for _, app := range n.apps {
		if nil == checkAppDomain(app.AppDomain, device.DeviceIdentifier) {
			reqHead["App-Token"] = app.AppToken
			_, err := utils.SendHttpRequest(app.ReportUrl, string(jsonRes), "POST", reqHead)
			if err != nil {
				server.Log.Errorf("http post json error : %v", err)
			}
			server.Log.Debugf("http post json succ : %v", string(jsonRes))
		}
	}

	return nil
}

func (n *Notifier) processEvents() error {
	for {
		event := rpcs.ArgsOnEvent{}
		err := n.eventsQueue.Receive(&event)
		if err != nil {
			server.Log.Errorf("error when receiving from queue : %v", err)
			return err
		}
		go n.reportEvent(event)
	}

	return nil
}

func (n *Notifier) Run() error {
	go n.updateApplications()
	go n.processEvents()
	go n.processStatus()

	return nil
}

func RunNotifier() error {
	if notifier == nil {
		notifier, err := NewNotifier(*confRabbitHost)
		if err != nil {
			server.Log.Error(err)
		}
		err = notifier.Run()
		if err != nil {
			server.Log.Error(err)
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package registration

import (
	"fmt"
	"log"
	"net/url"
	"os"
	"sync"
	"time"

	"github.com/influxdb/enterprise-client/v1"
	"github.com/influxdb/influxdb/monitor"
)

// Service represents the registration service.
type Service struct {
	MetaStore interface {
		ClusterID() (uint64, error)
		NodeID() uint64
	}
	Monitor interface {
		Statistics(tags map[string]string) ([]*monitor.Statistic, error)
		RegisterDiagnosticsClient(name string, client monitor.DiagsClient)
	}

	enabled       bool
	url           *url.URL
	token         string
	statsInterval time.Duration
	version       string
	mu            sync.Mutex
	lastContact   time.Time

	wg   sync.WaitGroup
	done chan struct{}

	logger *log.Logger
}

// NewService returns a configured registration service.
func NewService(c Config, version string) (*Service, error) {
	url, err := url.Parse(c.URL)
	if err != nil {
		return nil, err
	}

	return &Service{
		enabled:       c.Enabled,
		url:           url,
		token:         c.Token,
		statsInterval: time.Duration(c.StatsInterval),
		version:       version,
		done:          make(chan struct{}),
		logger:        log.New(os.Stderr, "[registration] ", log.LstdFlags),
	}, nil
}

// Open starts retention policy enforcement.
func (s *Service) Open() error {
	if !s.enabled {
		return nil
	}

	s.logger.Println("Starting registration service")
	if err := s.registerServer(); err != nil {
		return err
	}

	// Register diagnostics if a Monitor service is available.
	if s.Monitor != nil {
		s.Monitor.RegisterDiagnosticsClient("registration", s)
	}

	s.wg.Add(1)
	go s.reportStats()

	return nil
}

// Close stops retention policy enforcement.
func (s *Service) Close() error {
	s.logger.Println("registration service terminating")
	close(s.done)
	s.wg.Wait()
	return nil
}

// Diagnostics returns diagnostics information.
func (s *Service) Diagnostics() (*monitor.Diagnostic, error) {
	diagnostics := map[string]interface{}{
		"URL":          s.url.String(),
		"token":        s.token,
		"last_contact": s.getLastContact().String(),
	}

	return monitor.DiagnosticFromMap(diagnostics), nil
}

// registerServer registers the server.
func (s *Service) registerServer() error {
	if !s.enabled || s.token == "" {
		return nil
	}

	cl := client.New(s.token)
	cl.URL = s.url.String()

	clusterID, err := s.MetaStore.ClusterID()
	if err != nil {
		s.logger.Printf("failed to retrieve cluster ID for registration: %s", err.Error())
		return err
	}
	hostname, err := os.Hostname()
	if err != nil {
		return err
	}

	server := client.Server{
		ClusterID: fmt.Sprintf("%d", clusterID),
		ServerID:  fmt.Sprintf("%d", s.MetaStore.NodeID()),
		Host:      hostname,
		Product:   "influxdb",
		Version:   s.version,
	}

	s.wg.Add(1)
	go func() {
		defer s.wg.Done()

		resp, err := cl.Save(server)

		if err != nil {
			s.logger.Printf("failed to register server with %s: received code %s, error: %s", s.url.String(), resp.Status, err)
			return
		}
		s.updateLastContact(time.Now().UTC())
	}()
	return nil
}

func (s *Service) reportStats() {
	defer s.wg.Done()
	if s.token == "" {
		// No reporting, for now, without token.
		return
	}

	cl := client.New(s.token)
	cl.URL = s.url.String()

	clusterID, err := s.MetaStore.ClusterID()
	if err != nil {
		s.logger.Printf("failed to retrieve cluster ID for registration -- aborting stats upload: %s", err.Error())
		return
	}

	t := time.NewTicker(s.statsInterval)
	for {
		select {
		case <-t.C:
			stats, err := s.Monitor.Statistics(nil)
			if err != nil {
				s.logger.Printf("failed to retrieve statistics: %s", err.Error())
				continue
			}

			st := client.Stats{
				Product:   "influxdb",
				ClusterID: fmt.Sprintf("%d", clusterID),
				ServerID:  fmt.Sprintf("%d", s.MetaStore.NodeID()),
			}
			data := make([]client.StatsData, len(stats))
			for i, x := range stats {
				data[i] = client.StatsData{
					Name:   x.Name,
					Tags:   x.Tags,
					Values: x.Values,
				}
			}
			st.Data = data

			resp, err := cl.Save(st)
			if err != nil {
				s.logger.Printf("failed to post statistics to Enterprise: repsonse code: %d: error: %s", resp.StatusCode, err)
				continue
			}
			s.updateLastContact(time.Now().UTC())

		case <-s.done:
			return
		}
	}
}

func (s *Service) updateLastContact(t time.Time) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.lastContact = t
}

func (s *Service) getLastContact() time.Time {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.lastContact
}
<commit_msg>silence registration logging for testing<commit_after>package registration

import (
	"fmt"
	"log"
	"net/url"
	"os"
	"sync"
	"time"

	"github.com/influxdb/enterprise-client/v1"
	"github.com/influxdb/influxdb/monitor"
)

// Service represents the registration service.
type Service struct {
	MetaStore interface {
		ClusterID() (uint64, error)
		NodeID() uint64
	}
	Monitor interface {
		Statistics(tags map[string]string) ([]*monitor.Statistic, error)
		RegisterDiagnosticsClient(name string, client monitor.DiagsClient)
	}

	enabled       bool
	url           *url.URL
	token         string
	statsInterval time.Duration
	version       string
	mu            sync.Mutex
	lastContact   time.Time

	wg   sync.WaitGroup
	done chan struct{}

	logger *log.Logger
}

// NewService returns a configured registration service.
func NewService(c Config, version string) (*Service, error) {
	url, err := url.Parse(c.URL)
	if err != nil {
		return nil, err
	}

	return &Service{
		enabled:       c.Enabled,
		url:           url,
		token:         c.Token,
		statsInterval: time.Duration(c.StatsInterval),
		version:       version,
		done:          make(chan struct{}),
		logger:        log.New(os.Stderr, "[registration] ", log.LstdFlags),
	}, nil
}

// Open starts retention policy enforcement.
func (s *Service) Open() error {
	if !s.enabled {
		return nil
	}

	s.logger.Println("Starting registration service")
	if err := s.registerServer(); err != nil {
		return err
	}

	// Register diagnostics if a Monitor service is available.
	if s.Monitor != nil {
		s.Monitor.RegisterDiagnosticsClient("registration", s)
	}

	s.wg.Add(1)
	go s.reportStats()

	return nil
}

// Close stops retention policy enforcement.
func (s *Service) Close() error {
	s.logger.Println("registration service terminating")
	close(s.done)
	s.wg.Wait()
	return nil
}

// SetLogger sets the internal logger to the logger passed in.
func (s *Service) SetLogger(l *log.Logger) {
	s.logger = l
}

// Diagnostics returns diagnostics information.
func (s *Service) Diagnostics() (*monitor.Diagnostic, error) {
	diagnostics := map[string]interface{}{
		"URL":          s.url.String(),
		"token":        s.token,
		"last_contact": s.getLastContact().String(),
	}

	return monitor.DiagnosticFromMap(diagnostics), nil
}

// registerServer registers the server.
func (s *Service) registerServer() error {
	if !s.enabled || s.token == "" {
		return nil
	}

	cl := client.New(s.token)
	cl.URL = s.url.String()

	clusterID, err := s.MetaStore.ClusterID()
	if err != nil {
		s.logger.Printf("failed to retrieve cluster ID for registration: %s", err.Error())
		return err
	}
	hostname, err := os.Hostname()
	if err != nil {
		return err
	}

	server := client.Server{
		ClusterID: fmt.Sprintf("%d", clusterID),
		ServerID:  fmt.Sprintf("%d", s.MetaStore.NodeID()),
		Host:      hostname,
		Product:   "influxdb",
		Version:   s.version,
	}

	s.wg.Add(1)
	go func() {
		defer s.wg.Done()

		resp, err := cl.Save(server)

		if err != nil {
			s.logger.Printf("failed to register server with %s: received code %s, error: %s", s.url.String(), resp.Status, err)
			return
		}
		s.updateLastContact(time.Now().UTC())
	}()
	return nil
}

func (s *Service) reportStats() {
	defer s.wg.Done()
	if s.token == "" {
		// No reporting, for now, without token.
		return
	}

	cl := client.New(s.token)
	cl.URL = s.url.String()

	clusterID, err := s.MetaStore.ClusterID()
	if err != nil {
		s.logger.Printf("failed to retrieve cluster ID for registration -- aborting stats upload: %s", err.Error())
		return
	}

	t := time.NewTicker(s.statsInterval)
	for {
		select {
		case <-t.C:
			stats, err := s.Monitor.Statistics(nil)
			if err != nil {
				s.logger.Printf("failed to retrieve statistics: %s", err.Error())
				continue
			}

			st := client.Stats{
				Product:   "influxdb",
				ClusterID: fmt.Sprintf("%d", clusterID),
				ServerID:  fmt.Sprintf("%d", s.MetaStore.NodeID()),
			}
			data := make([]client.StatsData, len(stats))
			for i, x := range stats {
				data[i] = client.StatsData{
					Name:   x.Name,
					Tags:   x.Tags,
					Values: x.Values,
				}
			}
			st.Data = data

			resp, err := cl.Save(st)
			if err != nil {
				s.logger.Printf("failed to post statistics to Enterprise: repsonse code: %d: error: %s", resp.StatusCode, err)
				continue
			}
			s.updateLastContact(time.Now().UTC())

		case <-s.done:
			return
		}
	}
}

func (s *Service) updateLastContact(t time.Time) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.lastContact = t
}

func (s *Service) getLastContact() time.Time {
	s.mu.Lock()
	defer s.mu.Unlock()
	return s.lastContact
}
<|endoftext|>


<commit_before>package htmltest

import (
	"github.com/imdario/mergo"
	"github.com/wjdp/htmltest/issues"
	"github.com/wjdp/htmltest/output"
	"path"
	"testing"
)

// Keep it quiet
const tLogLevel int = issues.LevelNone

// We're running non-concurrently, speed up the tests by turning down the
// timeout. Assumes we're on a good connection.
const tExternalTimeout int = 3

// Raise an error if a specific issue isn't present in the test's store
func tExpectIssue(t *testing.T, hT *HTMLTest, message string, expected int) {
	c := hT.issueStore.MessageMatchCount(message)
	if c != expected {
		hT.issueStore.DumpIssues(true)
		t.Error("expected issue", message, "count", expected, "!=", c)
	}
}

// Raise an error if issue count of errors != expected
func tExpectIssueCount(t *testing.T, hT *HTMLTest, expected int) {
	c := hT.issueStore.Count(issues.LevelError)
	if c != expected {
		hT.issueStore.DumpIssues(true)
		t.Error("expected", expected, "issues,", c, "found")
	}
}

// Default options for running a file test
func defaultFileTestOpts(filename string) map[string]interface{} {
	return map[string]interface{}{
		"DirectoryPath":   path.Dir(filename),
		"FilePath":        path.Base(filename),
		"LogLevel":        tLogLevel,
		"ExternalTimeout": tExternalTimeout,
		"EnableCache":     false,
		"EnableLog":       false,
		"CheckDoctype":    false,
	}
}

// Test a single file and return the run test
func tTestFile(filename string) *HTMLTest {
	hT, err := Test(defaultFileTestOpts(filename))
	output.CheckErrorPanic(err)
	return hT
}

// Test a single file with custom options and return the run test
func tTestFileOpts(filename string, tOpts map[string]interface{}) *HTMLTest {
	opts := defaultFileTestOpts(filename)
	mergo.MergeWithOverwrite(&opts, tOpts)
	hT, err := Test(opts)
	output.CheckErrorPanic(err)
	return hT
}

// Default options for running a directory test
func defaultDirectoryTestOpts(filename string) map[string]interface{} {
	return map[string]interface{}{
		"DirectoryPath":   filename,
		"LogLevel":        tLogLevel,
		"ExternalTimeout": tExternalTimeout,
		"EnableCache":     false,
		"EnableLog":       false,
		"CheckDoctype":    false,
	}
}

// Test a directory and return the run test
func tTestDirectory(filename string) *HTMLTest {
	hT, err := Test(defaultDirectoryTestOpts(filename))
	output.CheckErrorPanic(err)
	return hT
}

// Test a directory with custom options and return the run test
func tTestDirectoryOpts(filename string, tOpts map[string]interface{}) *HTMLTest {
	opts := defaultDirectoryTestOpts(filename)
	mergo.MergeWithOverwrite(&opts, tOpts)
	hT, err := Test(opts)
	output.CheckErrorPanic(err)
	return hT
}

// All tests that make network calls should be marked with this function
func tSkipShortExternal(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test requiring network calls in short mode")
	}
}
<commit_msg>Add quotes around message in tExpectIssue<commit_after>package htmltest

import (
	"github.com/imdario/mergo"
	"github.com/wjdp/htmltest/issues"
	"github.com/wjdp/htmltest/output"
	"path"
	"testing"
)

// Keep it quiet
const tLogLevel int = issues.LevelNone

// We're running non-concurrently, speed up the tests by turning down the
// timeout. Assumes we're on a good connection.
const tExternalTimeout int = 3

// Raise an error if a specific issue isn't present in the test's store
func tExpectIssue(t *testing.T, hT *HTMLTest, message string, expected int) {
	c := hT.issueStore.MessageMatchCount(message)
	if c != expected {
		hT.issueStore.DumpIssues(true)
		t.Error("expected issue", "'"+message+"'", "count", expected, "!=", c)
	}
}

// Raise an error if issue count of errors != expected
func tExpectIssueCount(t *testing.T, hT *HTMLTest, expected int) {
	c := hT.issueStore.Count(issues.LevelError)
	if c != expected {
		hT.issueStore.DumpIssues(true)
		t.Error("expected", expected, "issues,", c, "found")
	}
}

// Default options for running a file test
func defaultFileTestOpts(filename string) map[string]interface{} {
	return map[string]interface{}{
		"DirectoryPath":   path.Dir(filename),
		"FilePath":        path.Base(filename),
		"LogLevel":        tLogLevel,
		"ExternalTimeout": tExternalTimeout,
		"EnableCache":     false,
		"EnableLog":       false,
		"CheckDoctype":    false,
	}
}

// Test a single file and return the run test
func tTestFile(filename string) *HTMLTest {
	hT, err := Test(defaultFileTestOpts(filename))
	output.CheckErrorPanic(err)
	return hT
}

// Test a single file with custom options and return the run test
func tTestFileOpts(filename string, tOpts map[string]interface{}) *HTMLTest {
	opts := defaultFileTestOpts(filename)
	mergo.MergeWithOverwrite(&opts, tOpts)
	hT, err := Test(opts)
	output.CheckErrorPanic(err)
	return hT
}

// Default options for running a directory test
func defaultDirectoryTestOpts(filename string) map[string]interface{} {
	return map[string]interface{}{
		"DirectoryPath":   filename,
		"LogLevel":        tLogLevel,
		"ExternalTimeout": tExternalTimeout,
		"EnableCache":     false,
		"EnableLog":       false,
		"CheckDoctype":    false,
	}
}

// Test a directory and return the run test
func tTestDirectory(filename string) *HTMLTest {
	hT, err := Test(defaultDirectoryTestOpts(filename))
	output.CheckErrorPanic(err)
	return hT
}

// Test a directory with custom options and return the run test
func tTestDirectoryOpts(filename string, tOpts map[string]interface{}) *HTMLTest {
	opts := defaultDirectoryTestOpts(filename)
	mergo.MergeWithOverwrite(&opts, tOpts)
	hT, err := Test(opts)
	output.CheckErrorPanic(err)
	return hT
}

// All tests that make network calls should be marked with this function
func tSkipShortExternal(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test requiring network calls in short mode")
	}
}
<|endoftext|>


<commit_before>package chart

import (
	"testing"

	"github.com/blendlabs/go-assert"
)

type mockValueProvider struct {
	X []float64
	Y []float64
}

func (m mockValueProvider) Len() int {
	return MinInt(len(m.X), len(m.Y))
}

func (m mockValueProvider) GetValue(index int) (x, y float64) {
	x = m.X[index]
	y = m.Y[index]
	return
}

func TestMovingAverageSeriesGetValue(t *testing.T) {
	assert := assert.New(t)

	mockSeries := mockValueProvider{
		Seq(1.0, 10.0),
		Seq(10, 1.0),
	}
	assert.Equal(10, mockSeries.Len())

	mas := &MovingAverageSeries{
		InnerSeries: mockSeries,
		WindowSize:  10,
	}

	var yvalues []float64
	for x := 0; x < mas.Len(); x++ {
		_, y := mas.GetValue(x)
		yvalues = append(yvalues, y)
	}

	assert.Equal(10.0, yvalues[0])
	assert.Equal(9.5, yvalues[1])
	assert.Equal(9.0, yvalues[2])
	assert.Equal(8.5, yvalues[3])
	assert.Equal(8.0, yvalues[4])
	assert.Equal(7.5, yvalues[5])
	assert.Equal(7.0, yvalues[6])
	assert.Equal(6.5, yvalues[7])
	assert.Equal(6.0, yvalues[8])
}

func TestMovingAverageSeriesGetLastValueWindowOverlap(t *testing.T) {
	assert := assert.New(t)

	mockSeries := mockValueProvider{
		Seq(1.0, 10.0),
		Seq(10, 1.0),
	}
	assert.Equal(10, mockSeries.Len())

	mas := &MovingAverageSeries{
		InnerSeries: mockSeries,
		WindowSize:  15,
	}

	lx, ly := mas.GetLastValue()
	assert.Equal(10.0, lx)
	assert.Equal(5.5, ly)
}

func TestMovingAverageSeriesGetLastValue(t *testing.T) {
	assert := assert.New(t)

	mockSeries := mockValueProvider{
		Seq(1.0, 100.0),
		Seq(100, 1.0),
	}
	assert.Equal(100, mockSeries.Len())

	mas := &MovingAverageSeries{
		InnerSeries: mockSeries,
		WindowSize:  10,
	}

	lx, ly := mas.GetLastValue()
	assert.Equal(100.0, lx)
	assert.Equal(5.5, ly)
}
<commit_msg>more rigorous test.<commit_after>package chart

import (
	"testing"

	"github.com/blendlabs/go-assert"
)

type mockValueProvider struct {
	X []float64
	Y []float64
}

func (m mockValueProvider) Len() int {
	return MinInt(len(m.X), len(m.Y))
}

func (m mockValueProvider) GetValue(index int) (x, y float64) {
	x = m.X[index]
	y = m.Y[index]
	return
}

func TestMovingAverageSeriesGetValue(t *testing.T) {
	assert := assert.New(t)

	mockSeries := mockValueProvider{
		Seq(1.0, 10.0),
		Seq(10, 1.0),
	}
	assert.Equal(10, mockSeries.Len())

	mas := &MovingAverageSeries{
		InnerSeries: mockSeries,
		WindowSize:  10,
	}

	var yvalues []float64
	for x := 0; x < mas.Len(); x++ {
		_, y := mas.GetValue(x)
		yvalues = append(yvalues, y)
	}

	assert.Equal(10.0, yvalues[0])
	assert.Equal(9.5, yvalues[1])
	assert.Equal(9.0, yvalues[2])
	assert.Equal(8.5, yvalues[3])
	assert.Equal(8.0, yvalues[4])
	assert.Equal(7.5, yvalues[5])
	assert.Equal(7.0, yvalues[6])
	assert.Equal(6.5, yvalues[7])
	assert.Equal(6.0, yvalues[8])
}

func TestMovingAverageSeriesGetLastValueWindowOverlap(t *testing.T) {
	assert := assert.New(t)

	mockSeries := mockValueProvider{
		Seq(1.0, 10.0),
		Seq(10, 1.0),
	}
	assert.Equal(10, mockSeries.Len())

	mas := &MovingAverageSeries{
		InnerSeries: mockSeries,
		WindowSize:  15,
	}

	lx, ly := mas.GetLastValue()
	assert.Equal(10.0, lx)
	assert.Equal(5.5, ly)
}

func TestMovingAverageSeriesGetLastValue(t *testing.T) {
	assert := assert.New(t)

	mockSeries := mockValueProvider{
		Seq(1.0, 100.0),
		Seq(100, 1.0),
	}
	assert.Equal(100, mockSeries.Len())

	mas := &MovingAverageSeries{
		InnerSeries: mockSeries,
		WindowSize:  10,
	}

	var yvalues []float64
	for x := 0; x < mas.Len(); x++ {
		_, y := mas.GetValue(x)
		yvalues = append(yvalues, y)
	}

	lx, ly := mas.GetLastValue()
	assert.Equal(100.0, lx)
	assert.Equal(5.5, ly)
	assert.Equal(yvalues[len(yvalues)-1], ly)
}
<|endoftext|>


<commit_before>package manager

import (
	"bufio"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"syscall"

	"github.com/Symantec/Dominator/lib/format"
	proto "github.com/Symantec/Dominator/proto/hypervisor"
)

const (
	procMounts    = "/proc/mounts"
	sysClassBlock = "/sys/class/block"
)

type mountInfo struct {
	mountPoint string
	size       uint64
}

func demapDevice(device string) (string, error) {
	sysDir := filepath.Join(sysClassBlock, filepath.Base(device), "slaves")
	if file, err := os.Open(sysDir); err != nil {
		return device, nil
	} else {
		defer file.Close()
		names, err := file.Readdirnames(-1)
		if err != nil {
			return "", err
		}
		if len(names) != 1 {
			return "", fmt.Errorf("%s has %d entries", len(names))
		}
		return filepath.Join("/dev", names[0]), nil
	}
}

func getFreeSpace(dirname string, freeSpaceTable map[string]uint64) (
	uint64, error) {
	if freeSpace, ok := freeSpaceTable[dirname]; ok {
		return freeSpace, nil
	}
	var statbuf syscall.Statfs_t
	if err := syscall.Statfs(dirname, &statbuf); err != nil {
		return 0, fmt.Errorf("error statfsing: %s: %s", dirname, err)
	}
	freeSpace := uint64(statbuf.Bfree * uint64(statbuf.Bsize))
	freeSpaceTable[dirname] = freeSpace
	return freeSpace, nil
}

func getMounts() (map[string]string, error) {
	file, err := os.Open(procMounts)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	scanner := bufio.NewScanner(file)
	mounts := make(map[string]string)
	for scanner.Scan() {
		line := scanner.Text()
		var device, mountPoint, fsType, fsOptions, junk string
		nScanned, err := fmt.Sscanf(line, "%s %s %s %s %s",
			&device, &mountPoint, &fsType, &fsOptions, &junk)
		if err != nil {
			return nil, err
		}
		if nScanned < 4 {
			return nil, errors.New(fmt.Sprintf("only read %d values from %s",
				nScanned, line))
		}
		if mountPoint == "/boot" {
			continue
		}
		if !strings.HasPrefix(device, "/dev/") {
			continue
		}
		if device == "/dev/root" { // Ignore this dumb shit.
			continue
		}
		if target, err := filepath.EvalSymlinks(device); err != nil {
			return nil, err
		} else {
			device = target
		}
		device, err = demapDevice(device)
		if err != nil {
			return nil, err
		}
		device = device[5:]
		if _, ok := mounts[device]; !ok { // Pick the first mount point.
			mounts[device] = mountPoint
		}
	}
	if err := scanner.Err(); err != nil {
		return nil, err
	}
	return mounts, nil
}

func getVolumeDirectories() ([]string, error) {
	mounts, err := getMounts()
	if err != nil {
		return nil, err
	}
	var mountPointsToUse []string
	biggestMounts := make(map[string]mountInfo)
	for device, mountPoint := range mounts {
		sysDir := filepath.Join(sysClassBlock, device)
		linkTarget, err := os.Readlink(sysDir)
		if err != nil {
			if os.IsNotExist(err) {
				continue
			}
			return nil, err
		}
		_, err = os.Stat(filepath.Join(sysDir, "partition"))
		if err != nil {
			if os.IsNotExist(err) { // Not a partition: easy!
				mountPointsToUse = append(mountPointsToUse, mountPoint)
				continue
			}
			return nil, err
		}
		var statbuf syscall.Statfs_t
		if err := syscall.Statfs(mountPoint, &statbuf); err != nil {
			return nil, fmt.Errorf("error statfsing: %s: %s", mountPoint, err)
		}
		size := uint64(statbuf.Blocks * uint64(statbuf.Bsize))
		parentDevice := filepath.Base(filepath.Dir(linkTarget))
		if biggestMount, ok := biggestMounts[parentDevice]; !ok {
			biggestMounts[parentDevice] = mountInfo{mountPoint, size}
		} else if size > biggestMount.size {
			biggestMounts[parentDevice] = mountInfo{mountPoint, size}
		}
	}
	for _, biggestMount := range biggestMounts {
		mountPointsToUse = append(mountPointsToUse, biggestMount.mountPoint)
	}
	var volumeDirectories []string
	for _, mountPoint := range mountPointsToUse {
		volumeDirectories = append(volumeDirectories,
			filepath.Join(mountPoint, "hyper-volumes"))
	}
	sort.Strings(volumeDirectories)
	return volumeDirectories, nil
}

func (m *Manager) findFreeSpace(size uint64, freeSpaceTable map[string]uint64,
	position *int) (string, error) {
	if *position >= len(m.volumeDirectories) {
		*position = 0
	}
	startingPosition := *position
	for {
		freeSpace, err := getFreeSpace(m.volumeDirectories[*position],
			freeSpaceTable)
		if err != nil {
			return "", err
		}
		if size < freeSpace {
			dirname := m.volumeDirectories[*position]
			freeSpaceTable[dirname] -= size
			return dirname, nil
		}
		*position++
		if *position >= len(m.volumeDirectories) {
			*position = 0
		}
		if *position == startingPosition {
			return "", fmt.Errorf("not enough free space for %s volume",
				format.FormatBytes(size))
		}
	}
}

func (m *Manager) getVolumeDirectories(rootSize uint64,
	volumes []proto.Volume, spreadVolumes bool) ([]string, error) {
	sizes := make([]uint64, 1, len(volumes)+1)
	sizes[0] = rootSize
	for _, volume := range volumes {
		if volume.Size > 0 {
			sizes = append(sizes, volume.Size)
		}
	}
	freeSpaceTable := make(map[string]uint64, len(m.volumeDirectories))
	directoriesToUse := make([]string, 0, len(sizes))
	position := 0
	for len(sizes) > 0 {
		dirname, err := m.findFreeSpace(sizes[0], freeSpaceTable, &position)
		if err != nil {
			return nil, err
		}
		directoriesToUse = append(directoriesToUse, dirname)
		sizes = sizes[1:]
		if spreadVolumes {
			position++
		}
	}
	return directoriesToUse, nil
}
<commit_msg>Fix fmt.Errorf() call in hypervisor/manager/volumes.go.<commit_after>package manager

import (
	"bufio"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"strings"
	"syscall"

	"github.com/Symantec/Dominator/lib/format"
	proto "github.com/Symantec/Dominator/proto/hypervisor"
)

const (
	procMounts    = "/proc/mounts"
	sysClassBlock = "/sys/class/block"
)

type mountInfo struct {
	mountPoint string
	size       uint64
}

func demapDevice(device string) (string, error) {
	sysDir := filepath.Join(sysClassBlock, filepath.Base(device), "slaves")
	if file, err := os.Open(sysDir); err != nil {
		return device, nil
	} else {
		defer file.Close()
		names, err := file.Readdirnames(-1)
		if err != nil {
			return "", err
		}
		if len(names) != 1 {
			return "", fmt.Errorf("%s has %d entries", device, len(names))
		}
		return filepath.Join("/dev", names[0]), nil
	}
}

func getFreeSpace(dirname string, freeSpaceTable map[string]uint64) (
	uint64, error) {
	if freeSpace, ok := freeSpaceTable[dirname]; ok {
		return freeSpace, nil
	}
	var statbuf syscall.Statfs_t
	if err := syscall.Statfs(dirname, &statbuf); err != nil {
		return 0, fmt.Errorf("error statfsing: %s: %s", dirname, err)
	}
	freeSpace := uint64(statbuf.Bfree * uint64(statbuf.Bsize))
	freeSpaceTable[dirname] = freeSpace
	return freeSpace, nil
}

func getMounts() (map[string]string, error) {
	file, err := os.Open(procMounts)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	scanner := bufio.NewScanner(file)
	mounts := make(map[string]string)
	for scanner.Scan() {
		line := scanner.Text()
		var device, mountPoint, fsType, fsOptions, junk string
		nScanned, err := fmt.Sscanf(line, "%s %s %s %s %s",
			&device, &mountPoint, &fsType, &fsOptions, &junk)
		if err != nil {
			return nil, err
		}
		if nScanned < 4 {
			return nil, errors.New(fmt.Sprintf("only read %d values from %s",
				nScanned, line))
		}
		if mountPoint == "/boot" {
			continue
		}
		if !strings.HasPrefix(device, "/dev/") {
			continue
		}
		if device == "/dev/root" { // Ignore this dumb shit.
			continue
		}
		if target, err := filepath.EvalSymlinks(device); err != nil {
			return nil, err
		} else {
			device = target
		}
		device, err = demapDevice(device)
		if err != nil {
			return nil, err
		}
		device = device[5:]
		if _, ok := mounts[device]; !ok { // Pick the first mount point.
			mounts[device] = mountPoint
		}
	}
	if err := scanner.Err(); err != nil {
		return nil, err
	}
	return mounts, nil
}

func getVolumeDirectories() ([]string, error) {
	mounts, err := getMounts()
	if err != nil {
		return nil, err
	}
	var mountPointsToUse []string
	biggestMounts := make(map[string]mountInfo)
	for device, mountPoint := range mounts {
		sysDir := filepath.Join(sysClassBlock, device)
		linkTarget, err := os.Readlink(sysDir)
		if err != nil {
			if os.IsNotExist(err) {
				continue
			}
			return nil, err
		}
		_, err = os.Stat(filepath.Join(sysDir, "partition"))
		if err != nil {
			if os.IsNotExist(err) { // Not a partition: easy!
				mountPointsToUse = append(mountPointsToUse, mountPoint)
				continue
			}
			return nil, err
		}
		var statbuf syscall.Statfs_t
		if err := syscall.Statfs(mountPoint, &statbuf); err != nil {
			return nil, fmt.Errorf("error statfsing: %s: %s", mountPoint, err)
		}
		size := uint64(statbuf.Blocks * uint64(statbuf.Bsize))
		parentDevice := filepath.Base(filepath.Dir(linkTarget))
		if biggestMount, ok := biggestMounts[parentDevice]; !ok {
			biggestMounts[parentDevice] = mountInfo{mountPoint, size}
		} else if size > biggestMount.size {
			biggestMounts[parentDevice] = mountInfo{mountPoint, size}
		}
	}
	for _, biggestMount := range biggestMounts {
		mountPointsToUse = append(mountPointsToUse, biggestMount.mountPoint)
	}
	var volumeDirectories []string
	for _, mountPoint := range mountPointsToUse {
		volumeDirectories = append(volumeDirectories,
			filepath.Join(mountPoint, "hyper-volumes"))
	}
	sort.Strings(volumeDirectories)
	return volumeDirectories, nil
}

func (m *Manager) findFreeSpace(size uint64, freeSpaceTable map[string]uint64,
	position *int) (string, error) {
	if *position >= len(m.volumeDirectories) {
		*position = 0
	}
	startingPosition := *position
	for {
		freeSpace, err := getFreeSpace(m.volumeDirectories[*position],
			freeSpaceTable)
		if err != nil {
			return "", err
		}
		if size < freeSpace {
			dirname := m.volumeDirectories[*position]
			freeSpaceTable[dirname] -= size
			return dirname, nil
		}
		*position++
		if *position >= len(m.volumeDirectories) {
			*position = 0
		}
		if *position == startingPosition {
			return "", fmt.Errorf("not enough free space for %s volume",
				format.FormatBytes(size))
		}
	}
}

func (m *Manager) getVolumeDirectories(rootSize uint64,
	volumes []proto.Volume, spreadVolumes bool) ([]string, error) {
	sizes := make([]uint64, 1, len(volumes)+1)
	sizes[0] = rootSize
	for _, volume := range volumes {
		if volume.Size > 0 {
			sizes = append(sizes, volume.Size)
		}
	}
	freeSpaceTable := make(map[string]uint64, len(m.volumeDirectories))
	directoriesToUse := make([]string, 0, len(sizes))
	position := 0
	for len(sizes) > 0 {
		dirname, err := m.findFreeSpace(sizes[0], freeSpaceTable, &position)
		if err != nil {
			return nil, err
		}
		directoriesToUse = append(directoriesToUse, dirname)
		sizes = sizes[1:]
		if spreadVolumes {
			position++
		}
	}
	return directoriesToUse, nil
}
<|endoftext|>


<commit_before>// Copyright 2015-2016, Cyrill @ Schumacher.fm and the CoreStore contributors
//
// 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 backendjwt

import (
	"github.com/corestoreio/csfw/config"
	"github.com/corestoreio/csfw/net/jwt"
	"github.com/corestoreio/csfw/store/scope"
	"github.com/corestoreio/csfw/util/csjwt"
	"github.com/corestoreio/csfw/util/errors"
)

// PrepareOptions creates a closure around the type Backend. The closure will be
// used during a scoped request to figure out the configuration depending on the
// incoming scope. An option array will be returned by the closure.
func PrepareOptions(be *Configuration) jwt.OptionFactoryFunc {
	return func(sg config.Scoped) []jwt.Option {
		var (
			opts  [6]jwt.Option
			i     int // used as index in opts
			scp   scope.Scope
			scpID int64
		)

		off, h, err := be.NetJwtDisabled.Get(sg)
		if err != nil {
			return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtDisabled.Get"))
		}
		scp, scpID = h.Unpack()
		opts[i] = jwt.WithDisable(scp, scpID, off)
		i++

		exp, h, err := be.NetJwtExpiration.Get(sg)
		if err != nil {
			return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtExpiration.Get"))
		}
		scp, scpID = h.Unpack()
		opts[i] = jwt.WithExpiration(scp, scpID, exp)
		i++

		skew, h, err := be.NetJwtSkew.Get(sg)
		if err != nil {
			return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtSkew.Get"))
		}
		scp, scpID = h.Unpack()
		opts[i] = jwt.WithSkew(scp, scpID, skew)
		i++

		isSU, h, err := be.NetJwtSingleTokenUsage.Get(sg)
		if err != nil {
			return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtSingleUsage.Get"))
		}
		scp, scpID = h.Unpack()
		opts[i] = jwt.WithSingleTokenUsage(scp, scpID, isSU)
		i++

		// todo: avoid the next code and use OptionFactories to apply a signing method. Example in ratelimit package.

		signingMethod, h, err := be.NetJwtSigningMethod.Get(sg)
		if err != nil {
			return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtSigningMethod.Get"))
		}
		scp, scpID = h.Unpack()

		var key csjwt.Key

		switch signingMethod.Alg() {
		case csjwt.RS256, csjwt.RS384, csjwt.RS512:

			rsaKey, _, err := be.NetJwtRSAKey.Get(sg)
			if err != nil {
				return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtRSAKey.Get"))
			}
			rsaPW, _, err := be.NetJwtRSAKeyPassword.Get(sg)
			if err != nil {
				return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtRSAKeyPassword.Get"))
			}
			key = csjwt.WithRSAPrivateKeyFromPEM(rsaKey, rsaPW)

		case csjwt.ES256, csjwt.ES384, csjwt.ES512:

			ecdsaKey, _, err := be.NetJwtECDSAKey.Get(sg)
			if err != nil {
				return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtECDSAKey.Get"))
			}
			ecdsaPW, _, err := be.NetJwtECDSAKeyPassword.Get(sg)
			if err != nil {
				return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtECDSAKeyPassword.Get"))
			}
			key = csjwt.WithECPrivateKeyFromPEM(ecdsaKey, ecdsaPW)

		case csjwt.HS256, csjwt.HS384, csjwt.HS512:

			password, _, err := be.NetJwtHmacPassword.Get(sg)
			if err != nil {
				return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtHmacPassword.Get"))
			}
			key = csjwt.WithPassword(password)

		default:
			return jwt.OptionsError(errors.Errorf("[jwt] Unknown signing method: %q", signingMethod.Alg()))
		}

		// WithSigningMethod must be added at the end of the slice to overwrite default signing methods
		opts[i] = jwt.WithKey(scp, scpID, key)
		i++
		opts[i] = jwt.WithSigningMethod(scp, scpID, signingMethod)
		return opts[:]
	}
}
<commit_msg>net/jwt/backendjwt: Use scope.Hashes to figure out the lowest scope<commit_after>// Copyright 2015-2016, Cyrill @ Schumacher.fm and the CoreStore contributors
//
// 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 backendjwt

import (
	"github.com/corestoreio/csfw/config"
	"github.com/corestoreio/csfw/net/jwt"
	"github.com/corestoreio/csfw/store/scope"
	"github.com/corestoreio/csfw/util/csjwt"
	"github.com/corestoreio/csfw/util/errors"
)

// PrepareOptions creates a closure around the type Backend. The closure will be
// used during a scoped request to figure out the configuration depending on the
// incoming scope. An option array will be returned by the closure.
func PrepareOptions(be *Configuration) jwt.OptionFactoryFunc {
	return func(sg config.Scoped) []jwt.Option {
		var (
			opts  [6]jwt.Option
			i     int // used as index in opts
			scp   scope.Scope
			scpID int64
		)

		off, h, err := be.NetJwtDisabled.Get(sg)
		if err != nil {
			return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtDisabled.Get"))
		}
		scp, scpID = h.Unpack()
		opts[i] = jwt.WithDisable(scp, scpID, off)
		i++

		exp, h, err := be.NetJwtExpiration.Get(sg)
		if err != nil {
			return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtExpiration.Get"))
		}
		scp, scpID = h.Unpack()
		opts[i] = jwt.WithExpiration(scp, scpID, exp)
		i++

		skew, h, err := be.NetJwtSkew.Get(sg)
		if err != nil {
			return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtSkew.Get"))
		}
		scp, scpID = h.Unpack()
		opts[i] = jwt.WithSkew(scp, scpID, skew)
		i++

		isSU, h, err := be.NetJwtSingleTokenUsage.Get(sg)
		if err != nil {
			return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtSingleUsage.Get"))
		}
		scp, scpID = h.Unpack()
		opts[i] = jwt.WithSingleTokenUsage(scp, scpID, isSU)
		i++

		// todo: avoid the next code and use OptionFactories to apply a signing method. Example in ratelimit package.

		signingMethod, h, err := be.NetJwtSigningMethod.Get(sg)
		if err != nil {
			return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtSigningMethod.Get"))
		}

		// in case we later support store scope the hashes variable protects use
		// from applying the incorrect scope to a functional option.
		var hashes = make(scope.Hashes, 0, 5)
		var key csjwt.Key
		hashes = append(hashes, h)

		switch signingMethod.Alg() {
		case csjwt.RS256, csjwt.RS384, csjwt.RS512:
			rsaKey, h1, err := be.NetJwtRSAKey.Get(sg)
			if err != nil {
				return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtRSAKey.Get"))
			}
			rsaPW, h2, err := be.NetJwtRSAKeyPassword.Get(sg)
			if err != nil {
				return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtRSAKeyPassword.Get"))
			}
			key = csjwt.WithRSAPrivateKeyFromPEM(rsaKey, rsaPW)
			hashes = append(hashes, h1, h2)
		case csjwt.ES256, csjwt.ES384, csjwt.ES512:

			ecdsaKey, h1, err := be.NetJwtECDSAKey.Get(sg)
			if err != nil {
				return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtECDSAKey.Get"))
			}
			ecdsaPW, h2, err := be.NetJwtECDSAKeyPassword.Get(sg)
			if err != nil {
				return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtECDSAKeyPassword.Get"))
			}
			key = csjwt.WithECPrivateKeyFromPEM(ecdsaKey, ecdsaPW)
			hashes = append(hashes, h1, h2)
		case csjwt.HS256, csjwt.HS384, csjwt.HS512:

			password, h1, err := be.NetJwtHmacPassword.Get(sg)
			if err != nil {
				return jwt.OptionsError(errors.Wrap(err, "[backendjwt] NetJwtHmacPassword.Get"))
			}
			key = csjwt.WithPassword(password)
			hashes = append(hashes, h1)
		default:
			return jwt.OptionsError(errors.Errorf("[jwt] Unknown signing method: %q", signingMethod.Alg()))
		}

		// figure out the common lowest scope to apply.
		newH, err := hashes.Lowest()
		if err != nil {
			return jwt.OptionsError(errors.Wrap(err, "[backendjwt] Hashes.Lowest"))
		}
		scp, scpID = newH.Unpack()

		// WithSigningMethod must be added at the end of the slice to overwrite
		// default signing methods
		opts[i] = jwt.WithKey(scp, scpID, key)
		i++
		opts[i] = jwt.WithSigningMethod(scp, scpID, signingMethod)
		return opts[:]
	}
}
<|endoftext|>


<commit_before>package infinispan

import (
	"bytes"
	"testing"
	"time"
)

const conf = `
		{
		 "servers":[
			 {"host": "127.0.0.1", "port": 11222}
		 ],
		 "cacheName": ""
		}
	`

func TestSimplePutAndGet(t *testing.T) {

	if c, err := NewClientJSON(conf); err == nil {
		defer c.Close()

		if _, errPut := c.Put([]byte("1"), []byte("foo")); errPut != nil {
			t.Error(errPut.Error())
		}

		if _, errPut := c.Put([]byte("2"), []byte("bar")); errPut != nil {
			t.Error(errPut.Error())
		}

		if _, errPut := c.Put([]byte("3"), []byte("ugol")); errPut != nil {
			t.Error(errPut.Error())
		}

		if ugol, errGet := c.Get([]byte("3")); errGet == nil {
			if !bytes.Equal([]byte("ugol"), ugol.object) {
				t.Errorf("Expected %v, was %v", []byte("ugol"), ugol)
			}
		} else {
			t.Error(errGet.Error())
		}

		if notFound, errGet := c.Get([]byte("4")); errGet == nil {
			if !bytes.Equal([]byte(""), notFound.object) {
				t.Errorf("Expected %v, was %v", []byte(""), notFound)
			}
		} else {
			t.Error(errGet.Error())
		}

	} else {
		t.Error(err.Error())
		return
	}

}

func TestLifespanPut(t *testing.T) {

	if c, err := NewClientJSON(conf); err == nil {
		defer c.Close()

		opts := map[string]string{
			"lifespan": "10ms",
		}

		c.PutWithOptions([]byte("100"), []byte("T"), opts)

		if found, errGet := c.Get([]byte("100")); errGet == nil {
			if !bytes.Equal([]byte("T"), found.object) {
				t.Errorf("Expected %v, was %v", []byte("T"), found)
			}
		} else {
			t.Error(errGet.Error())
		}

		time.Sleep(20 * time.Millisecond)

		if notFound, errGet := c.Get([]byte("100")); errGet == nil {
			if !bytes.Equal([]byte(""), notFound.object) {
				t.Errorf("Expected %v, was %v", []byte(""), notFound)
			}
		} else {
			t.Error(errGet.Error())
		}

	} else {
		t.Error(err.Error())
		return
	}

}
<commit_msg>Added a maxidle test<commit_after>package infinispan

import (
	"bytes"
	"testing"
	"time"
)

const conf = `
		{
		 "servers":[
			 {"host": "127.0.0.1", "port": 11222}
		 ],
		 "cacheName": ""
		}
	`

func TestSimplePutAndGet(t *testing.T) {

	if c, err := NewClientJSON(conf); err == nil {
		defer c.Close()

		if _, errPut := c.Put([]byte("1"), []byte("foo")); errPut != nil {
			t.Error(errPut.Error())
		}

		if _, errPut := c.Put([]byte("2"), []byte("bar")); errPut != nil {
			t.Error(errPut.Error())
		}

		if _, errPut := c.Put([]byte("3"), []byte("ugol")); errPut != nil {
			t.Error(errPut.Error())
		}

		if ugol, errGet := c.Get([]byte("3")); errGet == nil {
			if !bytes.Equal([]byte("ugol"), ugol.object) {
				t.Errorf("Expected %v, was %v", []byte("ugol"), ugol)
			}
		} else {
			t.Error(errGet.Error())
		}

		if notFound, errGet := c.Get([]byte("4")); errGet == nil {
			if !bytes.Equal([]byte(""), notFound.object) {
				t.Errorf("Expected %v, was %v", []byte(""), notFound)
			}
		} else {
			t.Error(errGet.Error())
		}

	} else {
		t.Error(err.Error())
		return
	}

}

func TestLifespanAndMaxidlePut(t *testing.T) {

	if c, err := NewClientJSON(conf); err == nil {
		defer c.Close()

		opts := map[string]string{
			"lifespan": "10ms",
		}

		c.PutWithOptions([]byte("100"), []byte("T"), opts)

		if found, errGet := c.Get([]byte("100")); errGet == nil {
			if !bytes.Equal([]byte("T"), found.object) {
				t.Errorf("Expected %v, was %v", []byte("T"), found)
			}
		} else {
			t.Error(errGet.Error())
		}

		time.Sleep(10 * time.Millisecond)

		if notFound, errGet := c.Get([]byte("100")); errGet == nil {
			if !bytes.Equal([]byte(""), notFound.object) {
				t.Errorf("Expected %v, was %v", []byte(""), notFound)
			}
		} else {
			t.Error(errGet.Error())
		}

		opts = map[string]string{
			"maxidle": "10ms",
		}

		c.PutWithOptions([]byte("200"), []byte("T"), opts)

		if found, errGet := c.Get([]byte("200")); errGet == nil {
			if !bytes.Equal([]byte("T"), found.object) {
				t.Errorf("Expected %v, was %v", []byte("T"), found)
			}
		} else {
			t.Error(errGet.Error())
		}

		time.Sleep(10 * time.Millisecond)

		if notFound, errGet := c.Get([]byte("200")); errGet == nil {
			if !bytes.Equal([]byte(""), notFound.object) {
				t.Errorf("Expected %v, was %v", []byte(""), notFound)
			}
		} else {
			t.Error(errGet.Error())
		}

	} else {
		t.Error(err.Error())
		return
	}

}
<|endoftext|>


<commit_before>package integrationtests

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"runtime"
	"strconv"
	"time"

	_ "github.com/lucas-clemente/quic-clients" // download clients
	"github.com/lucas-clemente/quic-go/integrationtests/proxy"
	"github.com/lucas-clemente/quic-go/protocol"
	"github.com/lucas-clemente/quic-go/utils"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("Drop Proxy", func() {
	BeforeEach(func() {
		dataMan.GenerateData(dataLen)
	})

	var dropproxy *proxy.UDPProxy

	runDropTest := func(incomingPacketDropper, outgoingPacketDropper proxy.DropCallback, version protocol.VersionNumber) {
		utils.SetLogLevel(utils.LogLevelInfo)
		proxyPort := 12345

		clientPath := fmt.Sprintf(
			"%s/src/github.com/lucas-clemente/quic-clients/client-%s-debug",
			os.Getenv("GOPATH"),
			runtime.GOOS,
		)

		iPort, _ := strconv.Atoi(port)
		var err error
		dropproxy, err = proxy.NewUDPProxy(proxyPort, "localhost", iPort, incomingPacketDropper, outgoingPacketDropper, 0, 0)
		Expect(err).ToNot(HaveOccurred())

		command := exec.Command(
			clientPath,
			"--quic-version="+strconv.Itoa(int(version)),
			"--host=127.0.0.1",
			"--port="+strconv.Itoa(proxyPort),
			"https://quic.clemente.io/data",
		)

		session, err := Start(command, GinkgoWriter, GinkgoWriter)
		Expect(err).NotTo(HaveOccurred())
		defer session.Kill()
		Eventually(session, 20).Should(Exit(0))
		Expect(bytes.Contains(session.Out.Contents(), dataMan.GetData())).To(BeTrue())
	}

	AfterEach(func() {
		dropproxy.Stop()
		time.Sleep(time.Millisecond)
		utils.SetLogLevel(utils.LogLevelNothing)
	})

	for i := range protocol.SupportedVersions {
		version := protocol.SupportedVersions[i]

		Context(fmt.Sprintf("with quic version %d", version), func() {
			Context("dropping every 4th packet after the crypto handshake", func() {
				dropper := func(p protocol.PacketNumber) bool {
					if p <= 10 { // don't interfere with the crypto handshake
						return false
					}
					return p%4 == 0
				}

				It("gets a file when many outgoing packets are dropped", func() {
					runDropTest(nil, dropper, version)
				})

				It("gets a file when many incoming packets are dropped", func() {
					runDropTest(dropper, nil, version)
				})
			})
		})
	}
})
<commit_msg>disable flaky drop test<commit_after>package integrationtests

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"runtime"
	"strconv"
	"time"

	_ "github.com/lucas-clemente/quic-clients" // download clients
	"github.com/lucas-clemente/quic-go/integrationtests/proxy"
	"github.com/lucas-clemente/quic-go/protocol"
	"github.com/lucas-clemente/quic-go/utils"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gexec"
)

var _ = PDescribe("Drop Proxy", func() {
	BeforeEach(func() {
		dataMan.GenerateData(dataLen)
	})

	var dropproxy *proxy.UDPProxy

	runDropTest := func(incomingPacketDropper, outgoingPacketDropper proxy.DropCallback, version protocol.VersionNumber) {
		utils.SetLogLevel(utils.LogLevelInfo)
		proxyPort := 12345

		clientPath := fmt.Sprintf(
			"%s/src/github.com/lucas-clemente/quic-clients/client-%s-debug",
			os.Getenv("GOPATH"),
			runtime.GOOS,
		)

		iPort, _ := strconv.Atoi(port)
		var err error
		dropproxy, err = proxy.NewUDPProxy(proxyPort, "localhost", iPort, incomingPacketDropper, outgoingPacketDropper, 0, 0)
		Expect(err).ToNot(HaveOccurred())

		command := exec.Command(
			clientPath,
			"--quic-version="+strconv.Itoa(int(version)),
			"--host=127.0.0.1",
			"--port="+strconv.Itoa(proxyPort),
			"https://quic.clemente.io/data",
		)

		session, err := Start(command, GinkgoWriter, GinkgoWriter)
		Expect(err).NotTo(HaveOccurred())
		defer session.Kill()
		Eventually(session, 20).Should(Exit(0))
		Expect(bytes.Contains(session.Out.Contents(), dataMan.GetData())).To(BeTrue())
	}

	AfterEach(func() {
		dropproxy.Stop()
		time.Sleep(time.Millisecond)
		utils.SetLogLevel(utils.LogLevelNothing)
	})

	for i := range protocol.SupportedVersions {
		version := protocol.SupportedVersions[i]

		Context(fmt.Sprintf("with quic version %d", version), func() {
			Context("dropping every 4th packet after the crypto handshake", func() {
				dropper := func(p protocol.PacketNumber) bool {
					if p <= 10 { // don't interfere with the crypto handshake
						return false
					}
					return p%4 == 0
				}

				It("gets a file when many outgoing packets are dropped", func() {
					runDropTest(nil, dropper, version)
				})

				It("gets a file when many incoming packets are dropped", func() {
					runDropTest(dropper, nil, version)
				})
			})
		})
	}
})
<|endoftext|>


<commit_before>// Copyright 2015 Google Inc. 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 buffer

import (
	"fmt"
	"io"
	"syscall"
	"unsafe"

	"github.com/jacobsa/fuse/internal/fusekernel"
)

// All requests read from the kernel, without data, are shorter than
// this.
const pageSize = 4096

func init() {
	// Confirm the page size.
	if syscall.Getpagesize() != pageSize {
		panic(fmt.Sprintf("Page size is unexpectedly %d", syscall.Getpagesize()))
	}
}

// We size the buffer to have enough room for a fuse request plus data
// associated with a write request.
const bufSize = pageSize + MaxWriteSize

// An incoming message from the kernel, including leading fusekernel.InHeader
// struct. Provides storage for messages and convenient access to their
// contents.
type InMessage struct {
	remaining []byte
	storage   [bufSize]byte
}

// Initialize with the data read by a single call to r.Read. The first call to
// Consume will consume the bytes directly after the fusekernel.InHeader
// struct.
func (m *InMessage) Init(r io.Reader) error {
	n, err := r.Read(m.storage[:])
	if err != nil {
		return err
	}

	// Make sure the message is long enough.
	const headerSize = unsafe.Sizeof(fusekernel.InHeader{})
	if uintptr(n) < headerSize {
		return fmt.Errorf("Unexpectedly read only %d bytes.", n)
	}

	m.remaining = m.storage[headerSize:n]

	// Check the header's length.
	if int(m.Header().Len) != n {
		return fmt.Errorf(
			"Header says %d bytes, but we read %d",
			m.Header().Len,
			n)
	}

	return nil
}

// Return a reference to the header read in the most recent call to Init.
func (m *InMessage) Header() *fusekernel.InHeader {
	return (*fusekernel.InHeader)(unsafe.Pointer(&m.storage[0]))
}

// Return the number of bytes left to consume.
func (m *InMessage) Len() uintptr {
	return uintptr(len(m.remaining))
}

// Consume the next n bytes from the message, returning a nil pointer if there
// are fewer than n bytes available.
func (m *InMessage) Consume(n uintptr) unsafe.Pointer {
	if m.Len() == 0 || n > m.Len() {
		return nil
	}

	p := unsafe.Pointer(&m.remaining[0])
	m.remaining = m.remaining[n:]

	return p
}

// Equivalent to Consume, except returns a slice of bytes. The result will be
// nil if Consume would fail.
func (m *InMessage) ConsumeBytes(n uintptr) []byte {
	if n > m.Len() {
		return nil
	}

	b := m.remaining[:n]
	m.remaining = m.remaining[n:]

	return b
}
<commit_msg>Calculate pageSize and bufSize at run-time (#102)<commit_after>// Copyright 2015 Google Inc. 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 buffer

import (
	"fmt"
	"io"
	"syscall"
	"unsafe"

	"github.com/jacobsa/fuse/internal/fusekernel"
)

// All requests read from the kernel, without data, are shorter than
// this.
var pageSize int

// We size the buffer to have enough room for a fuse request plus data
// associated with a write request.
var bufSize int

func init() {
	pageSize = syscall.Getpagesize()
	bufSize = pageSize + MaxWriteSize
}

// An incoming message from the kernel, including leading fusekernel.InHeader
// struct. Provides storage for messages and convenient access to their
// contents.
type InMessage struct {
	remaining []byte
	storage   []byte
}

// Initialize with the data read by a single call to r.Read. The first call to
// Consume will consume the bytes directly after the fusekernel.InHeader
// struct.
func (m *InMessage) Init(r io.Reader) error {
	m.storage = make([]byte, bufSize, bufSize)
	n, err := r.Read(m.storage[:])
	if err != nil {
		return err
	}

	// Make sure the message is long enough.
	const headerSize = unsafe.Sizeof(fusekernel.InHeader{})
	if uintptr(n) < headerSize {
		return fmt.Errorf("Unexpectedly read only %d bytes.", n)
	}

	m.remaining = m.storage[headerSize:n]

	// Check the header's length.
	if int(m.Header().Len) != n {
		return fmt.Errorf(
			"Header says %d bytes, but we read %d",
			m.Header().Len,
			n)
	}

	return nil
}

// Return a reference to the header read in the most recent call to Init.
func (m *InMessage) Header() *fusekernel.InHeader {
	return (*fusekernel.InHeader)(unsafe.Pointer(&m.storage[0]))
}

// Return the number of bytes left to consume.
func (m *InMessage) Len() uintptr {
	return uintptr(len(m.remaining))
}

// Consume the next n bytes from the message, returning a nil pointer if there
// are fewer than n bytes available.
func (m *InMessage) Consume(n uintptr) unsafe.Pointer {
	if m.Len() == 0 || n > m.Len() {
		return nil
	}

	p := unsafe.Pointer(&m.remaining[0])
	m.remaining = m.remaining[n:]

	return p
}

// Equivalent to Consume, except returns a slice of bytes. The result will be
// nil if Consume would fail.
func (m *InMessage) ConsumeBytes(n uintptr) []byte {
	if n > m.Len() {
		return nil
	}

	b := m.remaining[:n]
	m.remaining = m.remaining[n:]

	return b
}
<|endoftext|>


<commit_before>package nsqd

import (
	"math/rand"
	"sort"
	"testing"

	"github.com/bmizerany/assert"
)

func TestPriorityQueue(t *testing.T) {
	c := 100
	pq := newInFlightPqueue(c)

	for i := 0; i < c+1; i++ {
		pq.Push(&Message{clientID: int64(i), pri: int64(i)})
	}
	assert.Equal(t, len(pq), c+1)
	assert.Equal(t, cap(pq), c*2)

	for i := 0; i < c+1; i++ {
		msg := pq.Pop()
		assert.Equal(t, msg.clientID, int64(i))
	}
	assert.Equal(t, cap(pq), c/4)
}

func TestUnsortedInsert(t *testing.T) {
	c := 100
	pq := newInFlightPqueue(c)
	ints := make([]int, 0, c)

	for i := 0; i < c; i++ {
		v := rand.Int()
		ints = append(ints, v)
		pq.Push(&Message{pri: int64(v)})
	}
	assert.Equal(t, len(pq), c)
	assert.Equal(t, cap(pq), c)

	sort.Sort(sort.IntSlice(ints))

	for i := 0; i < c; i++ {
		msg, _ := pq.PeekAndShift(int64(ints[len(ints)-1]))
		assert.Equal(t, msg.pri, int64(ints[i]))
	}
}

func TestRemove(t *testing.T) {
	c := 100
	pq := newInFlightPqueue(c)

	for i := 0; i < c; i++ {
		v := rand.Int()
		pq.Push(&Message{pri: int64(v)})
	}

	for i := 0; i < 10; i++ {
		pq.Remove(rand.Intn((c - 1) - i))
	}

	lastPriority := pq.Pop().pri
	for i := 0; i < (c - 10 - 1); i++ {
		msg := pq.Pop()
		assert.Equal(t, lastPriority < msg.pri, true)
		lastPriority = msg.pri
	}
}
<commit_msg>nsqd: improve in flight pqueue remove test<commit_after>package nsqd

import (
	"fmt"
	"math/rand"
	"sort"
	"testing"

	"github.com/bmizerany/assert"
)

func TestPriorityQueue(t *testing.T) {
	c := 100
	pq := newInFlightPqueue(c)

	for i := 0; i < c+1; i++ {
		pq.Push(&Message{clientID: int64(i), pri: int64(i)})
	}
	assert.Equal(t, len(pq), c+1)
	assert.Equal(t, cap(pq), c*2)

	for i := 0; i < c+1; i++ {
		msg := pq.Pop()
		assert.Equal(t, msg.clientID, int64(i))
	}
	assert.Equal(t, cap(pq), c/4)
}

func TestUnsortedInsert(t *testing.T) {
	c := 100
	pq := newInFlightPqueue(c)
	ints := make([]int, 0, c)

	for i := 0; i < c; i++ {
		v := rand.Int()
		ints = append(ints, v)
		pq.Push(&Message{pri: int64(v)})
	}
	assert.Equal(t, len(pq), c)
	assert.Equal(t, cap(pq), c)

	sort.Sort(sort.IntSlice(ints))

	for i := 0; i < c; i++ {
		msg, _ := pq.PeekAndShift(int64(ints[len(ints)-1]))
		assert.Equal(t, msg.pri, int64(ints[i]))
	}
}

func TestRemove(t *testing.T) {
	c := 100
	pq := newInFlightPqueue(c)

	msgs := make(map[MessageID]*Message)
	for i := 0; i < c; i++ {
		m := &Message{pri: int64(rand.Intn(100000000))}
		copy(m.ID[:], fmt.Sprintf("%016d", m.pri))
		msgs[m.ID] = m
		pq.Push(m)
	}

	for i := 0; i < 10; i++ {
		idx := rand.Intn((c - 1) - i)
		var fm *Message
		for _, m := range msgs {
			if m.index == idx {
				fm = m
				break
			}
		}
		rm := pq.Remove(idx)
		assert.Equal(t, fmt.Sprintf("%s", fm.ID), fmt.Sprintf("%s", rm.ID))
	}

	lastPriority := pq.Pop().pri
	for i := 0; i < (c - 10 - 1); i++ {
		msg := pq.Pop()
		assert.Equal(t, lastPriority <= msg.pri, true)
		lastPriority = msg.pri
	}
}
<|endoftext|>


<commit_before>// Copyright 2017 by caixw, All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package entry

import (
	"bytes"
	"fmt"
	"strings"

	"github.com/issue9/mux/internal/syntax"
)

// 表示命名参数中的某个节点
type node struct {
	value    string // 当前节点的值。
	endByte  byte   // 下一个节点的起始字符
	isString bool   // 当前节点是否为一个字符串
}

// 命名参数是正则表达式的简化版本，
// 在一个参数中未指定正则表达式，默认使用此类型，
// 性能会比用正则好一些。
type named struct {
	*base
	nodes []*node
}

// 声明一个新的 named 实例。
func newNamed(s *syntax.Syntax) *named {
	b := newBase(s)

	str := s.Patterns[len(s.Patterns)-1]
	if b.wildcard {
		str = str[:len(str)-2]
		if len(str) == 0 {
			s.Patterns = s.Patterns[:len(s.Patterns)-1]
		} else {
			s.Patterns[len(s.Patterns)-1] = str
		}
	}

	nodes := make([]*node, 0, len(s.Patterns))
	for index, str := range s.Patterns {
		if str[0] == syntax.Start {
			endByte := byte('/')
			if index < len(s.Patterns)-1 {
				endByte = s.Patterns[index+1][0]
			}
			nodes = append(nodes, &node{
				value:    str[1 : len(str)-1],
				isString: false,
				endByte:  endByte,
			})
		} else {
			nodes = append(nodes, &node{
				value:    str,
				isString: true,
			})
		}
	}

	return &named{
		base:  b,
		nodes: nodes,
	}
}

func (n *named) Priority() int {
	return syntax.TypeNamed
}

func (n *named) Match(path string) (bool, map[string]string) {
	rawPath := path
	for i, name := range n.nodes {
		islast := (i == len(n.nodes)-1)

		if name.isString { // 普通字符串节点
			if !strings.HasPrefix(path, name.value) {
				return false, nil
			}

			if islast {
				if path == name.value {
					return true, n.params(rawPath)
				}
				return false, nil
			}

			path = path[len(name.value):]
		} else { // 带命名的节点
			index := strings.IndexByte(path, name.endByte)
			if !islast {
				if index == -1 {
					return false, nil
				}

				path = path[index:]
			} else { // 最后一个节点了
				if index == -1 {
					if n.wildcard {
						return false, nil
					}
					return true, n.params(rawPath)
				}

				if !n.wildcard {
					return false, nil
				}
				return true, n.params(rawPath)
			}
		} // end if
	} // end for

	return true, n.params(rawPath)
}

func (n *named) params(path string) map[string]string {
	// 由调用者 n.match() 保证 path 参数始终是与当前路由项匹配的。
	// 所以以下代码不再作是否匹配的检测工作。

	params := make(map[string]string, len(n.nodes))
	for i, name := range n.nodes {
		islast := (i == len(n.nodes)-1)

		if name.isString { // 普通字符串节点
			if islast {
				return params
			}

			path = path[len(name.value):]
		} else { // 带命名的节点
			index := strings.IndexByte(path, name.endByte)
			if !islast {
				params[name.value] = path[:index]
				path = path[index:]
			} else { // 最后一个节点了
				if index == -1 {
					params[name.value] = path
					return params
				}

				params[name.value] = path[:index]
				return params
			}
		} // end if
	} // end for

	return params
}

func (n *named) URL(params map[string]string, path string) (string, error) {
	ret := new(bytes.Buffer)

	for _, name := range n.nodes {
		if name.isString {
			ret.WriteString(name.value)
			continue
		}

		if param, exists := params[name.value]; exists {
			ret.WriteString(param)
		} else {
			return "", fmt.Errorf("参数 %v 未指定", name.value)
		}
	}

	if n.wildcard {
		ret.WriteByte('/')
		ret.WriteString(path)
	}

	return ret.String(), nil
}
<commit_msg>[internal/entry] 提升 named.URL 性能<commit_after>// Copyright 2017 by caixw, All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package entry

import (
	"fmt"
	"strings"

	"github.com/issue9/mux/internal/syntax"
)

// 表示命名参数中的某个节点
type node struct {
	value    string // 当前节点的值。
	endByte  byte   // 下一个节点的起始字符
	isString bool   // 当前节点是否为一个字符串
}

// 命名参数是正则表达式的简化版本，
// 在一个参数中未指定正则表达式，默认使用此类型，
// 性能会比用正则好一些。
type named struct {
	*base
	nodes []*node
}

// 声明一个新的 named 实例。
func newNamed(s *syntax.Syntax) *named {
	b := newBase(s)

	str := s.Patterns[len(s.Patterns)-1]
	if b.wildcard {
		str = str[:len(str)-2]
		if len(str) == 0 {
			s.Patterns = s.Patterns[:len(s.Patterns)-1]
		} else {
			s.Patterns[len(s.Patterns)-1] = str
		}
	}

	nodes := make([]*node, 0, len(s.Patterns))
	for index, str := range s.Patterns {
		if str[0] == syntax.Start {
			endByte := byte('/')
			if index < len(s.Patterns)-1 {
				endByte = s.Patterns[index+1][0]
			}
			nodes = append(nodes, &node{
				value:    str[1 : len(str)-1],
				isString: false,
				endByte:  endByte,
			})
		} else {
			nodes = append(nodes, &node{
				value:    str,
				isString: true,
			})
		}
	}

	return &named{
		base:  b,
		nodes: nodes,
	}
}

func (n *named) Priority() int {
	return syntax.TypeNamed
}

func (n *named) Match(path string) (bool, map[string]string) {
	rawPath := path
	for i, name := range n.nodes {
		islast := (i == len(n.nodes)-1)

		if name.isString { // 普通字符串节点
			if !strings.HasPrefix(path, name.value) {
				return false, nil
			}

			if islast {
				if path == name.value {
					return true, n.params(rawPath)
				}
				return false, nil
			}

			path = path[len(name.value):]
		} else { // 带命名的节点
			index := strings.IndexByte(path, name.endByte)
			if !islast {
				if index == -1 {
					return false, nil
				}

				path = path[index:]
			} else { // 最后一个节点了
				if index == -1 {
					if n.wildcard {
						return false, nil
					}
					return true, n.params(rawPath)
				}

				if !n.wildcard {
					return false, nil
				}
				return true, n.params(rawPath)
			}
		} // end if
	} // end for

	return true, n.params(rawPath)
}

func (n *named) params(path string) map[string]string {
	// 由调用者 n.match() 保证 path 参数始终是与当前路由项匹配的。
	// 所以以下代码不再作是否匹配的检测工作。

	params := make(map[string]string, len(n.nodes))
	for i, name := range n.nodes {
		islast := (i == len(n.nodes)-1)

		if name.isString { // 普通字符串节点
			if islast {
				return params
			}

			path = path[len(name.value):]
		} else { // 带命名的节点
			index := strings.IndexByte(path, name.endByte)
			if !islast {
				params[name.value] = path[:index]
				path = path[index:]
			} else { // 最后一个节点了
				if index == -1 {
					params[name.value] = path
					return params
				}

				params[name.value] = path[:index]
				return params
			}
		} // end if
	} // end for

	return params
}

func (n *named) URL(params map[string]string, path string) (string, error) {
	ret := make([]byte, 0, 500)

	for _, name := range n.nodes {
		if name.isString {
			ret = append(ret, name.value...)
			continue
		}

		if param, exists := params[name.value]; exists {
			ret = append(ret, param...)
		} else {
			return "", fmt.Errorf("参数 %v 未指定", name.value)
		}
	}

	if n.wildcard {
		ret = append(ret, '/')
		ret = append(ret, path...)
	}

	return string(ret), nil
}
<|endoftext|>


<commit_before>package v2

import (
	"bytes"
	"net/http"
	"net/url"
	"os"
	"testing"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/request"
	"github.com/aws/aws-sdk-go/aws/service"
	"github.com/stretchr/testify/assert"
)

func buildSigner(serviceName string, region string, signTime time.Time, query url.Values) signer {
	endpoint := "https://" + serviceName + "." + region + ".amazonaws.com"
	body := []byte(query.Encode())
	reader := bytes.NewReader(body)
	req, _ := http.NewRequest("POST", endpoint, reader)
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
	req.Header.Add("Content-Length", string(len(body)))

	signer := signer{
		Request: req,
		Time:    signTime,
		Credentials: credentials.NewStaticCredentials(
			"AKID",
			"SECRET",
			"SESSION"),
	}

	if os.Getenv("DEBUG") != "" {
		signer.Debug = aws.LogDebug
		signer.Logger = aws.NewDefaultLogger()
	}

	return signer
}

func TestSimpleSignRequest(t *testing.T) {
	query := make(url.Values)
	query.Add("Action", "CreateDomain")
	query.Add("DomainName", "TestDomain-1437033376")
	query.Add("Version", "2009-04-15")

	timestamp := time.Date(2015, 7, 16, 7, 56, 16, 0, time.UTC)
	signer := buildSigner("sdb", "ap-southeast-2", timestamp, query)

	err := signer.Sign()
	assert.Nil(t, err)
	assert.Equal(t, "Ch6qv3rzXB1SLqY2vFhsgA1WQ9rnQIE2WJCigOvAJwI=", signer.signature)
	assert.Equal(t, 9, len(signer.Query))
	assert.Equal(t, "AKID", signer.Query.Get("AWSAccessKeyId"))
	assert.Equal(t, "2015-07-16T07:56:16Z", signer.Query.Get("Timestamp"))
	assert.Equal(t, "HmacSHA256", signer.Query.Get("SignatureMethod"))
	assert.Equal(t, "2", signer.Query.Get("SignatureVersion"))
	assert.Equal(t, "Ch6qv3rzXB1SLqY2vFhsgA1WQ9rnQIE2WJCigOvAJwI=", signer.Query.Get("Signature"))
	assert.Equal(t, "CreateDomain", signer.Query.Get("Action"))
	assert.Equal(t, "TestDomain-1437033376", signer.Query.Get("DomainName"))
	assert.Equal(t, "2009-04-15", signer.Query.Get("Version"))
}

func TestMoreComplexSignRequest(t *testing.T) {
	query := make(url.Values)
	query.Add("Action", "PutAttributes")
	query.Add("DomainName", "TestDomain-1437041569")
	query.Add("Version", "2009-04-15")
	query.Add("Attribute.2.Name", "Attr2")
	query.Add("Attribute.2.Value", "Value2")
	query.Add("Attribute.2.Replace", "true")
	query.Add("Attribute.1.Name", "Attr1-%\\+ %")
	query.Add("Attribute.1.Value", " \tValue1 +!@#$%^&*(){}[]\"';:?/.>,<\x12\x00")
	query.Add("Attribute.1.Replace", "true")
	query.Add("ItemName", "Item 1")

	timestamp := time.Date(2015, 7, 16, 10, 12, 51, 0, time.UTC)
	signer := buildSigner("sdb", "ap-southeast-2", timestamp, query)

	err := signer.Sign()
	assert.Nil(t, err)
	assert.Equal(t, "WNdE62UJKLKoA6XncVY/9RDbrKmcVMdQPQOTAs8SgwQ=", signer.signature)
}

func TestGet(t *testing.T) {
	assert := assert.New(t)
	svc := service.New(&aws.Config{
		Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "TOKEN"),
		Region:      aws.String("ap-southeast-2"),
	})
	r := svc.NewRequest(
		&request.Operation{
			Name:       "OpName",
			HTTPMethod: "GET",
			HTTPPath:   "/",
		},
		nil,
		nil,
	)

	r.Build()
	assert.Equal("GET", r.HTTPRequest.Method)
	assert.Equal("", r.HTTPRequest.URL.Query().Get("Signature"))

	Sign(r)
	assert.NoError(r.Error)
	t.Logf("Signature: %s", r.HTTPRequest.URL.Query().Get("Signature"))
	assert.NotEqual("", r.HTTPRequest.URL.Query().Get("Signature"))
}

func TestAnonymousCredentials(t *testing.T) {
	svc := service.New(&aws.Config{
		Credentials: credentials.AnonymousCredentials,
		Region:      aws.String("ap-southeast-2"),
	})
	r := svc.NewRequest(
		&request.Operation{
			Name:       "PutAttributes",
			HTTPMethod: "POST",
			HTTPPath:   "/",
		},
		nil,
		nil,
	)
	r.Build()

	Sign(r)

	req := r.HTTPRequest
	req.ParseForm()

	assert.Empty(t, req.PostForm.Get("Signature"))
}
<commit_msg>Additional testing for v2 signer.<commit_after>package v2

import (
	"bytes"
	"net/http"
	"net/url"
	"os"
	"testing"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/request"
	"github.com/aws/aws-sdk-go/aws/service"
	"github.com/stretchr/testify/assert"
)

type signerBuilder struct {
	ServiceName  string
	Region       string
	SignTime     time.Time
	Query        url.Values
	Method       string
	SessionToken string
}

func (sb signerBuilder) BuildSigner() signer {
	endpoint := "https://" + sb.ServiceName + "." + sb.Region + ".amazonaws.com"
	var req *http.Request
	if sb.Method == "POST" {
		body := []byte(sb.Query.Encode())
		reader := bytes.NewReader(body)
		req, _ = http.NewRequest(sb.Method, endpoint, reader)
		req.Header.Add("Content-Type", "application/x-www-form-urlencoded")
		req.Header.Add("Content-Length", string(len(body)))
	} else {
		req, _ = http.NewRequest(sb.Method, endpoint, nil)
		req.URL.RawQuery = sb.Query.Encode()
	}

	signer := signer{
		Request: req,
		Time:    sb.SignTime,
		Credentials: credentials.NewStaticCredentials(
			"AKID",
			"SECRET",
			sb.SessionToken),
	}

	if os.Getenv("DEBUG") != "" {
		signer.Debug = aws.LogDebug
		signer.Logger = aws.NewDefaultLogger()
	}

	return signer
}

func TestSignRequestWithAndWithoutSession(t *testing.T) {
	assert := assert.New(t)

	// have to create more than once, so use a function
	newQuery := func() url.Values {
		query := make(url.Values)
		query.Add("Action", "CreateDomain")
		query.Add("DomainName", "TestDomain-1437033376")
		query.Add("Version", "2009-04-15")
		return query
	}

	// create request without a SecurityToken (session) in the credentials

	query := newQuery()
	timestamp := time.Date(2015, 7, 16, 7, 56, 16, 0, time.UTC)
	builder := signerBuilder{
		Method:      "POST",
		ServiceName: "sdb",
		Region:      "ap-southeast-2",
		SignTime:    timestamp,
		Query:       query,
	}

	signer := builder.BuildSigner()

	err := signer.Sign()
	assert.NoError(err)
	assert.Equal("tm4dX8Ks7pzFSVHz7qHdoJVXKRLuC4gWz9eti60d8ks=", signer.signature)
	assert.Equal(8, len(signer.Query))
	assert.Equal("AKID", signer.Query.Get("AWSAccessKeyId"))
	assert.Equal("2015-07-16T07:56:16Z", signer.Query.Get("Timestamp"))
	assert.Equal("HmacSHA256", signer.Query.Get("SignatureMethod"))
	assert.Equal("2", signer.Query.Get("SignatureVersion"))
	assert.Equal("tm4dX8Ks7pzFSVHz7qHdoJVXKRLuC4gWz9eti60d8ks=", signer.Query.Get("Signature"))
	assert.Equal("CreateDomain", signer.Query.Get("Action"))
	assert.Equal("TestDomain-1437033376", signer.Query.Get("DomainName"))
	assert.Equal("2009-04-15", signer.Query.Get("Version"))

	// should not have a SecurityToken parameter
	_, ok := signer.Query["SecurityToken"]
	assert.False(ok)

	// now sign again, this time with a security token (session)

	query = newQuery()
	builder.SessionToken = "SESSION"
	signer = builder.BuildSigner()

	err = signer.Sign()
	assert.NoError(err)
	assert.Equal("Ch6qv3rzXB1SLqY2vFhsgA1WQ9rnQIE2WJCigOvAJwI=", signer.signature)
	assert.Equal(9, len(signer.Query)) // expect one more parameter
	assert.Equal("Ch6qv3rzXB1SLqY2vFhsgA1WQ9rnQIE2WJCigOvAJwI=", signer.Query.Get("Signature"))
	assert.Equal("SESSION", signer.Query.Get("SecurityToken"))
}

func TestMoreComplexSignRequest(t *testing.T) {
	assert := assert.New(t)
	query := make(url.Values)
	query.Add("Action", "PutAttributes")
	query.Add("DomainName", "TestDomain-1437041569")
	query.Add("Version", "2009-04-15")
	query.Add("Attribute.2.Name", "Attr2")
	query.Add("Attribute.2.Value", "Value2")
	query.Add("Attribute.2.Replace", "true")
	query.Add("Attribute.1.Name", "Attr1-%\\+ %")
	query.Add("Attribute.1.Value", " \tValue1 +!@#$%^&*(){}[]\"';:?/.>,<\x12\x00")
	query.Add("Attribute.1.Replace", "true")
	query.Add("ItemName", "Item 1")

	timestamp := time.Date(2015, 7, 16, 10, 12, 51, 0, time.UTC)
	builder := signerBuilder{
		Method:       "POST",
		ServiceName:  "sdb",
		Region:       "ap-southeast-2",
		SignTime:     timestamp,
		Query:        query,
		SessionToken: "SESSION",
	}

	signer := builder.BuildSigner()

	err := signer.Sign()
	assert.NoError(err)
	assert.Equal("WNdE62UJKLKoA6XncVY/9RDbrKmcVMdQPQOTAs8SgwQ=", signer.signature)
}

func TestGet(t *testing.T) {
	assert := assert.New(t)
	svc := service.New(&aws.Config{
		Credentials: credentials.NewStaticCredentials("AKID", "SECRET", "SESSION"),
		Region:      aws.String("ap-southeast-2"),
	})
	r := svc.NewRequest(
		&request.Operation{
			Name:       "OpName",
			HTTPMethod: "GET",
			HTTPPath:   "/",
		},
		nil,
		nil,
	)

	r.Build()
	assert.Equal("GET", r.HTTPRequest.Method)
	assert.Equal("", r.HTTPRequest.URL.Query().Get("Signature"))

	Sign(r)
	assert.NoError(r.Error)
	t.Logf("Signature: %s", r.HTTPRequest.URL.Query().Get("Signature"))
	assert.NotEqual("", r.HTTPRequest.URL.Query().Get("Signature"))
}

func TestAnonymousCredentials(t *testing.T) {
	assert := assert.New(t)
	svc := service.New(&aws.Config{
		Credentials: credentials.AnonymousCredentials,
		Region:      aws.String("ap-southeast-2"),
	})
	r := svc.NewRequest(
		&request.Operation{
			Name:       "PutAttributes",
			HTTPMethod: "POST",
			HTTPPath:   "/",
		},
		nil,
		nil,
	)
	r.Build()

	Sign(r)

	req := r.HTTPRequest
	req.ParseForm()

	assert.Empty(req.PostForm.Get("Signature"))
}
<|endoftext|>


<commit_before>// Copyright The OpenTelemetry 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 testutil // import "go.opentelemetry.io/collector/internal/testutil"

import (
	"net"
	"os/exec"
	"runtime"
	"strconv"
	"strings"
	"testing"

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

type portpair struct {
	first string
	last  string
}

// GetAvailableLocalAddress finds an available local port and returns an endpoint
// describing it. The port is available for opening when this function returns
// provided that there is no race by some other code to grab the same port
// immediately.
func GetAvailableLocalAddress(t *testing.T) string {
	ln, err := net.Listen("tcp", "localhost:0")
	require.NoError(t, err, "Failed to get a free local port")
	// There is a possible race if something else takes this same port before
	// the test uses it, however, that is unlikely in practice.
	defer ln.Close()
	return ln.Addr().String()
}

// GetAvailablePort finds an available local port and returns it. The port is
// available for opening when this function returns provided that there is no
// race by some other code to grab the same port immediately.
func GetAvailablePort(t *testing.T) uint16 {
	// Retry has been added for windows as net.Listen can return a port that is not actually available. Details can be
	// found in https://github.com/docker/for-win/issues/3171 but to summarize Hyper-V will reserve ranges of ports
	// which do not show up under the "netstat -ano" but can only be found by
	// "netsh interface ipv4 show excludedportrange protocol=tcp".  We'll use []exclusions to hold those ranges and
	// retry if the port returned by GetAvailableLocalAddress falls in one of those them.
	var exclusions []portpair
	portFound := false
	var port string
	var err error
	if runtime.GOOS == "windows" {
		exclusions = getExclusionsList(t)
	}

	for !portFound {
		endpoint := GetAvailableLocalAddress(t)
		_, port, err = net.SplitHostPort(endpoint)
		require.NoError(t, err)
		portFound = true
		if runtime.GOOS == "windows" {
			for _, pair := range exclusions {
				if port >= pair.first && port <= pair.last {
					portFound = false
					break
				}
			}
		}
	}

	portInt, err := strconv.Atoi(port)
	require.NoError(t, err)

	return uint16(portInt)
}

// Get excluded ports on Windows from the command: netsh interface ipv4 show excludedportrange protocol=tcp
func getExclusionsList(t *testing.T) []portpair {
	cmd := exec.Command("netsh", "interface", "ipv4", "show", "excludedportrange", "protocol=tcp")
	output, err := cmd.CombinedOutput()
	require.NoError(t, err)

	exclusions := createExclusionsList(string(output), t)
	return exclusions
}

func createExclusionsList(exclusionsText string, t *testing.T) []portpair {
	exclusions := []portpair{}

	parts := strings.Split(exclusionsText, "--------")
	require.Equal(t, len(parts), 3)
	portsText := strings.Split(parts[2], "*")
	require.Greater(t, len(portsText), 1) // original text may have a suffix like " - Administered port exclusions."
	lines := strings.Split(portsText[0], "\n")
	for _, line := range lines {
		if strings.TrimSpace(line) != "" {
			entries := strings.Fields(strings.TrimSpace(line))
			require.Equal(t, len(entries), 2)
			pair := portpair{entries[0], entries[1]}
			exclusions = append(exclusions, pair)
		}
	}
	return exclusions
}
<commit_msg>Avoid potential integer overflow (#4277)<commit_after>// Copyright The OpenTelemetry 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 testutil // import "go.opentelemetry.io/collector/internal/testutil"

import (
	"net"
	"os/exec"
	"runtime"
	"strconv"
	"strings"
	"testing"

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

type portpair struct {
	first string
	last  string
}

// GetAvailableLocalAddress finds an available local port and returns an endpoint
// describing it. The port is available for opening when this function returns
// provided that there is no race by some other code to grab the same port
// immediately.
func GetAvailableLocalAddress(t *testing.T) string {
	ln, err := net.Listen("tcp", "localhost:0")
	require.NoError(t, err, "Failed to get a free local port")
	// There is a possible race if something else takes this same port before
	// the test uses it, however, that is unlikely in practice.
	defer ln.Close()
	return ln.Addr().String()
}

// GetAvailablePort finds an available local port and returns it. The port is
// available for opening when this function returns provided that there is no
// race by some other code to grab the same port immediately.
func GetAvailablePort(t *testing.T) uint16 {
	// Retry has been added for windows as net.Listen can return a port that is not actually available. Details can be
	// found in https://github.com/docker/for-win/issues/3171 but to summarize Hyper-V will reserve ranges of ports
	// which do not show up under the "netstat -ano" but can only be found by
	// "netsh interface ipv4 show excludedportrange protocol=tcp".  We'll use []exclusions to hold those ranges and
	// retry if the port returned by GetAvailableLocalAddress falls in one of those them.
	var exclusions []portpair
	portFound := false
	var port string
	var err error
	if runtime.GOOS == "windows" {
		exclusions = getExclusionsList(t)
	}

	for !portFound {
		endpoint := GetAvailableLocalAddress(t)
		_, port, err = net.SplitHostPort(endpoint)
		require.NoError(t, err)
		portFound = true
		if runtime.GOOS == "windows" {
			for _, pair := range exclusions {
				if port >= pair.first && port <= pair.last {
					portFound = false
					break
				}
			}
		}
	}

	portInt, err := strconv.ParseUint(port, 10, 16)
	require.NoError(t, err)

	return uint16(portInt)
}

// Get excluded ports on Windows from the command: netsh interface ipv4 show excludedportrange protocol=tcp
func getExclusionsList(t *testing.T) []portpair {
	cmd := exec.Command("netsh", "interface", "ipv4", "show", "excludedportrange", "protocol=tcp")
	output, err := cmd.CombinedOutput()
	require.NoError(t, err)

	exclusions := createExclusionsList(string(output), t)
	return exclusions
}

func createExclusionsList(exclusionsText string, t *testing.T) []portpair {
	exclusions := []portpair{}

	parts := strings.Split(exclusionsText, "--------")
	require.Equal(t, len(parts), 3)
	portsText := strings.Split(parts[2], "*")
	require.Greater(t, len(portsText), 1) // original text may have a suffix like " - Administered port exclusions."
	lines := strings.Split(portsText[0], "\n")
	for _, line := range lines {
		if strings.TrimSpace(line) != "" {
			entries := strings.Fields(strings.TrimSpace(line))
			require.Equal(t, len(entries), 2)
			pair := portpair{entries[0], entries[1]}
			exclusions = append(exclusions, pair)
		}
	}
	return exclusions
}
<|endoftext|>


<commit_before>package modify

import (
	"fmt"
	"reflect"

	oas3 "github.com/getkin/kin-openapi/openapi3"
	"github.com/grokify/simplego/fmt/fmtutil"
	"github.com/grokify/swaggman/openapi3"
)

/*
func CopyOperation(src oas3.Operation) oas3.Operation {
	dst := oas3.Operation{
		ExtensionProps: src.ExtensionProps,
		Tags:           src.Tags,
		Summary:        src.Summary,
		Description:    src.Description,
		OperationID:    src.OperationID,
		Parameters:     src.Parameters,
		RequestBody:    src.RequestBody,
		Responses:      src.Responses,
		Callbacks:      src.Callbacks,
		Deprecated:     src.Deprecated,
		Security:       src.Security,
		Servers:        src.Servers,
		ExternalDocs:   src.ExternalDocs,
	}
	return dst
}
*/

func SpecSchemasSetDeprecated(spec *oas3.Swagger, newDeprecated bool) {
	for _, schemaRef := range spec.Components.Schemas {
		if len(schemaRef.Ref) == 0 && schemaRef.Value != nil {
			schemaRef.Value.Deprecated = newDeprecated
		}
	}
}

func SpecOperationsSetDeprecated(spec *oas3.Swagger, newDeprecated bool) {
	openapi3.VisitOperations(
		spec,
		func(path, method string, op *oas3.Operation) {
			/*if op == nil {
				return
			}*/

			// op = &*op

			op.Summary = "SUMSUMSUMARY"
			op.Deprecated = true
			op.Tags = append(op.Tags, "NEW_TAG")

			newOp := oas3.Operation{
				ExtensionProps: op.ExtensionProps,
				Tags:           op.Tags,
				Summary:        op.Summary,
				Description:    op.Description,
				OperationID:    op.OperationID,
				Parameters:     op.Parameters,
				RequestBody:    op.RequestBody,
				Responses:      op.Responses,
				Callbacks:      op.Callbacks,
				Deprecated:     op.Deprecated,
				Security:       op.Security,
				Servers:        op.Servers,
				ExternalDocs:   op.ExternalDocs,
			}

			//newOp := oas3.Operation{}
			// reflect.Copy([]oas3.Operation{*op}, []oas3.Operation{newOp})
			SpecSetOperation(spec, path, method, newOp)
			if 1 == 0 {
				ps := reflect.ValueOf(op)
				// struct
				s := ps.Elem()
				if s.Kind() == reflect.Struct {
					// exported field
					f := s.FieldByName("Deprecated")
					if f.IsValid() {
						// A Value can be changed only if it is
						// addressable and was not obtained by
						// the use of unexported struct fields.
						if f.CanSet() {
							// change value of N
							if f.Kind() == reflect.Bool {
								f.SetBool(false)
								fmt.Println("SETTING_REEFLECT")
								//x := int64(7)
								/*if !f.OverflowInt(x) {
									f.Set(x)
								}*/
							}
						}
					}
				}
			}

			if 1 == 0 && op.OperationID == "listGlipGroups" {
				op.Deprecated = false
				fmt.Printf("DEP  [%v]\n", op.Deprecated)

				fmtutil.PrintJSON(op)
				panic("ABC_VISIT")
				fmt.Printf("DEP  [%v]\n", op.Deprecated)
				if 1 == 0 {
					panic("YYY")
					fmt.Printf("DEP  [%v]\n", op.Deprecated)
					op.Deprecated = false
					fmt.Printf("DEP  [%v]\n", op.Deprecated)
					fmtutil.PrintJSON(op)
					fmt.Printf("SSUM [%s]\n", op.Summary)
					op.Summary = op.Summary + " " + "ABC "
					fmt.Printf("SSUM [%s]\n", op.Summary)
				}
				//panic("ZZZ_LISTGLIPGROUPS")
			}

		},
	)
}

/*

func SpecOperationsRemoveDeprecated(spec *oas3.Swagger) {
	openapi3.VisitOperations(
		spec,
		func(path, method string, op *oas3.Operation) {
			if op == nil {
				return
			}
			op.Deprecated = false
			// SpecSetOperation(spec, path, method, &*op)
			// op = &*op
			if 1 == 1 && op.OperationID == "listGlipGroups" {
				op.Deprecated = false
				fmt.Printf("DEP  [%v]\n", op.Deprecated)

				fmtutil.PrintJSON(*op)
				fmt.Printf("DEP  [%v]\n", op.Deprecated)
				if 1 == 0 {
					panic("YYY")
					fmt.Printf("DEP  [%v]\n", op.Deprecated)
					op.Deprecated = true
					fmt.Printf("DEP  [%v]\n", op.Deprecated)
					fmtutil.PrintJSON(op)
					fmt.Printf("SSUM [%s]\n", op.Summary)
					op.Summary = op.Summary + " " + "ABC "
					fmt.Printf("SSUM [%s]\n", op.Summary)
				}
				panic("ZZZ_LISTGLIPGROUPS")
			}
		},
	)
}
*/
<commit_msg>enhance: openapi3/modify: update set deprecated<commit_after>package modify

import (
	oas3 "github.com/getkin/kin-openapi/openapi3"
	"github.com/grokify/swaggman/openapi3"
)

func SpecSchemasSetDeprecated(spec *oas3.Swagger, newDeprecated bool) {
	for _, schemaRef := range spec.Components.Schemas {
		if len(schemaRef.Ref) == 0 && schemaRef.Value != nil {
			schemaRef.Value.Deprecated = newDeprecated
		}
	}
}

func SpecOperationsSetDeprecated(spec *oas3.Swagger, newDeprecated bool) {
	openapi3.VisitOperations(
		spec,
		func(path, method string, op *oas3.Operation) {
			if op != nil {
				op.Deprecated = newDeprecated
			}
		},
	)
}
<|endoftext|>