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

// Package benchfmt provides readers and writers for the Go benchmark format.
//
// The format is documented at https://golang.org/design/14313-benchmark-format
package benchfmt

import (
	"bufio"
	"fmt"
	"io"
	"sort"
	"strconv"
	"strings"
	"unicode"
)

// Reader reads benchmark results from an io.Reader.
// Use Next to advance through the results.
//
//   br := benchfmt.NewReader(r)
//   for br.Next() {
//     res := br.Result()
//     ...
//   }
//   err = br.Err() // get any error encountered during iteration
//   ...
type Reader struct {
	s      *bufio.Scanner
	labels Labels
	// permLabels are permanent labels read from the start of the
	// file or provided by AddLabels. They cannot be overridden.
	permLabels Labels
	lineNum    int
	// cached from the last call to Next
	result *Result
	err    error
}

// NewReader creates a BenchmarkReader that reads from r.
func NewReader(r io.Reader) *Reader {
	return &Reader{
		s:      bufio.NewScanner(r),
		labels: make(Labels),
	}
}

// AddLabels adds additional labels as if they had been read from the header of a file.
// It must be called before the first call to r.Next.
func (r *Reader) AddLabels(labels Labels) {
	r.permLabels = labels.copy()
	for k, v := range labels {
		r.labels[k] = v
	}
}

// Result represents a single line from a benchmark file.
// All information about that line is self-contained in the Result.
type Result struct {
	// Labels is the set of persistent labels that apply to the result.
	// Labels must not be modified.
	Labels Labels
	// NameLabels is the set of ephemeral labels that were parsed
	// from the benchmark name/line.
	// NameLabels must not be modified.
	NameLabels Labels
	// LineNum is the line number on which the result was found
	LineNum int
	// Content is the verbatim input line of the benchmark file, beginning with the string "Benchmark".
	Content string
}

// Labels is a set of key-value strings.
type Labels map[string]string

// TODO(quentin): Add String and Equal methods to Labels?

// Keys returns a sorted list of the keys in l.
func (l Labels) Keys() []string {
	var out []string
	for k := range l {
		out = append(out, k)
	}
	sort.Strings(out)
	return out
}

// A Printer prints a sequence of benchmark results.
type Printer struct {
	w      io.Writer
	labels Labels
}

// NewPrinter constructs a BenchmarkPrinter writing to w.
func NewPrinter(w io.Writer) *Printer {
	return &Printer{w: w}
}

// Print writes the lines necessary to recreate r.
func (p *Printer) Print(r *Result) error {
	var keys []string
	// Print removed keys first.
	for k := range p.labels {
		if r.Labels[k] == "" {
			keys = append(keys, k)
		}
	}
	sort.Strings(keys)
	for _, k := range keys {
		if _, err := fmt.Fprintf(p.w, "%s:\n", k); err != nil {
			return err
		}
	}
	// Then print new or changed keys.
	keys = keys[:0]
	for k, v := range r.Labels {
		if v != "" && p.labels[k] != v {
			keys = append(keys, k)
		}
	}
	sort.Strings(keys)
	for _, k := range keys {
		if _, err := fmt.Fprintf(p.w, "%s: %s\n", k, r.Labels[k]); err != nil {
			return err
		}
	}
	// Finally print the actual line itself.
	if _, err := fmt.Fprintf(p.w, "%s\n", r.Content); err != nil {
		return err
	}
	p.labels = r.Labels
	return nil
}

// parseNameLabels extracts extra labels from a benchmark name and sets them in labels.
func parseNameLabels(name string, labels Labels) {
	dash := strings.LastIndex(name, "-")
	if dash >= 0 {
		// Accept -N as an alias for /gomaxprocs=N
		_, err := strconv.Atoi(name[dash+1:])
		if err == nil {
			labels["gomaxprocs"] = name[dash+1:]
			name = name[:dash]
		}
	}
	parts := strings.Split(name, "/")
	labels["name"] = parts[0]
	for i, sub := range parts[1:] {
		equals := strings.Index(sub, "=")
		var key string
		if equals >= 0 {
			key, sub = sub[:equals], sub[equals+1:]
		} else {
			key = fmt.Sprintf("sub%d", i+1)
		}
		labels[key] = sub
	}
}

// newResult parses a line and returns a Result object for the line.
func newResult(labels Labels, lineNum int, name, content string) *Result {
	r := &Result{
		Labels:     labels,
		NameLabels: make(Labels),
		LineNum:    lineNum,
		Content:    content,
	}
	parseNameLabels(name, r.NameLabels)
	return r
}

// copy returns a new copy of the labels map, to protect against
// future modifications to labels.
func (l Labels) copy() Labels {
	new := make(Labels)
	for k, v := range l {
		new[k] = v
	}
	return new
}

// TODO(quentin): How to represent and efficiently group multiple lines?

// Next returns the next benchmark result from the file. If there are
// no further results, it returns nil, io.EOF.
func (r *Reader) Next() bool {
	if r.err != nil {
		return false
	}
	copied := false
	havePerm := r.permLabels != nil
	for r.s.Scan() {
		r.lineNum++
		line := r.s.Text()
		if key, value, ok := parseKeyValueLine(line); ok {
			if _, ok := r.permLabels[key]; ok {
				continue
			}
			if !copied {
				copied = true
				r.labels = r.labels.copy()
			}
			// TODO(quentin): Spec says empty value is valid, but
			// we need a way to cancel previous labels, so we'll
			// treat an empty value as a removal.
			if value == "" {
				delete(r.labels, key)
			} else {
				r.labels[key] = value
			}
			continue
		}
		// Blank line delimits the header. If we find anything else, the file must not have a header.
		if !havePerm {
			if line == "" {
				r.permLabels = r.labels.copy()
			} else {
				r.permLabels = Labels{}
			}
		}
		if fullName, ok := parseBenchmarkLine(line); ok {
			r.result = newResult(r.labels, r.lineNum, fullName, line)
			return true
		}
	}
	if err := r.s.Err(); err != nil {
		r.err = err
		return false
	}
	r.err = io.EOF
	return false
}

// Result returns the most recent result generated by a call to Next.
func (r *Reader) Result() *Result {
	return r.result
}

// Err returns the error state of the reader.
func (r *Reader) Err() error {
	if r.err == io.EOF {
		return nil
	}
	return r.err
}

// parseKeyValueLine attempts to parse line as a key: value pair. ok
// indicates whether the line could be parsed.
func parseKeyValueLine(line string) (key, val string, ok bool) {
	for i, c := range line {
		if i == 0 && !unicode.IsLower(c) {
			return
		}
		if unicode.IsSpace(c) || unicode.IsUpper(c) {
			return
		}
		if i > 0 && c == ':' {
			key = line[:i]
			val = line[i+1:]
			break
		}
	}
	if key == "" {
		return
	}
	if val == "" {
		ok = true
		return
	}
	for len(val) > 0 && (val[0] == ' ' || val[0] == '\t') {
		val = val[1:]
		ok = true
	}
	return
}

// parseBenchmarkLine attempts to parse line as a benchmark result. If
// successful, fullName is the name of the benchmark with the
// "Benchmark" prefix stripped, and ok is true.
func parseBenchmarkLine(line string) (fullName string, ok bool) {
	space := strings.IndexFunc(line, unicode.IsSpace)
	if space < 0 {
		return
	}
	name := line[:space]
	if !strings.HasPrefix(name, "Benchmark") {
		return
	}
	return name[len("Benchmark"):], true
}
<commit_msg>storage/benchfmt: reuse maps when identical<commit_after>// Copyright 2016 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package benchfmt provides readers and writers for the Go benchmark format.
//
// The format is documented at https://golang.org/design/14313-benchmark-format
package benchfmt

import (
	"bufio"
	"fmt"
	"io"
	"sort"
	"strconv"
	"strings"
	"unicode"
)

// Reader reads benchmark results from an io.Reader.
// Use Next to advance through the results.
//
//   br := benchfmt.NewReader(r)
//   for br.Next() {
//     res := br.Result()
//     ...
//   }
//   err = br.Err() // get any error encountered during iteration
//   ...
type Reader struct {
	s      *bufio.Scanner
	labels Labels
	// permLabels are permanent labels read from the start of the
	// file or provided by AddLabels. They cannot be overridden.
	permLabels Labels
	lineNum    int
	// cached from last call to newResult, to save on allocations
	lastName       string
	lastNameLabels Labels
	// cached from the last call to Next
	result *Result
	err    error
}

// NewReader creates a BenchmarkReader that reads from r.
func NewReader(r io.Reader) *Reader {
	return &Reader{
		s:      bufio.NewScanner(r),
		labels: make(Labels),
	}
}

// AddLabels adds additional labels as if they had been read from the header of a file.
// It must be called before the first call to r.Next.
func (r *Reader) AddLabels(labels Labels) {
	r.permLabels = labels.copy()
	for k, v := range labels {
		r.labels[k] = v
	}
}

// Result represents a single line from a benchmark file.
// All information about that line is self-contained in the Result.
type Result struct {
	// Labels is the set of persistent labels that apply to the result.
	// Labels must not be modified.
	Labels Labels
	// NameLabels is the set of ephemeral labels that were parsed
	// from the benchmark name/line.
	// NameLabels must not be modified.
	NameLabels Labels
	// LineNum is the line number on which the result was found
	LineNum int
	// Content is the verbatim input line of the benchmark file, beginning with the string "Benchmark".
	Content string
}

// Labels is a set of key-value strings.
type Labels map[string]string

// TODO(quentin): Add String and Equal methods to Labels?

// Keys returns a sorted list of the keys in l.
func (l Labels) Keys() []string {
	var out []string
	for k := range l {
		out = append(out, k)
	}
	sort.Strings(out)
	return out
}

// A Printer prints a sequence of benchmark results.
type Printer struct {
	w      io.Writer
	labels Labels
}

// NewPrinter constructs a BenchmarkPrinter writing to w.
func NewPrinter(w io.Writer) *Printer {
	return &Printer{w: w}
}

// Print writes the lines necessary to recreate r.
func (p *Printer) Print(r *Result) error {
	var keys []string
	// Print removed keys first.
	for k := range p.labels {
		if r.Labels[k] == "" {
			keys = append(keys, k)
		}
	}
	sort.Strings(keys)
	for _, k := range keys {
		if _, err := fmt.Fprintf(p.w, "%s:\n", k); err != nil {
			return err
		}
	}
	// Then print new or changed keys.
	keys = keys[:0]
	for k, v := range r.Labels {
		if v != "" && p.labels[k] != v {
			keys = append(keys, k)
		}
	}
	sort.Strings(keys)
	for _, k := range keys {
		if _, err := fmt.Fprintf(p.w, "%s: %s\n", k, r.Labels[k]); err != nil {
			return err
		}
	}
	// Finally print the actual line itself.
	if _, err := fmt.Fprintf(p.w, "%s\n", r.Content); err != nil {
		return err
	}
	p.labels = r.Labels
	return nil
}

// parseNameLabels extracts extra labels from a benchmark name and sets them in labels.
func parseNameLabels(name string, labels Labels) {
	dash := strings.LastIndex(name, "-")
	if dash >= 0 {
		// Accept -N as an alias for /gomaxprocs=N
		_, err := strconv.Atoi(name[dash+1:])
		if err == nil {
			labels["gomaxprocs"] = name[dash+1:]
			name = name[:dash]
		}
	}
	parts := strings.Split(name, "/")
	labels["name"] = parts[0]
	for i, sub := range parts[1:] {
		equals := strings.Index(sub, "=")
		var key string
		if equals >= 0 {
			key, sub = sub[:equals], sub[equals+1:]
		} else {
			key = fmt.Sprintf("sub%d", i+1)
		}
		labels[key] = sub
	}
}

// newResult parses a line and returns a Result object for the line.
func (r *Reader) newResult(labels Labels, lineNum int, name, content string) *Result {
	res := &Result{
		Labels:  labels,
		LineNum: lineNum,
		Content: content,
	}
	if r.lastName != name {
		r.lastName = name
		r.lastNameLabels = make(Labels)
		parseNameLabels(name, r.lastNameLabels)
	}
	res.NameLabels = r.lastNameLabels
	return res
}

// copy returns a new copy of the labels map, to protect against
// future modifications to labels.
func (l Labels) copy() Labels {
	new := make(Labels)
	for k, v := range l {
		new[k] = v
	}
	return new
}

// TODO(quentin): How to represent and efficiently group multiple lines?

// Next returns the next benchmark result from the file. If there are
// no further results, it returns nil, io.EOF.
func (r *Reader) Next() bool {
	if r.err != nil {
		return false
	}
	copied := false
	havePerm := r.permLabels != nil
	for r.s.Scan() {
		r.lineNum++
		line := r.s.Text()
		if key, value, ok := parseKeyValueLine(line); ok {
			if _, ok := r.permLabels[key]; ok {
				continue
			}
			if !copied {
				copied = true
				r.labels = r.labels.copy()
			}
			// TODO(quentin): Spec says empty value is valid, but
			// we need a way to cancel previous labels, so we'll
			// treat an empty value as a removal.
			if value == "" {
				delete(r.labels, key)
			} else {
				r.labels[key] = value
			}
			continue
		}
		// Blank line delimits the header. If we find anything else, the file must not have a header.
		if !havePerm {
			if line == "" {
				r.permLabels = r.labels.copy()
			} else {
				r.permLabels = Labels{}
			}
		}
		if fullName, ok := parseBenchmarkLine(line); ok {
			r.result = r.newResult(r.labels, r.lineNum, fullName, line)
			return true
		}
	}
	if err := r.s.Err(); err != nil {
		r.err = err
		return false
	}
	r.err = io.EOF
	return false
}

// Result returns the most recent result generated by a call to Next.
func (r *Reader) Result() *Result {
	return r.result
}

// Err returns the error state of the reader.
func (r *Reader) Err() error {
	if r.err == io.EOF {
		return nil
	}
	return r.err
}

// parseKeyValueLine attempts to parse line as a key: value pair. ok
// indicates whether the line could be parsed.
func parseKeyValueLine(line string) (key, val string, ok bool) {
	for i, c := range line {
		if i == 0 && !unicode.IsLower(c) {
			return
		}
		if unicode.IsSpace(c) || unicode.IsUpper(c) {
			return
		}
		if i > 0 && c == ':' {
			key = line[:i]
			val = line[i+1:]
			break
		}
	}
	if key == "" {
		return
	}
	if val == "" {
		ok = true
		return
	}
	for len(val) > 0 && (val[0] == ' ' || val[0] == '\t') {
		val = val[1:]
		ok = true
	}
	return
}

// parseBenchmarkLine attempts to parse line as a benchmark result. If
// successful, fullName is the name of the benchmark with the
// "Benchmark" prefix stripped, and ok is true.
func parseBenchmarkLine(line string) (fullName string, ok bool) {
	space := strings.IndexFunc(line, unicode.IsSpace)
	if space < 0 {
		return
	}
	name := line[:space]
	if !strings.HasPrefix(name, "Benchmark") {
		return
	}
	return name[len("Benchmark"):], true
}
<|endoftext|>


<commit_before>package benchmark

import (
	"bytes"
	"crypto/tls"
	"fmt"
	"io"
	"math/rand"
	"net"

	quic "github.com/lucas-clemente/quic-go"
	"github.com/lucas-clemente/quic-go/internal/protocol"
	"github.com/lucas-clemente/quic-go/internal/testdata"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

func init() {
	var _ = Describe("Benchmarks", func() {
		dataLen := size * /* MB */ (1 << 20)
		data := make([]byte, dataLen)
		rand.Seed(GinkgoRandomSeed())
		rand.Read(data) // no need to check for an error. math.Rand.Read never errors

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

			Context(fmt.Sprintf("with version %d", version), func() {
				Measure(fmt.Sprintf("transferring a %d MB file", size), func(b Benchmarker) {
					var ln quic.Listener
					serverAddr := make(chan net.Addr)
					handshakeChan := make(chan struct{})
					// start the server
					go func() {
						defer GinkgoRecover()
						var err error
						ln, err = quic.ListenAddr("localhost:0", testdata.GetTLSConfig(), nil)
						Expect(err).ToNot(HaveOccurred())
						serverAddr <- ln.Addr()
						sess, err := ln.Accept()
						Expect(err).ToNot(HaveOccurred())
						// wait for the client to complete the handshake before sending the data
						// this should not be necessary, but due to timing issues on the CIs, this is necessary to avoid sending too many undecryptable packets
						<-handshakeChan
						str, err := sess.OpenStream()
						Expect(err).ToNot(HaveOccurred())
						_, err = str.Write(data)
						Expect(err).ToNot(HaveOccurred())
						err = str.Close()
						Expect(err).ToNot(HaveOccurred())
					}()

					// start the client
					addr := <-serverAddr
					sess, err := quic.DialAddr(addr.String(), &tls.Config{InsecureSkipVerify: true}, nil)
					Expect(err).ToNot(HaveOccurred())
					close(handshakeChan)
					str, err := sess.AcceptStream()
					Expect(err).ToNot(HaveOccurred())

					buf := &bytes.Buffer{}
					// measure the time it takes to download the dataLen bytes
					// note we're measuring the time for the transfer, i.e. excluding the handshake
					runtime := b.Time("transfer time", func() {
						_, err := io.Copy(buf, str)
						Expect(err).NotTo(HaveOccurred())
					})
					Expect(buf.Bytes()).To(Equal(data))

					b.RecordValue("transfer rate [MB/s]", float64(dataLen)/1e6/runtime.Seconds())

					ln.Close()
					sess.Close(nil)
				}, samples)
			})
		}
	})
}
<commit_msg>actually run the benchmark tests with the selected version<commit_after>package benchmark

import (
	"bytes"
	"crypto/tls"
	"fmt"
	"io"
	"math/rand"
	"net"

	quic "github.com/lucas-clemente/quic-go"
	"github.com/lucas-clemente/quic-go/internal/protocol"
	"github.com/lucas-clemente/quic-go/internal/testdata"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

func init() {
	var _ = Describe("Benchmarks", func() {
		dataLen := size * /* MB */ (1 << 20)
		data := make([]byte, dataLen)
		rand.Seed(GinkgoRandomSeed())
		rand.Read(data) // no need to check for an error. math.Rand.Read never errors

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

			Context(fmt.Sprintf("with version %d", version), func() {
				Measure(fmt.Sprintf("transferring a %d MB file", size), func(b Benchmarker) {
					var ln quic.Listener
					serverAddr := make(chan net.Addr)
					handshakeChan := make(chan struct{})
					// start the server
					go func() {
						defer GinkgoRecover()
						var err error
						ln, err = quic.ListenAddr(
							"localhost:0",
							testdata.GetTLSConfig(),
							&quic.Config{Versions: []protocol.VersionNumber{version}},
						)
						Expect(err).ToNot(HaveOccurred())
						serverAddr <- ln.Addr()
						sess, err := ln.Accept()
						Expect(err).ToNot(HaveOccurred())
						// wait for the client to complete the handshake before sending the data
						// this should not be necessary, but due to timing issues on the CIs, this is necessary to avoid sending too many undecryptable packets
						<-handshakeChan
						str, err := sess.OpenStream()
						Expect(err).ToNot(HaveOccurred())
						_, err = str.Write(data)
						Expect(err).ToNot(HaveOccurred())
						err = str.Close()
						Expect(err).ToNot(HaveOccurred())
					}()

					// start the client
					addr := <-serverAddr
					sess, err := quic.DialAddr(
						addr.String(),
						&tls.Config{InsecureSkipVerify: true},
						&quic.Config{Versions: []protocol.VersionNumber{version}},
					)
					Expect(err).ToNot(HaveOccurred())
					close(handshakeChan)
					str, err := sess.AcceptStream()
					Expect(err).ToNot(HaveOccurred())

					buf := &bytes.Buffer{}
					// measure the time it takes to download the dataLen bytes
					// note we're measuring the time for the transfer, i.e. excluding the handshake
					runtime := b.Time("transfer time", func() {
						_, err := io.Copy(buf, str)
						Expect(err).NotTo(HaveOccurred())
					})
					Expect(buf.Bytes()).To(Equal(data))

					b.RecordValue("transfer rate [MB/s]", float64(dataLen)/1e6/runtime.Seconds())

					ln.Close()
					sess.Close(nil)
				}, samples)
			})
		}
	})
}
<|endoftext|>


<commit_before>/*
Copyright 2021 The logr 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 logr

import (
	"fmt"
	"testing"

	"github.com/go-logr/logr"
	"github.com/go-logr/logr/funcr"
)

func noop(prefix, args string) {
}

func BenchmarkInfoOneArg(b *testing.B) {
	var log logr.Logger = funcr.New(noop, funcr.Options{})

	for i := 0; i < b.N; i++ {
		log.Info("this is", "a", "string")
	}
}

func BenchmarkInfoSeveralArgs(b *testing.B) {
	var log logr.Logger = funcr.New(noop, funcr.Options{})

	for i := 0; i < b.N; i++ {
		log.Info("multi",
			"bool", true, "string", "str", "int", 42,
			"float", 3.14, "struct", struct{ X, Y int }{93, 76})
	}
}

func BenchmarkV0Info(b *testing.B) {
	var log logr.Logger = funcr.New(noop, funcr.Options{})

	for i := 0; i < b.N; i++ {
		log.V(0).Info("multi",
			"bool", true, "string", "str", "int", 42,
			"float", 3.14, "struct", struct{ X, Y int }{93, 76})
	}
}

func BenchmarkV9Info(b *testing.B) {
	var log logr.Logger = funcr.New(noop, funcr.Options{})

	for i := 0; i < b.N; i++ {
		log.V(9).Info("multi",
			"bool", true, "string", "str", "int", 42,
			"float", 3.14, "struct", struct{ X, Y int }{93, 76})
	}
}

func BenchmarkError(b *testing.B) {
	var log logr.Logger = funcr.New(noop, funcr.Options{})

	err := fmt.Errorf("error message")
	for i := 0; i < b.N; i++ {
		log.Error(err, "multi",
			"bool", true, "string", "str", "int", 42,
			"float", 3.14, "struct", struct{ X, Y int }{93, 76})
	}
}

func BenchmarkWithValues(b *testing.B) {
	var log logr.Logger = funcr.New(noop, funcr.Options{})

	for i := 0; i < b.N; i++ {
		l := log.WithValues("k1", "v1", "k2", "v2")
		_ = l
	}
}

func BenchmarkWithName(b *testing.B) {
	var log logr.Logger = funcr.New(noop, funcr.Options{})

	for i := 0; i < b.N; i++ {
		l := log.WithName("name")
		_ = l
	}
}
<commit_msg>Make the benchmark not inline ther impl<commit_after>/*
Copyright 2021 The logr 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 logr

import (
	"fmt"
	"testing"

	"github.com/go-logr/logr"
	"github.com/go-logr/logr/funcr"
)

func noop(prefix, args string) {
}

//go:noinline
func doInfoOneArg(b *testing.B, log logr.Logger) {
	for i := 0; i < b.N; i++ {
		log.Info("this is", "a", "string")
	}
}

//go:noinline
func doInfoSeveralArgs(b *testing.B, log logr.Logger) {
	for i := 0; i < b.N; i++ {
		log.Info("multi",
			"bool", true, "string", "str", "int", 42,
			"float", 3.14, "struct", struct{ X, Y int }{93, 76})
	}
}

//go:noinline
func doV0Info(b *testing.B, log logr.Logger) {
	for i := 0; i < b.N; i++ {
		log.V(0).Info("multi",
			"bool", true, "string", "str", "int", 42,
			"float", 3.14, "struct", struct{ X, Y int }{93, 76})
	}
}

//go:noinline
func doV9Info(b *testing.B, log logr.Logger) {
	for i := 0; i < b.N; i++ {
		log.V(9).Info("multi",
			"bool", true, "string", "str", "int", 42,
			"float", 3.14, "struct", struct{ X, Y int }{93, 76})
	}
}

//go:noinline
func doError(b *testing.B, log logr.Logger) {
	err := fmt.Errorf("error message")
	for i := 0; i < b.N; i++ {
		log.Error(err, "multi",
			"bool", true, "string", "str", "int", 42,
			"float", 3.14, "struct", struct{ X, Y int }{93, 76})
	}
}

//go:noinline
func doWithValues(b *testing.B, log logr.Logger) {
	for i := 0; i < b.N; i++ {
		l := log.WithValues("k1", "v1", "k2", "v2")
		_ = l
	}
}

//go:noinline
func doWithName(b *testing.B, log logr.Logger) {
	for i := 0; i < b.N; i++ {
		l := log.WithName("name")
		_ = l
	}
}

func BenchmarkDiscardInfoOneArg(b *testing.B) {
	var log logr.Logger = logr.Discard()
	doInfoOneArg(b, log)
}

func BenchmarkDiscardInfoSeveralArgs(b *testing.B) {
	var log logr.Logger = logr.Discard()
	doInfoSeveralArgs(b, log)
}

func BenchmarkDiscardV0Info(b *testing.B) {
	var log logr.Logger = logr.Discard()
	doV0Info(b, log)
}

func BenchmarkDiscardV9Info(b *testing.B) {
	var log logr.Logger = logr.Discard()
	doV9Info(b, log)
}

func BenchmarkDiscardError(b *testing.B) {
	var log logr.Logger = logr.Discard()
	doError(b, log)
}

func BenchmarkDiscardWithValues(b *testing.B) {
	var log logr.Logger = logr.Discard()
	doWithValues(b, log)
}

func BenchmarkDiscardWithName(b *testing.B) {
	var log logr.Logger = logr.Discard()
	doWithName(b, log)
}

func BenchmarkFuncrInfoOneArg(b *testing.B) {
	var log logr.Logger = funcr.New(noop, funcr.Options{})
	doInfoOneArg(b, log)
}

func BenchmarkFuncrInfoSeveralArgs(b *testing.B) {
	var log logr.Logger = funcr.New(noop, funcr.Options{})
	doInfoSeveralArgs(b, log)
}

func BenchmarkFuncrV0Info(b *testing.B) {
	var log logr.Logger = funcr.New(noop, funcr.Options{})
	doV0Info(b, log)
}

func BenchmarkFuncrV9Info(b *testing.B) {
	var log logr.Logger = funcr.New(noop, funcr.Options{})
	doV9Info(b, log)
}

func BenchmarkFuncrError(b *testing.B) {
	var log logr.Logger = funcr.New(noop, funcr.Options{})
	doError(b, log)
}

func BenchmarkFuncrWithValues(b *testing.B) {
	var log logr.Logger = funcr.New(noop, funcr.Options{})
	doWithValues(b, log)
}

func BenchmarkFuncrWithName(b *testing.B) {
	var log logr.Logger = funcr.New(noop, funcr.Options{})
	doWithName(b, log)
}
<|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 gcs

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"

	"github.com/jacobsa/gcloud/httputil"
	"golang.org/x/net/context"
	"google.golang.org/api/googleapi"
	storagev1 "google.golang.org/api/storage/v1"
)

func updateObject(
	httpClient *http.Client,
	bucketName string,
	ctx context.Context,
	req *UpdateObjectRequest) (o *Object, err error) {
	// Set up a map representing the JSON object we want to send to GCS. For now,
	// we don't treat empty strings specially.
	jsonMap := make(map[string]interface{})

	if req.ContentType != nil {
		jsonMap["contentType"] = req.ContentType
	}

	if req.ContentEncoding != nil {
		jsonMap["contentEncoding"] = req.ContentEncoding
	}

	if req.ContentLanguage != nil {
		jsonMap["contentLanguage"] = req.ContentLanguage
	}

	if req.CacheControl != nil {
		jsonMap["cacheControl"] = req.CacheControl
	}

	// Implement the convention that a pointer to an empty string means to delete
	// the field (communicated to GCS by setting it to null in the JSON).
	for k, v := range jsonMap {
		if *(v.(*string)) == "" {
			jsonMap[k] = nil
		}
	}

	// Add a field for user metadata if appropriate.
	if req.Metadata != nil {
		jsonMap["metadata"] = req.Metadata
	}

	// Set up a reader for the JSON object.
	body, err := googleapi.WithoutDataWrapper.JSONReader(jsonMap)
	if err != nil {
		return
	}

	// Construct an appropriate URL (cf. http://goo.gl/B46IDy).
	opaque := fmt.Sprintf(
		"//www.googleapis.com/storage/v1/b/%s/o/%s",
		httputil.EncodePathSegment(bucketName),
		httputil.EncodePathSegment(req.Name))

	query := make(url.Values)
	query.Set("projection", "full")

	url := &url.URL{
		Scheme:   "https",
		Opaque:   opaque,
		RawQuery: query.Encode(),
	}

	// Create an HTTP request.
	httpReq, err := httputil.NewRequest("PATCH", url, body, userAgent)
	if err != nil {
		err = fmt.Errorf("httputil.NewRequest: %v", err)
		return
	}

	httpReq.Header.Set("Content-Type", "application/json")

	// Execute the HTTP request.
	httpRes, err := httpClient.Do(httpReq)
	if err != nil {
		return
	}

	defer googleapi.CloseBody(httpRes)

	// Check for HTTP-level errors.
	if err = googleapi.CheckResponse(httpRes); err != nil {
		// Special case: handle not found errors.
		if typed, ok := err.(*googleapi.Error); ok {
			if typed.Code == http.StatusNotFound {
				err = &NotFoundError{Err: typed}
			}
		}

		return
	}

	// Parse the response.
	var rawObject *storagev1.Object
	if err = json.NewDecoder(httpRes.Body).Decode(&rawObject); err != nil {
		return
	}

	// Convert the response.
	if o, err = toObject(rawObject); err != nil {
		err = fmt.Errorf("toObject: %v", err)
		return
	}

	return
}
<commit_msg>Refactored JSON code for UpdateObject.<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 gcs

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"net/url"

	"github.com/jacobsa/gcloud/httputil"
	"golang.org/x/net/context"
	"google.golang.org/api/googleapi"
	storagev1 "google.golang.org/api/storage/v1"
)

func makeUpdateObjectBody(
	bucketName string,
	req *UpdateObjectRequest) (r io.Reader, err error) {
	// Set up a map representing the JSON object we want to send to GCS. For now,
	// we don't treat empty strings specially.
	jsonMap := make(map[string]interface{})

	if req.ContentType != nil {
		jsonMap["contentType"] = req.ContentType
	}

	if req.ContentEncoding != nil {
		jsonMap["contentEncoding"] = req.ContentEncoding
	}

	if req.ContentLanguage != nil {
		jsonMap["contentLanguage"] = req.ContentLanguage
	}

	if req.CacheControl != nil {
		jsonMap["cacheControl"] = req.CacheControl
	}

	// Implement the convention that a pointer to an empty string means to delete
	// the field (communicated to GCS by setting it to null in the JSON).
	for k, v := range jsonMap {
		if *(v.(*string)) == "" {
			jsonMap[k] = nil
		}
	}

	// Add a field for user metadata if appropriate.
	if req.Metadata != nil {
		jsonMap["metadata"] = req.Metadata
	}

	// Set up a reader.
	r, err = googleapi.WithoutDataWrapper.JSONReader(jsonMap)
	if err != nil {
		err = fmt.Errorf("JSONReader", err)
		return
	}

	return
}

func updateObject(
	httpClient *http.Client,
	bucketName string,
	ctx context.Context,
	req *UpdateObjectRequest) (o *Object, err error) {
	// Construct an appropriate URL (cf. http://goo.gl/B46IDy).
	opaque := fmt.Sprintf(
		"//www.googleapis.com/storage/v1/b/%s/o/%s",
		httputil.EncodePathSegment(bucketName),
		httputil.EncodePathSegment(req.Name))

	query := make(url.Values)
	query.Set("projection", "full")

	url := &url.URL{
		Scheme:   "https",
		Opaque:   opaque,
		RawQuery: query.Encode(),
	}

	// Set up the request body.
	body, err := makeUpdateObjectBody(bucketName, req)
	if err != nil {
		err = fmt.Errorf("makeUpdateObjectBody: %v", err)
		return
	}

	// Create an HTTP request.
	httpReq, err := httputil.NewRequest("PATCH", url, body, userAgent)
	if err != nil {
		err = fmt.Errorf("httputil.NewRequest: %v", err)
		return
	}

	httpReq.Header.Set("Content-Type", "application/json")

	// Execute the HTTP request.
	httpRes, err := httpClient.Do(httpReq)
	if err != nil {
		return
	}

	defer googleapi.CloseBody(httpRes)

	// Check for HTTP-level errors.
	if err = googleapi.CheckResponse(httpRes); err != nil {
		// Special case: handle not found errors.
		if typed, ok := err.(*googleapi.Error); ok {
			if typed.Code == http.StatusNotFound {
				err = &NotFoundError{Err: typed}
			}
		}

		return
	}

	// Parse the response.
	var rawObject *storagev1.Object
	if err = json.NewDecoder(httpRes.Body).Decode(&rawObject); err != nil {
		return
	}

	// Convert the response.
	if o, err = toObject(rawObject); err != nil {
		err = fmt.Errorf("toObject: %v", err)
		return
	}

	return
}
<|endoftext|>


<commit_before>// Copyright 2012-2013 Tamás Gulácsi
// See LICENSE.txt
// Translated from cx_Oracle ((c) Anthony Tuininga) by Tamás Gulácsi
package goracle

/*
#cgo CFLAGS: -I/usr/include/oracle/11.2/client64
#cgo LDFLAGS: -lclntsh -L/usr/lib/oracle/11.2/client64/lib

#include <stdlib.h>
#include <oci.h>

const int bindInfo_elementSize = (sizeof(char*) + sizeof(ub1) + sizeof(char*) + sizeof(ub1) +
            sizeof(ub1) + sizeof(OCIBind*));
*/
import "C"

import (
	"errors"
	"fmt"
	"log"
	"unsafe"
)

func init() {
	log.Printf("bindInfo_elementSize=%d", C.bindInfo_elementSize)
}

type Cursor struct {
	handle                                      *C.OCIStmt
	connection                                  *Connection
	environment                                 *Environment
	bindVariables, fetchVariables               []*Variable
	arraySize, bindArraySize, fetchArraySize    int
	setInputSizes, outputSize, outputSizeColumn int
	rowCount, actualRows, rownum                int
	statement                                   []byte
	statementTag                                []byte
	statementType                               int
	numbersAsStrings, isDML, isOpen, isOwned    bool
}

var DefaultArraySize int = 50

//statement // statementTag // rowFactory // inputTypeHandler // outputTypeHandler

//   Allocate a new handle.
func (cur *Cursor) allocateHandle(typ C.ub4) *Error {
	cur.isOwned = true
	return ociHandleAlloc(unsafe.Pointer(cur.environment.handle),
		C.OCI_HTYPE_STMT,
		(*unsafe.Pointer)(unsafe.Pointer(&cur.handle)),
		"allocate statement handle")
}

//   Free the handle which may be reallocated if necessary.
func (cur *Cursor) freeHandle() *Error {
	if cur.handle == nil {
		return nil
	}
	if cur.isOwned {
		return cur.environment.CheckStatus(C.OCIHandleFree(unsafe.Pointer(cur.handle), C.OCI_HTYPE_STMT),
			"freeCursor")
	} else if cur.connection.handle != nil {
		return cur.environment.CheckStatus(C.OCIStmtRelease(cur.handle,
			cur.environment.errorHandle, (*C.OraText)(&cur.statementTag[0]),
			C.ub4(len(cur.statementTag)), C.OCI_DEFAULT),
			"statement release")
	}
	cur.handle = nil
}

func (cur *Cursor) IsOpen() bool {
	if !cur.isOpen {
		return false
	}
	return cur.connection.IsConnected()
}

// Creates new cursor
func NewCursor(conn *Connection) *Cursor {
	return &Cursor{connection: conn, environment: conn.environment,
		arraySize: DefaultArraySize, fetchArraySize: DefaultArraySize,
		bindArraySize: 1, statementType: -1, outputSize: -1, outputSizeColumn: -1,
		isOpen: true}
}

func (cur Cursor) String() string {
	return fmt.Sprintf("<goracle.Cursor on %s>", cur.connection)
}

//   Return a list of bind variable names. At this point the cursor must have
// already been prepared.
func (cur *Cursor) GetBindNames(numElements int) (names []string, err error) {
	// ensure that a statement has already been prepared
	if cur.statement == nil {
		err = errors.New("statement must be prepared first!")
	}

	// avoid bus errors on 64-bit platforms
	// numElements = numElements + (sizeof(void*) - numElements % sizeof(void*));

	// initialize the buffers
	buffer := make([]byte, numElements*int(C.bindInfo_elementSize))
	bindNames := (*unsafe.Pointer)(unsafe.Pointer(&buffer[0]))
	bindNameLengths := &buffer[0+numElements]
	indicatorNames := (*unsafe.Pointer)(unsafe.Pointer(&buffer[1*numElements+numElements]))
	indicatorNameLengths := &buffer[2*numElements+numElements]
	duplicate := (*unsafe.Pointer)(unsafe.Pointer(&buffer[3*numElements+numElements]))
	bindHandles := (*C.OCIBind)(unsafe.Pointer(&buffer[4*numElements+numElements]))

	// get the bind information
	status := C.OCIStmtGetBindInfo(cur.handle,
		cur.environment.errorHandle, numElements, 1, &foundElements,
		(**C.text)(bindNames), bindNameLengths, (**C.text)(indicatorNames),
		indicatorNameLengths, duplicate, bindHandles)
	if status != C.OCI_NO_DATA {
		if e := CheckStatus(status, "GetBindInfo"); e != nil {
			return e
		}
	}
	if foundElements < 0 {
		return NewError(-foundElements, "negative foundElements")
	}

	// create the list which is to be returned
	names = make([]string, 0, foundElements)
	// process the bind information returned
	for i = 0; i < foundElements; i++ {
		if duplicate[i] > 0 {
			continue
		}
		names = append(names, cur.environment.FromEncodedString(bindNames[i][:bindNameLengths[i]]))
	}

	return nil
}

//-----------------------------------------------------------------------------
//   Perform the defines for the cursor. At this point it is assumed that the
// statement being executed is in fact a query.
//-----------------------------------------------------------------------------
func (cur *Cursor) PerformDefine() error {
	var numParams, pos int

	// determine number of items in select-list
	if err := CheckStatus(C.OCIAttrGet(unsafe.Pointer(cur.handle), C.OCI_HTYPE_STMT,
		unsafe.Pointer(&numParams), 0,
		C.OCI_ATTR_PARAM_COUNT, cur.environment.errorHandle),
		"PerformDefine"); err != nil {
		return err
	}

	// create a list corresponding to the number of items
	cur.fetchVariables = make([]*Variable, numParams)

	// define a variable for each select-item
	cur.fetchArraySize = cur.arraySize
	for pos := 1; pos <= numParams; pos++ {
		v, e := defineVariable(cur, cur.fetchArraySize, pos)
		if e != nil {
			return e
		}
		cur.fetchVariables[pos-1] = v
	}
}
<commit_msg>cursor.GetBindNames!<commit_after>// Copyright 2012-2013 Tamás Gulácsi
// See LICENSE.txt
// Translated from cx_Oracle ((c) Anthony Tuininga) by Tamás Gulácsi
package goracle

/*
#cgo CFLAGS: -I/usr/include/oracle/11.2/client64
#cgo LDFLAGS: -lclntsh -L/usr/lib/oracle/11.2/client64/lib

#include <stdlib.h>
#include <oci.h>

const int sizeof_OraText = sizeof(OraText);
*/
import "C"

import (
	"errors"
	"fmt"
	// "log"
	// "reflect"
	"unsafe"
)

func init() {
	// log.Printf("bindInfo_elementSize=%d", C.bindInfo_elementSize)
}

type Cursor struct {
	handle                                      *C.OCIStmt
	connection                                  *Connection
	environment                                 *Environment
	bindVariables, fetchVariables               []*Variable
	arraySize, bindArraySize, fetchArraySize    int
	setInputSizes, outputSize, outputSizeColumn int
	rowCount, actualRows, rownum                int
	statement                                   []byte
	statementTag                                []byte
	statementType                               int
	numbersAsStrings, isDML, isOpen, isOwned    bool
}

var DefaultArraySize int = 50

//statement // statementTag // rowFactory // inputTypeHandler // outputTypeHandler

//   Allocate a new handle.
func (cur *Cursor) allocateHandle(typ C.ub4) *Error {
	cur.isOwned = true
	return ociHandleAlloc(unsafe.Pointer(cur.environment.handle),
		C.OCI_HTYPE_STMT,
		(*unsafe.Pointer)(unsafe.Pointer(&cur.handle)),
		"allocate statement handle")
}

//   Free the handle which may be reallocated if necessary.
func (cur *Cursor) freeHandle() *Error {
	if cur.handle == nil {
		return nil
	}
	if cur.isOwned {
		return cur.environment.CheckStatus(C.OCIHandleFree(unsafe.Pointer(cur.handle), C.OCI_HTYPE_STMT),
			"freeCursor")
	} else if cur.connection.handle != nil {
		return cur.environment.CheckStatus(C.OCIStmtRelease(cur.handle,
			cur.environment.errorHandle, (*C.OraText)(&cur.statementTag[0]),
			C.ub4(len(cur.statementTag)), C.OCI_DEFAULT),
			"statement release")
	}
	cur.handle = nil
	return nil
}

func (cur *Cursor) IsOpen() bool {
	if !cur.isOpen {
		return false
	}
	return cur.connection.IsConnected()
}

// Creates new cursor
func NewCursor(conn *Connection) *Cursor {
	return &Cursor{connection: conn, environment: conn.environment,
		arraySize: DefaultArraySize, fetchArraySize: DefaultArraySize,
		bindArraySize: 1, statementType: -1, outputSize: -1, outputSizeColumn: -1,
		isOpen: true}
}

func (cur Cursor) String() string {
	return fmt.Sprintf("<goracle.Cursor on %s>", cur.connection)
}

//   Return a list of bind variable names. At this point the cursor must have
// already been prepared.
func (cur *Cursor) GetBindNames(numElements int) (names []string, err error) {
	// ensure that a statement has already been prepared
	if cur.statement == nil {
		err = errors.New("statement must be prepared first!")
	}
	var foundElements C.sb4

	// avoid bus errors on 64-bit platforms
	// numElements = numElements + (sizeof(void*) - numElements % sizeof(void*));

	// initialize the buffers
	// buffer := make([]byte, numElements*int(C.bindInfo_elementSize))
	// bindNames := (**C.OraText)(unsafe.Pointer(&buffer[0]))
	bindNames := make([](*C.OraText), numElements)
	// bindNameLengths := (*C.ub1)(&buffer[0+numElements])
	bindNameLengths := make([]byte, numElements)
	// indicatorNames := (**C.OraText)(unsafe.Pointer(&buffer[1*numElements+numElements]))
	indicatorNames := make([](*C.OraText), numElements)
	// indicatorNameLengths := (*C.ub1)(&buffer[2*numElements+numElements])
	indicatorNameLengths := make([]byte, numElements)
	// duplicate := (*C.ub1)(unsafe.Pointer(&buffer[3*numElements+numElements]))
	duplicate := make([]byte, numElements)
	// bindHandles := (**C.OCIBind)(unsafe.Pointer(&buffer[4*numElements+numElements]))
	bindHandles := make([](*C.OCIBind), numElements)

	// get the bind information
	status := C.OCIStmtGetBindInfo(cur.handle,
		cur.environment.errorHandle, C.ub4(numElements), 1, &foundElements,
		(**C.OraText)(unsafe.Pointer(&bindNames[0])),
		(*C.ub1)(&bindNameLengths[0]),
		(**C.OraText)(&indicatorNames[0]), (*C.ub1)(&indicatorNameLengths[0]),
		(*C.ub1)(&duplicate[0]), (**C.OCIBind)(&bindHandles[0]))
	if status != C.OCI_NO_DATA {
		if e := cur.environment.CheckStatus(status, "GetBindInfo"); e != nil {
			return nil, e
		}
	}
	if foundElements < 0 {
		return nil, NewError(-int(foundElements), "negative foundElements")
	}

	// create the list which is to be returned
	names = make([]string, 0, foundElements)
	// process the bind information returned
	for i := 0; i < int(foundElements); i++ {
		if duplicate[i] > 0 {
			continue
		}
		names = append(names, FromOraText(bindNames[i], int(bindNameLengths[i])))
	}

	return names, nil
}

//-----------------------------------------------------------------------------
//   Perform the defines for the cursor. At this point it is assumed that the
// statement being executed is in fact a query.
//-----------------------------------------------------------------------------
func (cur *Cursor) PerformDefine() error {
	var numParams int
	var x C.ub4 = 0

	// determine number of items in select-list
	if err := cur.environment.CheckStatus(C.OCIAttrGet(
		unsafe.Pointer(cur.handle),
		C.OCI_HTYPE_STMT,
		unsafe.Pointer(&numParams), &x,
		C.OCI_ATTR_PARAM_COUNT, cur.environment.errorHandle),
		"PerformDefine"); err != nil {
		return err
	}

	// create a list corresponding to the number of items
	cur.fetchVariables = make([]*Variable, numParams)

	// define a variable for each select-item
	cur.fetchArraySize = cur.arraySize
	for pos := 1; pos <= numParams; pos++ {
		// FIXME defineVariable
		// v, e := defineVariable(cur, cur.fetchArraySize, pos)
		var v *Variable
		var e error
		v, e = nil, nil
		if e != nil {
			return e
		}
		cur.fetchVariables[pos-1] = v
	}
	return nil
}

func FromOraText(textp *C.OraText, length int) string {
	return string(C.GoBytes(unsafe.Pointer(textp), C.int(C.sizeof_OraText*length)))
}
<|endoftext|>


<commit_before>package disruptor

const (
	cpuCacheLinePadding        = 7
	InitialSequenceValue int64 = -1
	MaxSequenceValue     int64 = (1 << 63) - 1
	Gating                     = InitialSequenceValue - 1
	Idling                     = Gating - 1
)

// TODO: research aligned read/write:
// https://groups.google.com/forum/#!topic/golang-nuts/XDfQUn4U_g8
// https://gist.github.com/anachronistic/7495541
// http://blog.chewxy.com/2013/12/10/pointer-tagging-in-go/
// http://www.goinggo.net/2014/01/concurrency-goroutines-and-gomaxprocs.html
type Cursor struct {
	sequence int64
	padding  [cpuCacheLinePadding]int64
}

func NewCursor() *Cursor {
	return &Cursor{sequence: InitialSequenceValue}
}
<commit_msg>Additional performance TODOs.<commit_after>package disruptor

const (
	cpuCacheLinePadding        = 7
	InitialSequenceValue int64 = -1
	MaxSequenceValue     int64 = (1 << 63) - 1
	Gating                     = InitialSequenceValue - 1
	Idling                     = Gating - 1
)

// TODO: research aligned read/write:
// https://github.com/fmstephe/fatomic/blob/master/slice.go
// https://groups.google.com/forum/#!topic/golang-nuts/XDfQUn4U_g8
// https://gist.github.com/anachronistic/7495541
// http://blog.chewxy.com/2013/12/10/pointer-tagging-in-go/
// http://www.goinggo.net/2014/01/concurrency-goroutines-and-gomaxprocs.html
type Cursor struct {
	sequence int64
	padding  [cpuCacheLinePadding]int64 // https://github.com/fmstephe/fatomic/blob/master/paddedint.go
}

func NewCursor() *Cursor {
	return &Cursor{sequence: InitialSequenceValue}
}
<|endoftext|>


<commit_before>/*
 * ------------------------------------------------------------------
 * YANG Development Kit
 * Copyright 2017 Cisco Systems. All rights reserved
 *
 *----------------------------------------------
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 types

import (
	"sort"
)

type YFilter int

const (
	NotSet YFilter = iota
	Read
	Merge
	Create
	Remove
	Delete
	Replace
)

type Empty struct {
	set bool
}

type LeafData struct {
	Value  string
	Filter YFilter
	IsSet  bool
}

type NameLeafData struct {
	Name string
	Data LeafData
}

type EntityPath struct {
	Path       string
	ValuePaths []NameLeafData
}

type AugmentCapabilitiesFunction func() map[string]string

type Entity interface {
	GetEntityPath(Entity) EntityPath
	GetSegmentPath() string

	HasDataOrFilter() bool

	SetValue(string, string)
	GetChildByName(string, string) Entity

	GetChildren() map[string]Entity

	SetParent(Entity)
	GetParent() Entity

	GetAugmentCapabilitiesFunction() AugmentCapabilitiesFunction
	GetBundleYangModelsLocation() string
	GetBundleName() string

	GetYangName() string
	GetParentYangName() string

	GetFilter() YFilter
}

type Bits map[string]bool

type Decimal64 struct {
	value string
}

type EnumYLeaf struct {
	value int
	name  string
}

type Enum struct {
	EnumYLeaf
}

type YType int

const (
	Uint_8 YType = iota
	Uint_16
	Uint_32
	Uint_64
	Int_8
	Int_16
	Int_32
	Int_64
	Empty_
	Identityref
	Str
	Boolean
	Enumeration
	Bits_
	Decimal64_
)

type YLeaf struct {
	name string

	leaf_type  YType
	bits_value Bits

	Value  string
	IsSet  bool
	Filter YFilter
}

func (y *YLeaf) GetNameLeafdata() NameLeafData {
	return NameLeafData{y.name, LeafData{y.Value, y.Filter, y.IsSet}}
}

type YLeafList struct {
	name   string
	values []YLeaf

	Filter    YFilter
	leaf_type YType
}

func (y *YLeafList) GetYLeafs() []YLeaf {
	return y.values
}

func (y *YLeafList) GetNameLeafdata() [](NameLeafData) {
	result := make([]NameLeafData, len(y.values))
	for i := 0; i < len(y.values); i++ {
		result = append(result, NameLeafData{y.values[i].name, LeafData{y.values[i].Value, y.values[i].Filter, y.values[i].IsSet}})
	}
	return result
}

type EncodingFormat int

const (
	XML EncodingFormat = iota
	JSON
)

func (e YFilter) String() string {
	switch e {
	case Read:
		return "read"
	case Replace:
		return "replace"
	case Delete:
		return "delete"
	case Merge:
		return "merge"
	case Create:
		return "create"
	case NotSet:
		return ""
	}
	return ""
}

type ServiceProvider interface {
	GetPrivate() interface{}
	Connect()
	Disconnect()
}

type CodecServiceProvider struct {
	Encoding EncodingFormat
}

type Protocol int

const (
	Restconf Protocol = iota
	Netconf
)

type DataNode struct {
	Private interface{}
}

type CServiceProvider struct {
	Private interface{}
}

type Repository struct {
	Path string
}

//////////////////////////////////////////////////////////////////////////
// Exported utility functions
//////////////////////////////////////////////////////////////////////////

type EntitySlice []Entity

func (s EntitySlice) Len() int {
	return len(s)
}

func (s EntitySlice) Less(i, j int) bool {
	return s[i].GetSegmentPath() < s[j].GetSegmentPath()
}

func (s EntitySlice) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

func GetRelativeEntityPath(current_node Entity, ancestor Entity, path string) string {
	path_buffer := path

	if ancestor == nil {
		return ""
	}
	p := current_node.GetParent()
	parents := EntitySlice{}
	for p != nil && p != ancestor {
		//append(parents, p)
		p = p.GetParent()
	}

	if p == nil {
		return ""
	}

	parents = sort.Reverse(parents).(EntitySlice)

	p = nil
	for _, p1 := range parents {
		if p != nil {
			path_buffer += "/"
		} else {
			p = p1
		}
		path_buffer += p1.GetSegmentPath()
	}
	if p != nil {
		path_buffer += "/"
	}
	path_buffer += current_node.GetSegmentPath()
	return path_buffer

}

func IsSet(Filter YFilter) bool {
	return Filter != NotSet
}
<commit_msg>More fixes<commit_after>/*
 * ------------------------------------------------------------------
 * YANG Development Kit
 * Copyright 2017 Cisco Systems. All rights reserved
 *
 *----------------------------------------------
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 types

import (
	"sort"
)

type YFilter int

const (
	NotSet YFilter = iota
	Read
	Merge
	Create
	Remove
	Delete
	Replace
)

type Empty struct {
	set bool
}

type LeafData struct {
	Value  string
	Filter YFilter
	IsSet  bool
}

type NameLeafData struct {
	Name string
	Data LeafData
}

type EntityPath struct {
	Path       string
	ValuePaths []NameLeafData
}

type AugmentCapabilitiesFunction func() map[string]string

type Entity interface {
	GetEntityPath(Entity) EntityPath
	GetSegmentPath() string

	HasDataOrFilter() bool

	SetValue(string, string)
	GetChildByName(string, string) Entity

	GetChildren() map[string]Entity

	SetParent(Entity)
	GetParent() Entity

	GetAugmentCapabilitiesFunction() AugmentCapabilitiesFunction
	GetBundleYangModelsLocation() string
	GetBundleName() string

	GetYangName() string
	GetParentYangName() string

	GetFilter() YFilter
}

type Bits map[string]bool

type Decimal64 struct {
	value string
}

type EnumYLeaf struct {
	value int
	name  string
}

type Enum struct {
	EnumYLeaf
}

type YType int

const (
	Uint_8 YType = iota
	Uint_16
	Uint_32
	Uint_64
	Int_8
	Int_16
	Int_32
	Int_64
	Empty_
	Identityref
	Str
	Boolean
	Enumeration
	Bits_
	Decimal64_
)

type YLeaf struct {
	name string

	leaf_type  YType
	bits_value Bits

	Value  string
	IsSet  bool
	Filter YFilter
}

func (y *YLeaf) GetNameLeafdata() NameLeafData {
	return NameLeafData{y.name, LeafData{y.Value, y.Filter, y.IsSet}}
}

type YLeafList struct {
	name   string
	values []YLeaf

	Filter    YFilter
	leaf_type YType
}

func (y *YLeafList) GetYLeafs() []YLeaf {
	return y.values
}

func (y *YLeafList) GetNameLeafdata() [](NameLeafData) {
	result := make([]NameLeafData, len(y.values))
	for i := 0; i < len(y.values); i++ {
		result = append(result, NameLeafData{y.values[i].name, LeafData{y.values[i].Value, y.values[i].Filter, y.values[i].IsSet}})
	}
	return result
}

type EncodingFormat int

const (
	XML EncodingFormat = iota
	JSON
)

func (e YFilter) String() string {
	switch e {
	case Read:
		return "read"
	case Replace:
		return "replace"
	case Delete:
		return "delete"
	case Merge:
		return "merge"
	case Create:
		return "create"
    case Remove:
        return "remove"
	case NotSet:
		return ""
	}
	return ""
}

type ServiceProvider interface {
	GetPrivate() interface{}
	Connect()
	Disconnect()
}

type CodecServiceProvider struct {
	Encoding EncodingFormat
}

type Protocol int

const (
	Restconf Protocol = iota
	Netconf
)

type DataNode struct {
	Private interface{}
}

type CServiceProvider struct {
	Private interface{}
}

type Repository struct {
	Path string
}

//////////////////////////////////////////////////////////////////////////
// Exported utility functions
//////////////////////////////////////////////////////////////////////////

type EntitySlice []Entity

func (s EntitySlice) Len() int {
	return len(s)
}

func (s EntitySlice) Less(i, j int) bool {
	return s[i].GetSegmentPath() < s[j].GetSegmentPath()
}

func (s EntitySlice) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}

func GetRelativeEntityPath(current_node Entity, ancestor Entity, path string) string {
	path_buffer := path

	if ancestor == nil {
		return ""
	}
	p := current_node.GetParent()
	parents := EntitySlice{}
	for p != nil && p != ancestor {
		//append(parents, p)
		p = p.GetParent()
	}

	if p == nil {
		return ""
	}

	parents = sort.Reverse(parents).(EntitySlice)

	p = nil
	for _, p1 := range parents {
		if p != nil {
			path_buffer += "/"
		} else {
			p = p1
		}
		path_buffer += p1.GetSegmentPath()
	}
	if p != nil {
		path_buffer += "/"
	}
	path_buffer += current_node.GetSegmentPath()
	return path_buffer

}

func IsSet(Filter YFilter) bool {
	return Filter != NotSet
}
<|endoftext|>


<commit_before>package cyberark

import (
	"testing"

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

func DoShouldFailWhenNoClient(t *testing.T) {
	s := &GetPasswordService{}
	_, err := s.Do()
	assert.NotNil(t, err)
	assert.Equal(t, "Client is required", err.Error())
}

func DoShouldFailWhenNoAppID(t *testing.T) {
	c, err := NewClient(SetHost("foo"))
	assert.Nil(t, err)

	_, err = c.GetPassword().Do()
	assert.NotNil(t, err)
	assert.Equal(t, "AppID is required", err.Error())
}

func TestAppIDShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).AppID("app")
	assert.Equal(t, "app", s.appID)
}

func TestAddressShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Address("address")
	assert.Equal(t, "address", s.address)
}

func TestDatabaseShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Database("database")
	assert.Equal(t, "database", s.database)
}

func TestFolderShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Folder("folder")
	assert.Equal(t, "folder", s.folder)
}

func TestObjectShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Object("object")
	assert.Equal(t, "object", s.object)
}

func TestPolicyIDShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).PolicyID("policy")
	assert.Equal(t, "policy", s.policyID)
}

func TestQueryShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Query("query")
	assert.Equal(t, "query", s.query)
}

func TestQueryFormatShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).QueryFormat("query format")
	assert.Equal(t, "query format", s.queryFormat)
}

func TestReasonShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Reason("reason")
	assert.Equal(t, "reason", s.reason)
}

func TestSafeShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Safe("safe")
	assert.Equal(t, "safe", s.safe)
}

func TestTimeoutShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Timeout(1000)
	assert.Equal(t, 1000, s.timeout)
}

func TestUserNameShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).UserName("user")
	assert.Equal(t, "user", s.userName)
}
<commit_msg>Add tests for setParam<commit_after>package cyberark

import (
	"net/url"
	"testing"

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

func DoShouldFailWhenNoClient(t *testing.T) {
	s := &GetPasswordService{}
	_, err := s.Do()
	assert.NotNil(t, err)
	assert.Equal(t, "Client is required", err.Error())
}

func DoShouldFailWhenNoAppID(t *testing.T) {
	c, err := NewClient(SetHost("foo"))
	assert.Nil(t, err)

	_, err = c.GetPassword().Do()
	assert.NotNil(t, err)
	assert.Equal(t, "AppID is required", err.Error())
}

func TestAppIDShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).AppID("app")
	assert.Equal(t, "app", s.appID)
}

func TestAddressShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Address("address")
	assert.Equal(t, "address", s.address)
}

func TestDatabaseShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Database("database")
	assert.Equal(t, "database", s.database)
}

func TestFolderShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Folder("folder")
	assert.Equal(t, "folder", s.folder)
}

func TestObjectShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Object("object")
	assert.Equal(t, "object", s.object)
}

func TestPolicyIDShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).PolicyID("policy")
	assert.Equal(t, "policy", s.policyID)
}

func TestQueryShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Query("query")
	assert.Equal(t, "query", s.query)
}

func TestQueryFormatShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).QueryFormat("query format")
	assert.Equal(t, "query format", s.queryFormat)
}

func TestReasonShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Reason("reason")
	assert.Equal(t, "reason", s.reason)
}

func TestSafeShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Safe("safe")
	assert.Equal(t, "safe", s.safe)
}

func TestTimeoutShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).Timeout(1000)
	assert.Equal(t, 1000, s.timeout)
}

func TestUserNameShouldGetSet(t *testing.T) {
	s := newGetPasswordService(nil).UserName("user")
	assert.Equal(t, "user", s.userName)
}

func TestSetParamShouldSetWhenValuePresent(t *testing.T) {
	params := url.Values{}
	setParam(&params, "foo", "bar")
	assert.Equal(t, 1, len(params))
	assert.Equal(t, "bar", params.Get("foo"))
}

func TestSetParamShouldNotSetWhenNoValue(t *testing.T) {
	params := url.Values{}
	setParam(&params, "foo", "")
	assert.Equal(t, 0, len(params))
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/zerowidth/gh-shorthand/alfred"
	"github.com/zerowidth/gh-shorthand/config"
	"testing"
)

var cfg = &config.Config{
	DefaultRepo: "zerowidth/default",
	RepoMap: map[string]string{
		"df":  "zerowidth/dotfiles",
		"df2": "zerowidth/df2",
	},
}

var defaultInMap = &config.Config{
	DefaultRepo: "zerowidth/dotfiles",
	RepoMap: map[string]string{
		"df": "zerowidth/dotfiles",
	},
}

var emptyConfig = &config.Config{}

func TestDefaults(t *testing.T) {
	items := generateItems(cfg, "")
	if len(items) > 0 {
		t.Errorf("expected default result to be empty, got %#v", items)
	}
}

type testCase struct {
	desc    string         // test case description
	input   string         // input string
	uid     string         // the results must contain an entry with this uid
	valid   bool           // and with the valid flag set to this
	title   string         // the expected title
	arg     string         // expected argument
	auto    string         // expected autocomplete arg
	cfg     *config.Config // config to use instead of the default cfg
	exclude string         // exclude any item with this UID or title
}

func TestItems(t *testing.T) {
	// Based on input, the resulting items must include one that matches either
	// the given UID or title. All items are also validated for correctness and
	// uniqueness by UID.
	testCases := []testCase{
		// basic parsing tests
		{
			desc:  "open a shorthand repo",
			input: " df",
			uid:   "gh:zerowidth/dotfiles",
			valid: true,
			title: "Open zerowidth/dotfiles (df) on GitHub",
			arg:   "open https://github.com/zerowidth/dotfiles",
		},
		{
			desc:  "open a shorthand repo and issue",
			input: " df 123",
			uid:   "gh:zerowidth/dotfiles#123",
			valid: true,
			title: "Open zerowidth/dotfiles#123 (df#123) on GitHub",
			arg:   "open https://github.com/zerowidth/dotfiles/issues/123",
		},
		{
			desc:  "open a fully qualified repo",
			input: " foo/bar",
			uid:   "gh:foo/bar",
			valid: true,
			title: "Open foo/bar on GitHub",
			arg:   "open https://github.com/foo/bar",
		},
		{
			desc:  "open a fully qualified repo and issue",
			input: " foo/bar 123",
			uid:   "gh:foo/bar#123",
			valid: true,
			title: "Open foo/bar#123 on GitHub",
			arg:   "open https://github.com/foo/bar/issues/123",
		},
		{
			desc:    "no match if any unparsed query remains after shorthand",
			input:   " df foo",
			exclude: "gh:zerowidth/dotfiles",
		},
		{
			desc:    "no match if any unparsed query remains after repo",
			input:   " foo/bar baz",
			exclude: "gh:foo/bar",
		},

		// default repo
		{
			desc:  "open an issue with the default repo",
			input: " 123",
			uid:   "gh:zerowidth/default#123",
			valid: true,
			title: "Open zerowidth/default#123 (default repo) on GitHub",
			arg:   "open https://github.com/zerowidth/default/issues/123",
		},
		{
			// validate uniqueness of UIDs when colliding with autocomplete
			desc:  "open the default repo when default is also in map",
			cfg:   defaultInMap,
			input: " ",
			uid:   "gh:zerowidth/dotfiles",
			valid: true,
			title: "Open zerowidth/dotfiles (default repo) on GitHub",
			arg:   "open https://github.com/zerowidth/dotfiles",
		},
		{
			desc:    "includes no default if remaining input isn't otherwise valid",
			input:   " foo",
			exclude: "gh:zerowidth/default",
		},

		// repo autocomplete
		{
			desc:  "autocomplete 'd', first match",
			input: " d",
			uid:   "gh:zerowidth/dotfiles",
			valid: true,
			title: "Open zerowidth/dotfiles (df) on GitHub",
			arg:   "open https://github.com/zerowidth/dotfiles",
			auto:  " df",
		},
		{
			desc:  "autocomplete 'd', second match",
			input: " d",
			uid:   "gh:zerowidth/df2",
			valid: true,
			title: "Open zerowidth/df2 (df2) on GitHub",
			arg:   "open https://github.com/zerowidth/df2",
			auto:  " df2",
		},
		{
			desc:  "autocomplete 'd', open-ended",
			input: " d",
			title: "Open d... on GitHub",
			valid: false,
		},
		{
			desc:  "autocomplete unmatched user prefix",
			input: " foo/",
			title: "Open foo/... on GitHub",
			valid: false,
		},
		{
			desc:  "does not autocomplete with fully-qualified repo",
			input: " foo/bar",
			exclude: "Open foo/bar... on GitHub",
		},
	}

	for _, tc := range testCases {
		t.Run(fmt.Sprintf("generateItems(%#v): %s", tc.input, tc.desc), func(t *testing.T) {
			if tc.cfg == nil {
				tc.cfg = cfg
			}
			items := generateItems(tc.cfg, tc.input)

			validateItems(t, tc, items)

			if tc.exclude != "" {
				item := findMatchingItem(tc.exclude, tc.exclude, items)
				if item != nil {
					t.Errorf("%+v\nexpected no item with UID or Title %q", items, tc.exclude)
				}
				return
			}

			item := findMatchingItem(tc.uid, tc.title, items)
			if item != nil {
				if tc.uid != "" && item.UID != tc.uid {
					t.Errorf("%+v\nexpected UID %q to be %q", item, item.UID, tc.uid)
				}

				if tc.title != "" && item.Title != tc.title {
					t.Errorf("%+v\nexpected Title %q to be %q", item, item.Title, tc.title)
				}

				if item.Valid != tc.valid {
					t.Errorf("%+v\nexpected Valid %t to be %t", item, item.Valid, tc.valid)
				}

				if tc.arg != "" && item.Arg != tc.arg {
					t.Errorf("%+v\nexpected Arg %q to be %q", item, item.Arg, tc.arg)
				}

				if tc.auto != "" && item.Autocomplete != tc.auto {
					t.Errorf("%+v\nexpected Autocomplete %q to be %q", item, item.Autocomplete, tc.auto)
				}
			} else {
				t.Errorf("expected item with uid %q and/or title %q in %+v", tc.uid, tc.title, items)
			}

		})
	}
}

func validateItems(t *testing.T, tc testCase, items []alfred.Item) {
	uids := map[string]bool{}
	for _, item := range items {
		if item.Title == "" {
			t.Errorf("%+v is missing a title", item)
		}
		if item.Valid {
			if item.UID == "" {
				t.Errorf("%+v is valid but missing its uid", item)
			}
			if item.Arg == "" {
				t.Errorf("%+v is valid but missing its arg", item)
			}
		}
		if item.UID != "" {
			_, exists := uids[item.UID]
			if exists {
				t.Errorf("non-unique UID %#v in %+v", item.UID, items)
			} else {
				uids[item.UID] = true
			}
		}
	}

}

// Try to find item by uid or title
func findMatchingItem(uid, title string, items []alfred.Item) *alfred.Item {
	for _, item := range items {
		if item.Title == title || (item.UID != "" && item.UID == uid) {
			return &item
		}
	}
	return nil
}
<commit_msg>Test case to check that no autocomplete applies after a space<commit_after>package main

import (
	"fmt"
	"github.com/zerowidth/gh-shorthand/alfred"
	"github.com/zerowidth/gh-shorthand/config"
	"testing"
)

var cfg = &config.Config{
	DefaultRepo: "zerowidth/default",
	RepoMap: map[string]string{
		"df":  "zerowidth/dotfiles",
		"df2": "zerowidth/df2",
	},
}

var defaultInMap = &config.Config{
	DefaultRepo: "zerowidth/dotfiles",
	RepoMap: map[string]string{
		"df": "zerowidth/dotfiles",
	},
}

var emptyConfig = &config.Config{}

func TestDefaults(t *testing.T) {
	items := generateItems(cfg, "")
	if len(items) > 0 {
		t.Errorf("expected default result to be empty, got %#v", items)
	}
}

type testCase struct {
	desc    string         // test case description
	input   string         // input string
	uid     string         // the results must contain an entry with this uid
	valid   bool           // and with the valid flag set to this
	title   string         // the expected title
	arg     string         // expected argument
	auto    string         // expected autocomplete arg
	cfg     *config.Config // config to use instead of the default cfg
	exclude string         // exclude any item with this UID or title
}

func TestItems(t *testing.T) {
	// Based on input, the resulting items must include one that matches either
	// the given UID or title. All items are also validated for correctness and
	// uniqueness by UID.
	testCases := []testCase{
		// basic parsing tests
		{
			desc:  "open a shorthand repo",
			input: " df",
			uid:   "gh:zerowidth/dotfiles",
			valid: true,
			title: "Open zerowidth/dotfiles (df) on GitHub",
			arg:   "open https://github.com/zerowidth/dotfiles",
		},
		{
			desc:  "open a shorthand repo and issue",
			input: " df 123",
			uid:   "gh:zerowidth/dotfiles#123",
			valid: true,
			title: "Open zerowidth/dotfiles#123 (df#123) on GitHub",
			arg:   "open https://github.com/zerowidth/dotfiles/issues/123",
		},
		{
			desc:  "open a fully qualified repo",
			input: " foo/bar",
			uid:   "gh:foo/bar",
			valid: true,
			title: "Open foo/bar on GitHub",
			arg:   "open https://github.com/foo/bar",
		},
		{
			desc:  "open a fully qualified repo and issue",
			input: " foo/bar 123",
			uid:   "gh:foo/bar#123",
			valid: true,
			title: "Open foo/bar#123 on GitHub",
			arg:   "open https://github.com/foo/bar/issues/123",
		},
		{
			desc:    "no match if any unparsed query remains after shorthand",
			input:   " df foo",
			exclude: "gh:zerowidth/dotfiles",
		},
		{
			desc:    "no match if any unparsed query remains after repo",
			input:   " foo/bar baz",
			exclude: "gh:foo/bar",
		},

		// default repo
		{
			desc:  "open an issue with the default repo",
			input: " 123",
			uid:   "gh:zerowidth/default#123",
			valid: true,
			title: "Open zerowidth/default#123 (default repo) on GitHub",
			arg:   "open https://github.com/zerowidth/default/issues/123",
		},
		{
			// validate uniqueness of UIDs when colliding with autocomplete
			desc:  "open the default repo when default is also in map",
			cfg:   defaultInMap,
			input: " ",
			uid:   "gh:zerowidth/dotfiles",
			valid: true,
			title: "Open zerowidth/dotfiles (default repo) on GitHub",
			arg:   "open https://github.com/zerowidth/dotfiles",
		},
		{
			desc:    "includes no default if remaining input isn't otherwise valid",
			input:   " foo",
			exclude: "gh:zerowidth/default",
		},

		// repo autocomplete
		{
			desc:  "autocomplete 'd', first match",
			input: " d",
			uid:   "gh:zerowidth/dotfiles",
			valid: true,
			title: "Open zerowidth/dotfiles (df) on GitHub",
			arg:   "open https://github.com/zerowidth/dotfiles",
			auto:  " df",
		},
		{
			desc:  "autocomplete 'd', second match",
			input: " d",
			uid:   "gh:zerowidth/df2",
			valid: true,
			title: "Open zerowidth/df2 (df2) on GitHub",
			arg:   "open https://github.com/zerowidth/df2",
			auto:  " df2",
		},
		{
			desc:  "autocomplete 'd', open-ended",
			input: " d",
			title: "Open d... on GitHub",
			valid: false,
		},
		{
			desc:  "autocomplete unmatched user prefix",
			input: " foo/",
			title: "Open foo/... on GitHub",
			valid: false,
		},
		{
			desc:    "does not autocomplete with fully-qualified repo",
			input:   " foo/bar",
			exclude: "Open foo/bar... on GitHub",
		},
		{
			desc: "no autocomplete when input has space",
			input: " foo bar",
			exclude: "Open foo bar... on GitHub",
		},
	}

	for _, tc := range testCases {
		t.Run(fmt.Sprintf("generateItems(%#v): %s", tc.input, tc.desc), func(t *testing.T) {
			if tc.cfg == nil {
				tc.cfg = cfg
			}
			items := generateItems(tc.cfg, tc.input)

			validateItems(t, tc, items)

			if tc.exclude != "" {
				item := findMatchingItem(tc.exclude, tc.exclude, items)
				if item != nil {
					t.Errorf("%+v\nexpected no item with UID or Title %q", items, tc.exclude)
				}
				return
			}

			item := findMatchingItem(tc.uid, tc.title, items)
			if item != nil {
				if tc.uid != "" && item.UID != tc.uid {
					t.Errorf("%+v\nexpected UID %q to be %q", item, item.UID, tc.uid)
				}

				if tc.title != "" && item.Title != tc.title {
					t.Errorf("%+v\nexpected Title %q to be %q", item, item.Title, tc.title)
				}

				if item.Valid != tc.valid {
					t.Errorf("%+v\nexpected Valid %t to be %t", item, item.Valid, tc.valid)
				}

				if tc.arg != "" && item.Arg != tc.arg {
					t.Errorf("%+v\nexpected Arg %q to be %q", item, item.Arg, tc.arg)
				}

				if tc.auto != "" && item.Autocomplete != tc.auto {
					t.Errorf("%+v\nexpected Autocomplete %q to be %q", item, item.Autocomplete, tc.auto)
				}
			} else {
				t.Errorf("expected item with uid %q and/or title %q in %+v", tc.uid, tc.title, items)
			}

		})
	}
}

func validateItems(t *testing.T, tc testCase, items []alfred.Item) {
	uids := map[string]bool{}
	for _, item := range items {
		if item.Title == "" {
			t.Errorf("%+v is missing a title", item)
		}
		if item.Valid {
			if item.UID == "" {
				t.Errorf("%+v is valid but missing its uid", item)
			}
			if item.Arg == "" {
				t.Errorf("%+v is valid but missing its arg", item)
			}
		}
		if item.UID != "" {
			_, exists := uids[item.UID]
			if exists {
				t.Errorf("non-unique UID %#v in %+v", item.UID, items)
			} else {
				uids[item.UID] = true
			}
		}
	}

}

// Try to find item by uid or title
func findMatchingItem(uid, title string, items []alfred.Item) *alfred.Item {
	for _, item := range items {
		if item.Title == title || (item.UID != "" && item.UID == uid) {
			return &item
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package main

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

	"github.com/opencontainers/runtime-tools/validation/util"
)

func checkMaskedPaths() error {
	g, err := util.GetDefaultGenerator()
	if err != nil {
		return err
	}

	maskedDir := "masked-dir"
	maskedSubDir := "masked-subdir"
	maskedFile := "masked-file"

	maskedDirTop := filepath.Join("/", maskedDir)
	maskedFileTop := filepath.Join("/", maskedFile)

	maskedDirSub := filepath.Join(maskedDirTop, maskedSubDir)
	maskedFileSub := filepath.Join(maskedDirTop, maskedFile)
	maskedFileSubSub := filepath.Join(maskedDirSub, maskedFile)

	g.AddLinuxMaskedPaths(maskedDirTop)
	g.AddLinuxMaskedPaths(maskedFileTop)
	g.AddLinuxMaskedPaths(maskedDirSub)
	g.AddLinuxMaskedPaths(maskedFileSub)
	g.AddLinuxMaskedPaths(maskedFileSubSub)
	err = util.RuntimeInsideValidate(g, func(path string) error {
		testDir := filepath.Join(path, maskedDirSub)
		err = os.MkdirAll(testDir, 0777)
		if err != nil {
			return err
		}
		// create a temp file to make testDir non-empty
		tmpfile, err := ioutil.TempFile(testDir, "tmp")
		if err != nil {
			return err
		}
		defer os.Remove(tmpfile.Name())

		// runtimetest cannot check the readability of empty files, so
		// write something.
		testSubSubFile := filepath.Join(path, maskedFileSubSub)
		if err := ioutil.WriteFile(testSubSubFile, []byte("secrets"), 0777); err != nil {
			return err
		}

		testSubFile := filepath.Join(path, maskedFileSub)
		if err := ioutil.WriteFile(testSubFile, []byte("secrets"), 0777); err != nil {
			return err
		}

		testFile := filepath.Join(path, maskedFile)
		return ioutil.WriteFile(testFile, []byte("secrets"), 0777)
	})
	return err
}

func checkMaskedRelPaths() error {
	g, err := util.GetDefaultGenerator()
	if err != nil {
		return err
	}

	// Deliberately set a relative path to be masked, and expect an error
	maskedRelPath := "masked-relpath"

	g.AddLinuxMaskedPaths(maskedRelPath)
	err = util.RuntimeInsideValidate(g, func(path string) error {
		testFile := filepath.Join(path, maskedRelPath)
		if _, err := os.Stat(testFile); err != nil && os.IsNotExist(err) {
			return err
		}

		return nil
	})
	if err != nil {
		return nil
	}
	return fmt.Errorf("expected: err != nil, actual: err == nil")
}

func main() {
	if err := checkMaskedPaths(); err != nil {
		util.Fatal(err)
	}

	if err := checkMaskedRelPaths(); err != nil {
		util.Fatal(err)
	}
}
<commit_msg>validation: check for invalid symlink inside container<commit_after>package main

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

	"github.com/opencontainers/runtime-tools/validation/util"
)

func checkMaskedPaths() error {
	g, err := util.GetDefaultGenerator()
	if err != nil {
		return err
	}

	maskedDir := "masked-dir"
	maskedSubDir := "masked-subdir"
	maskedFile := "masked-file"

	maskedDirTop := filepath.Join("/", maskedDir)
	maskedFileTop := filepath.Join("/", maskedFile)

	maskedDirSub := filepath.Join(maskedDirTop, maskedSubDir)
	maskedFileSub := filepath.Join(maskedDirTop, maskedFile)
	maskedFileSubSub := filepath.Join(maskedDirSub, maskedFile)

	g.AddLinuxMaskedPaths(maskedDirTop)
	g.AddLinuxMaskedPaths(maskedFileTop)
	g.AddLinuxMaskedPaths(maskedDirSub)
	g.AddLinuxMaskedPaths(maskedFileSub)
	g.AddLinuxMaskedPaths(maskedFileSubSub)
	err = util.RuntimeInsideValidate(g, func(path string) error {
		testDir := filepath.Join(path, maskedDirSub)
		err = os.MkdirAll(testDir, 0777)
		if err != nil {
			return err
		}
		// create a temp file to make testDir non-empty
		tmpfile, err := ioutil.TempFile(testDir, "tmp")
		if err != nil {
			return err
		}
		defer os.Remove(tmpfile.Name())

		// runtimetest cannot check the readability of empty files, so
		// write something.
		testSubSubFile := filepath.Join(path, maskedFileSubSub)
		if err := ioutil.WriteFile(testSubSubFile, []byte("secrets"), 0777); err != nil {
			return err
		}

		testSubFile := filepath.Join(path, maskedFileSub)
		if err := ioutil.WriteFile(testSubFile, []byte("secrets"), 0777); err != nil {
			return err
		}

		testFile := filepath.Join(path, maskedFile)
		return ioutil.WriteFile(testFile, []byte("secrets"), 0777)
	})
	return err
}

func checkMaskedRelPaths() error {
	g, err := util.GetDefaultGenerator()
	if err != nil {
		return err
	}

	// Deliberately set a relative path to be masked, and expect an error
	maskedRelPath := "masked-relpath"

	g.AddLinuxMaskedPaths(maskedRelPath)
	err = util.RuntimeInsideValidate(g, func(path string) error {
		testFile := filepath.Join(path, maskedRelPath)
		if _, err := os.Stat(testFile); err != nil && os.IsNotExist(err) {
			return err
		}

		return nil
	})
	if err != nil {
		return nil
	}
	return fmt.Errorf("expected: err != nil, actual: err == nil")
}

func checkMaskedSymlinks() error {
	g, err := util.GetDefaultGenerator()
	if err != nil {
		return err
	}

	// Deliberately create a masked symlink that points an invalid file,
	// and expect an error.
	maskedSymlink := "/masked-symlink"

	g.AddLinuxMaskedPaths(maskedSymlink)
	err = util.RuntimeInsideValidate(g, func(path string) error {
		testFile := filepath.Join(path, maskedSymlink)
		// ln -s .. /masked-symlink ; readlink -f /masked-symlink; ls -L /masked-symlink
		if err := os.Symlink("../masked-symlink", testFile); err != nil {
			return err
		}
		rPath, errR := os.Readlink(testFile)
		if errR != nil {
			return errR
		}
		_, errS := os.Stat(rPath)
		if errS != nil && os.IsNotExist(errS) {
			return errS
		}

		return nil
	})
	if err != nil {
		return nil
	}
	return fmt.Errorf("expected: err != nil, actual: err == nil")
}

func main() {
	if err := checkMaskedPaths(); err != nil {
		util.Fatal(err)
	}

	if err := checkMaskedRelPaths(); err != nil {
		util.Fatal(err)
	}

	if err := checkMaskedSymlinks(); err != nil {
		util.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package controllers

import (
	"database/sql"
	"encoding/json"
	"io/ioutil"
	"net/http"

	"strconv"

	"github.com/Sirupsen/logrus"
	"github.com/bstaijen/mariadb-for-microservices/profile-service/database"
	sharedModels "github.com/bstaijen/mariadb-for-microservices/shared/models"
	"github.com/bstaijen/mariadb-for-microservices/shared/util"
	"github.com/buger/jsonparser"
	"github.com/gorilla/mux"
	"github.com/urfave/negroni"
)

func UserByIndexHandler(connection *sql.DB) negroni.HandlerFunc {
	return negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {

		vars := mux.Vars(r)
		strID := vars["id"]

		id, err := strconv.Atoi(strID)
		if err != nil {
			logrus.Error(err)
		}

		user, err := db.GetUserByID(connection, id)

		if err != nil {
			util.SendBadRequest(w, err)
			return
		}
		util.SendOK(w, user)
	})
}

func GetUsernamesHandler(connection *sql.DB) negroni.HandlerFunc {
	return negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
		result, err := bodyToArrayWithIDs(r)

		if err != nil {
			util.SendError(w, err)
			return
		}

		users, err := db.GetUsernames(connection, result)
		if err != nil {
			util.SendError(w, err)
			return
		}

		type Resp struct {
			Usernames []*sharedModels.GetUsernamesResponse `json:"usernames"`
		}
		util.SendOK(w, &Resp{Usernames: users})
	})
}

func bodyToArrayWithIDs(req *http.Request) ([]*sharedModels.GetUsernamesRequest, error) {
	data, _ := ioutil.ReadAll(req.Body)
	defer req.Body.Close()
	objects := make([]*sharedModels.GetUsernamesRequest, 0)
	err := jsonparser.ArrayEach(data, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
		usernameReq := &sharedModels.GetUsernamesRequest{}
		json.Unmarshal(value, usernameReq)
		objects = append(objects, usernameReq)
	}, "requests")
	if err != nil {
		return nil, err
	}
	return objects, nil
}
<commit_msg>more error handling<commit_after>package controllers

import (
	"database/sql"
	"encoding/json"
	"io/ioutil"
	"net/http"

	"strconv"

	"runtime/debug"

	"github.com/Sirupsen/logrus"
	"github.com/bstaijen/mariadb-for-microservices/profile-service/database"
	sharedModels "github.com/bstaijen/mariadb-for-microservices/shared/models"
	"github.com/bstaijen/mariadb-for-microservices/shared/util"
	"github.com/buger/jsonparser"
	"github.com/gorilla/mux"
	"github.com/urfave/negroni"
)

func UserByIndexHandler(connection *sql.DB) negroni.HandlerFunc {
	return negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {

		vars := mux.Vars(r)
		strID := vars["id"]

		id, err := strconv.Atoi(strID)
		if err != nil {
			logrus.Error(err)
		}

		user, err := db.GetUserByID(connection, id)

		if err != nil {
			util.SendBadRequest(w, err)
			return
		}
		util.SendOK(w, user)
	})
}

func GetUsernamesHandler(connection *sql.DB) negroni.HandlerFunc {
	return negroni.HandlerFunc(func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
		result, err := bodyToArrayWithIDs(r)

		if err != nil {
			util.SendError(w, err)
			return
		}

		users, err := db.GetUsernames(connection, result)
		if err != nil {
			util.SendError(w, err)
			return
		}

		type Resp struct {
			Usernames []*sharedModels.GetUsernamesResponse `json:"usernames"`
		}
		util.SendOK(w, &Resp{Usernames: users})
	})
}

func bodyToArrayWithIDs(req *http.Request) ([]*sharedModels.GetUsernamesRequest, error) {
	data, _ := ioutil.ReadAll(req.Body)
	defer req.Body.Close()
	objects := make([]*sharedModels.GetUsernamesRequest, 0)
	err := jsonparser.ArrayEach(data, func(value []byte, dataType jsonparser.ValueType, offset int, err error) {
		if err != nil {
			debug.PrintStack()
			logrus.Error(err)
			return
		}

		usernameReq := &sharedModels.GetUsernamesRequest{}
		err = json.Unmarshal(value, usernameReq)
		if err != nil {
			debug.PrintStack()
			logrus.Error(err)
			return
		}

		objects = append(objects, usernameReq)
	}, "requests")
	if err != nil {
		return nil, err
	}
	return objects, nil
}
<|endoftext|>


<commit_before>package memory

import "github.com/flavioribeiro/snickers/db"

// Database struct that persists configurations
type Database struct {
	Presets map[string]db.Preset
}

// NewDatabase creates a new database
func NewDatabase() (*Database, error) {
	d := &Database{}
	d.Presets = map[string]db.Preset{}
	return d, nil
}

//CreatePreset stores preset information
func (r *Database) StorePreset(preset db.Preset) map[string]db.Preset {
	r.Presets[preset.Name] = preset
	return r.Presets
}

//RetrievePreset retrieves one preset from the database
func (r *Database) RetrievePreset(presetName string) db.Preset {
	return r.Presets[presetName]
}
<commit_msg>db/memory: update StorePreset comment<commit_after>package memory

import "github.com/flavioribeiro/snickers/db"

// Database struct that persists configurations
type Database struct {
	Presets map[string]db.Preset
}

// NewDatabase creates a new database
func NewDatabase() (*Database, error) {
	d := &Database{}
	d.Presets = map[string]db.Preset{}
	return d, nil
}

//StorePreset stores preset information
func (r *Database) StorePreset(preset db.Preset) map[string]db.Preset {
	r.Presets[preset.Name] = preset
	return r.Presets
}

//RetrievePreset retrieves one preset from the database
func (r *Database) RetrievePreset(presetName string) db.Preset {
	return r.Presets[presetName]
}
<|endoftext|>


<commit_before>package pgx_test

import (
	"fmt"
	"github.com/jackc/pgx"
)

func Example_JSON() {
	conn, err := pgx.Connect(*defaultConnConfig)
	if err != nil {
		fmt.Printf("Unable to establish connection: %v", err)
		return
	}

	type person struct {
		Name string `json:"name"`
		Age  int    `json:"age"`
	}

	input := person{
		Name: "John",
		Age:  42,
	}

	var output person

	err = conn.QueryRow("select $1::json", input).Scan(&output)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(output.Name, output.Age)
	// Output:
	// John 42
}
<commit_msg>Fake example if PostgreSQL server too old for JSON<commit_after>package pgx_test

import (
	"fmt"
	"github.com/jackc/pgx"
)

func Example_JSON() {
	conn, err := pgx.Connect(*defaultConnConfig)
	if err != nil {
		fmt.Printf("Unable to establish connection: %v", err)
		return
	}

	if _, ok := conn.PgTypes[pgx.JsonOid]; !ok {
		// No JSON type -- must be running against very old PostgreSQL
		// Pretend it works
		fmt.Println("John", 42)
		return
	}

	type person struct {
		Name string `json:"name"`
		Age  int    `json:"age"`
	}

	input := person{
		Name: "John",
		Age:  42,
	}

	var output person

	err = conn.QueryRow("select $1::json", input).Scan(&output)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(output.Name, output.Age)
	// Output:
	// John 42
}
<|endoftext|>


<commit_before>package ftp

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"net"
	"strings"
)

var users = map[string]string{
	"anonymous":  "anonymous",
	"krasoffski": "krasoffski",
}

func NewServer(address, path string) *Server {
	return &Server{Addr: address, Path: path}
}

type Server struct {
	Addr string
	Path string
}

func (s *Server) Serve() {

	listener, err := net.Listen("tcp", s.Addr)
	if err != nil {
		log.Fatal(err)
	}
	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Print(err)
			continue
		}
		h := NewHandler(conn, s.Path)
		go h.Do()
	}
}

func NewHandler(conn net.Conn, path string) *Handler {
	return &Handler{Conn: conn, Path: path}
}

type Handler struct {
	Conn net.Conn
	User string
	Path string
	Auth bool
}

func (h *Handler) Do() {
	defer h.Conn.Close()

	h.Message(220, "Welcome to Go language FTPd")
	s := bufio.NewScanner(h.Conn)
	for s.Scan() {
		args := strings.SplitN(s.Text(), " ", 2)
		h.handleCmd(args[0], args[1])
	}
}

func (h *Handler) handleCmd(cmd, arg string) {
	switch cmd {
	case "USER":
		h.HandleUSER(arg)
	case "PASS":
		h.HandlePASS(arg)
	}
}

func (h *Handler) SendLine(text string) {
	io.WriteString(h.Conn, text+"\r\n")
}

func (h *Handler) Message(code int, text string) {
	h.SendLine(fmt.Sprintf("%d %s", code, text))
}

func (h *Handler) HandleUSER(name string) {
	if h.User == "" {
		if _, ok := users[name]; ok {
			h.Message(331, fmt.Sprintf("User %s OK. Password required", name))
			h.User = name
		} else {
			h.Message(530, "Login or password incorrect!")
		}
	} else {
		// ???
	}
}

func (h *Handler) HandlePASS(password string) {
	if h.User != "" {
		if p := users[h.User]; !h.Auth && password == p {
			h.Message(230, fmt.Sprintf("Password is OK. Working directory %s", h.Path))
		} else {
			// ???
		}
	} else {
		h.Message(530, "Login or password incorrect!")
	}
}
<commit_msg>[8.2] massage with sprintf style<commit_after>package ftp

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"net"
	"strconv"
	"strings"
)

var users = map[string]string{
	"anonymous":  "anonymous",
	"krasoffski": "krasoffski",
}

func NewServer(address, path string) *Server {
	return &Server{Addr: address, Path: path}
}

type Server struct {
	Addr string
	Path string
}

func (s *Server) Serve() {

	listener, err := net.Listen("tcp", s.Addr)
	if err != nil {
		log.Fatal(err)
	}
	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Print(err)
			continue
		}
		h := NewHandler(conn, s.Path)
		go h.Start()
	}
}

func NewHandler(conn net.Conn, path string) *Handler {
	return &Handler{Conn: conn, Path: path}
}

type Handler struct {
	Conn net.Conn
	User string
	Path string
	Auth bool
}

func (h *Handler) Start() {
	defer h.Conn.Close()

	h.Message(220, "Welcome to Go language FTPd")
	s := bufio.NewScanner(h.Conn)
	for s.Scan() {
		args := strings.SplitN(s.Text(), " ", 2)
		h.handleCmd(args[0], args[1])
	}
}

func (h *Handler) handleCmd(cmd, arg string) {
	switch cmd {
	case "USER":
		h.HandleUSER(arg)
	case "PASS":
		h.HandlePASS(arg)
	}
}

func (h *Handler) SendLine(text string) {
	io.WriteString(h.Conn, text+"\r\n")
}

func (h *Handler) Message(code int, format string, args ...interface{}) {
	h.SendLine(strconv.Itoa(code) + " " + fmt.Sprintf(format, args...))
}

func (h *Handler) HandleUSER(name string) {
	if h.User == "" {
		if _, ok := users[name]; ok {
			h.Message(331, "User %s OK. Password required", name)
			h.User = name
		} else {
			h.Message(530, "Login or password incorrect!")
		}
	} else {
		// ???
	}
}

func (h *Handler) HandlePASS(password string) {
	if h.User != "" {
		if p := users[h.User]; !h.Auth && password == p {
			h.Message(230, "Password is OK. Working directory %s", h.Path)
		} else {
			// ???
		}
	} else {
		h.Message(530, "Login or password incorrect!")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/ant0ine/go-json-rest/rest"
	"github.com/garyburd/redigo/redis"
	"github.com/ulule/limiter"
)

func main() {
	// 4 reqs/hour
	rate, err := limiter.NewRateFromFormatted("4-H")
	if err != nil {
		panic(err)
	}

	// Create a Redis pool.
	pool := redis.NewPool(func() (redis.Conn, error) {
		c, err := redis.Dial("tcp", ":6379")
		if err != nil {
			return nil, err
		}
		return c, err
	}, 100)

	// Create a store with the pool.
	store, err := limiter.NewRedisStoreWithOptions(
		pool,
		limiter.StoreOptions{Prefix: "limiter_gjr_example", MaxRetry: 3})

	if err != nil {
		panic(err)
	}

	// Create API.
	api := rest.NewApi()
	api.Use(rest.DefaultDevStack...)

	// Add middleware with the limiter instance.
	api.Use(limiter.NewGJRMiddleware(limiter.NewLimiter(store, rate)))

	// Set stupid app.
	api.SetApp(rest.AppSimple(func(w rest.ResponseWriter, r *rest.Request) {
		w.WriteJson(map[string]string{"message": "ok"})
	}))

	// Run server!
	fmt.Println("Server is running on 7777...")
	log.Fatal(http.ListenAndServe(":7777", api.MakeHandler()))
}
<commit_msg>chore: delete examples with gjr<commit_after><|endoftext|>