<commit_before>package session

import (
	"bytes"
	"encoding/gob"
	"errors"
	"log"
	"time"

	"github.com/boltdb/bolt"
)

/*
BoltStore is a session storage using bolt.
*/
type BoltStore struct {
	store *bolt.DB

	lastUsedName []byte
	sessionsName []byte

	maxAge time.Duration
}

const TimeStampFormat = "2006-01-02 15:04:05.000"

/*
NewBoltStore returns a BoltStore SessionStorage.
*/
func NewBoltStore(db *bolt.DB, maxAge time.Duration) (*BoltStore, error) {
	var s BoltStore
	if maxAge < 5*time.Minute {
		return nil, errors.New("maxAge duration too short")
	}

	s.store = db
	s.maxAge = maxAge

	s.lastUsedName = []byte("sessionsLastUsed")
	s.sessionsName = []byte("sessions")

	err := db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists(s.lastUsedName)
		if err != nil {
			return err
		}
		_, err = tx.CreateBucketIfNotExists(s.sessionsName)
		if err != nil {
			return err
		}
		return nil
	})

	if err != nil {
		return nil, err
	}

	return &s, nil
}

/* Interface Functions */

// Close the Store, will also close the bolt db.
func (s *BoltStore) Close() error {
	return s.store.Close()
}

// GC one pass over the BoltStore
func (s *BoltStore) GC() error {
	err := s.store.Update(func(tx *bolt.Tx) error {
		lastUsedBucket := tx.Bucket(s.lastUsedName)
		sessionsBucket := tx.Bucket(s.sessionsName)

		lastUsedBucket.ForEach(func(k, v []byte) error {
			var t time.Time
			err := t.GobDecode(v)
			if err != nil || time.Since(t) > s.maxAge {
				lastUsedBucket.Delete(k)
				sessionsBucket.Delete(k)
			}
			return nil
		})

		return nil
	})

	log.Printf("GC Completed. %s", err)
	return err
}

// Get session associated with sid.
func (s *BoltStore) Get(sid string) (*Session, error) {
	var ses Session

	err := s.store.View(func(tx *bolt.Tx) error {
		lastUsedBucket := tx.Bucket(s.lastUsedName)
		sessionsBucket := tx.Bucket(s.sessionsName)

		bsid := []byte(sid)
		lastUsed := lastUsedBucket.Get(bsid)
		if lastUsed == nil {
			return nil
		}

		var t time.Time
		err := t.GobDecode(lastUsed)
		if err != nil || time.Since(t) > s.maxAge {
			return nil
		}

		sesGob := sessionsBucket.Get(bsid)
		if sesGob == nil {
			return nil
		}

		ses.Values, _ = ungobValues(sesGob)
		return nil
	})

	if err != nil {
		return nil, err
	}

	if ses.Values == nil {
		return nil, ErrNotFound
	}

	return &ses, nil
}

// Commit session back to storage.
func (s *BoltStore) Commit(ses *Session) error {
	err := s.store.Update(func(tx *bolt.Tx) error {
		lastUsedBucket := tx.Bucket(s.lastUsedName)
		sessionsBucket := tx.Bucket(s.sessionsName)

		bsid := []byte(ses.sid)

		tb, err := time.Now().GobEncode()
		if err != nil {
			return err
		}
		err = lastUsedBucket.Put(bsid, tb)
		if err != nil {
			return err
		}

		g, err := gobValues(ses.Values)
		if err != nil {
			return err
		}

		err = sessionsBucket.Put(bsid, g)
		if err != nil {
			return err
		}

		return nil
	})

	log.Printf("Session Committed. %s", err)
	return err
}

// Convert a map[string]string to a gobbed []byte
func gobValues(v map[string]string) ([]byte, error) {
	b := &bytes.Buffer{}
	g := gob.NewEncoder(b)

	err := g.Encode(v)
	return b.Bytes(), err
}

// Convert a gobbed map[string]string back to a map.
func ungobValues(v []byte) (map[string]string, error) {
	b := bytes.NewBuffer(v)
	g := gob.NewDecoder(b)

	var values map[string]string
	err := g.Decode(&values)
	return values, err
}

// Delete session from storage.
func (s *BoltStore) Delete(ses *Session) error {
	err := s.store.Update(func(tx *bolt.Tx) error {
		lastUsedBucket := tx.Bucket(s.lastUsedName)
		sessionsBucket := tx.Bucket(s.sessionsName)

		err := lastUsedBucket.Delete([]byte(ses.sid))
		if err != nil {
			return err
		}

		err = sessionsBucket.Delete([]byte(ses.sid))
		if err != nil {
			return err
		}

		return nil
	})

	log.Printf("Sesion Deleted. %s", err)
	return err
}
<commit_msg>remove debug crap<commit_after>package session

import (
	"bytes"
	"encoding/gob"
	"errors"
	"time"

	"github.com/boltdb/bolt"
)

/*
BoltStore is a session storage using bolt.
*/
type BoltStore struct {
	store *bolt.DB

	lastUsedName []byte
	sessionsName []byte

	maxAge time.Duration
}

const TimeStampFormat = "2006-01-02 15:04:05.000"

/*
NewBoltStore returns a BoltStore SessionStorage.
*/
func NewBoltStore(db *bolt.DB, maxAge time.Duration) (*BoltStore, error) {
	var s BoltStore
	if maxAge < 5*time.Minute {
		return nil, errors.New("maxAge duration too short")
	}

	s.store = db
	s.maxAge = maxAge

	s.lastUsedName = []byte("sessionsLastUsed")
	s.sessionsName = []byte("sessions")

	err := db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists(s.lastUsedName)
		if err != nil {
			return err
		}
		_, err = tx.CreateBucketIfNotExists(s.sessionsName)
		if err != nil {
			return err
		}
		return nil
	})

	if err != nil {
		return nil, err
	}

	return &s, nil
}

/* Interface Functions */

// Close the Store, will also close the bolt db.
func (s *BoltStore) Close() error {
	return s.store.Close()
}

// GC one pass over the BoltStore
func (s *BoltStore) GC() error {
	err := s.store.Update(func(tx *bolt.Tx) error {
		lastUsedBucket := tx.Bucket(s.lastUsedName)
		sessionsBucket := tx.Bucket(s.sessionsName)

		lastUsedBucket.ForEach(func(k, v []byte) error {
			var t time.Time
			err := t.GobDecode(v)
			if err != nil || time.Since(t) > s.maxAge {
				lastUsedBucket.Delete(k)
				sessionsBucket.Delete(k)
			}
			return nil
		})

		return nil
	})

	return err
}

// Get session associated with sid.
func (s *BoltStore) Get(sid string) (*Session, error) {
	var ses Session

	err := s.store.View(func(tx *bolt.Tx) error {
		lastUsedBucket := tx.Bucket(s.lastUsedName)
		sessionsBucket := tx.Bucket(s.sessionsName)

		bsid := []byte(sid)
		lastUsed := lastUsedBucket.Get(bsid)
		if lastUsed == nil {
			return nil
		}

		var t time.Time
		err := t.GobDecode(lastUsed)
		if err != nil || time.Since(t) > s.maxAge {
			return nil
		}

		sesGob := sessionsBucket.Get(bsid)
		if sesGob == nil {
			return nil
		}

		ses.Values, _ = ungobValues(sesGob)
		return nil
	})

	if err != nil {
		return nil, err
	}

	if ses.Values == nil {
		return nil, ErrNotFound
	}

	return &ses, nil
}

// Commit session back to storage.
func (s *BoltStore) Commit(ses *Session) error {
	err := s.store.Update(func(tx *bolt.Tx) error {
		lastUsedBucket := tx.Bucket(s.lastUsedName)
		sessionsBucket := tx.Bucket(s.sessionsName)

		bsid := []byte(ses.sid)

		tb, err := time.Now().GobEncode()
		if err != nil {
			return err
		}
		err = lastUsedBucket.Put(bsid, tb)
		if err != nil {
			return err
		}

		g, err := gobValues(ses.Values)
		if err != nil {
			return err
		}

		err = sessionsBucket.Put(bsid, g)
		if err != nil {
			return err
		}

		return nil
	})

	return err
}

// Convert a map[string]string to a gobbed []byte
func gobValues(v map[string]string) ([]byte, error) {
	b := &bytes.Buffer{}
	g := gob.NewEncoder(b)

	err := g.Encode(v)
	return b.Bytes(), err
}

// Convert a gobbed map[string]string back to a map.
func ungobValues(v []byte) (map[string]string, error) {
	b := bytes.NewBuffer(v)
	g := gob.NewDecoder(b)

	var values map[string]string
	err := g.Decode(&values)
	return values, err
}

// Delete session from storage.
func (s *BoltStore) Delete(ses *Session) error {
	err := s.store.Update(func(tx *bolt.Tx) error {
		lastUsedBucket := tx.Bucket(s.lastUsedName)
		sessionsBucket := tx.Bucket(s.sessionsName)

		err := lastUsedBucket.Delete([]byte(ses.sid))
		if err != nil {
			return err
		}

		err = sessionsBucket.Delete([]byte(ses.sid))
		if err != nil {
			return err
		}

		return nil
	})

	return err
}
<|endoftext|>


<commit_before>package abool

import (
	"math"
	"sync"
	"sync/atomic"
	"testing"
)

func TestBool(t *testing.T) {
	v := NewBool(true)
	if !v.IsSet() {
		t.Fatal("NewValue(true) failed")
	}

	v = NewBool(false)
	if v.IsSet() {
		t.Fatal("NewValue(false) failed")
	}

	v = New()
	if v.IsSet() {
		t.Fatal("Empty value of AtomicBool should be false")
	}

	v.Set()
	if !v.IsSet() {
		t.Fatal("AtomicBool.Set() failed")
	}

	v.UnSet()
	if v.IsSet() {
		t.Fatal("AtomicBool.UnSet() failed")
	}

	v.SetTo(true)
	if !v.IsSet() {
		t.Fatal("AtomicBool.SetTo(true) failed")
	}

	v.SetTo(false)
	if v.IsSet() {
		t.Fatal("AtomicBool.SetTo(false) failed")
	}

	if set := v.SetToIf(true, false); set || v.IsSet() {
		t.Fatal("AtomicBool.SetTo(true, false) failed")
	}

	if set := v.SetToIf(false, true); !set || !v.IsSet() {
		t.Fatal("AtomicBool.SetTo(false, true) failed")
	}

	v = New()
	if v.IsSet() {
		t.Fatal("Empty value of AtomicBool should be false")
	}

	_ = v.Toggle()
	if !v.IsSet() {
		t.Fatal("AtomicBool.Toggle() to true failed")
	}

	prev := v.Toggle()
	if v.IsSet() == prev.IsSet() {
		t.Fatal("AtomicBool.Toggle() to false failed")
	}
}

func TestToogleMultipleTimes(t *testing.T) {
	t.Parallel()

	v := New()
	pre := NewBool(!v.IsSet())
	for i := 0; i < 100; i++ {
		v.SetTo(false)
		for j := 0; j < i; j++ {
			pre = v.Toggle()
		}

		expected := i%2 != 0
		if v.IsSet() != expected {
			t.Fatalf("AtomicBool.Toogle() doesn't work after %d calls, expected: %v, got %v", i, expected, v.IsSet())
		}

		if pre.IsSet() == v.IsSet() {
			t.Fatalf("AtomicBool.Toogle() returned wrong value at the %dth calls, expected: %v, got %v", i, !v.IsSet(), pre.IsSet())
		}
	}
}

func TestToogleAfterOverflow(t *testing.T) {
	t.Parallel()

	var value int32 = math.MaxInt32
	v := (*AtomicBool)(&value)

	valueBeforeToggle := *(*int32)(v)

	// test first toggle after overflow
	v.Toggle()
	expected := math.MaxInt32%2 == 0
	if v.IsSet() != expected {
		t.Fatalf("AtomicBool.Toogle() doesn't work after overflow, expected: %v, got %v", expected, v.IsSet())
	}

	// make sure overflow happened
	var valueAfterToggle int32 = *(*int32)(v)
	if valueAfterToggle >= valueBeforeToggle {
		t.Fatalf("Overflow does not happen as expected, before %d, after: %d", valueBeforeToggle, valueAfterToggle)
	}

	// test second toggle after overflow
	v.Toggle()
	expected = !expected
	if v.IsSet() != expected {
		t.Fatalf("AtomicBool.Toogle() doesn't work after the second call after overflow, expected: %v, got %v", expected, v.IsSet())
	}
}

func TestRace(t *testing.T) {
	repeat := 10000
	var wg sync.WaitGroup
	wg.Add(repeat * 4)
	v := New()

	// Writer
	go func() {
		for i := 0; i < repeat; i++ {
			v.Set()
			wg.Done()
		}
	}()

	// Reader
	go func() {
		for i := 0; i < repeat; i++ {
			v.IsSet()
			wg.Done()
		}
	}()

	// Writer
	go func() {
		for i := 0; i < repeat; i++ {
			v.UnSet()
			wg.Done()
		}
	}()

	// Reader And Writer
	go func() {
		for i := 0; i < repeat; i++ {
			v.Toggle()
			wg.Done()
		}
	}()

	wg.Wait()
}

func ExampleAtomicBool() {
	cond := New()    // default to false
	cond.Set()       // set to true
	cond.IsSet()     // returns true
	cond.UnSet()     // set to false
	cond.SetTo(true) // set to whatever you want
	cond.Toggle()    // toggles the boolean value
}

// Benchmark Read

func BenchmarkMutexRead(b *testing.B) {
	var m sync.RWMutex
	var v bool
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		m.RLock()
		_ = v
		m.RUnlock()
	}
}

func BenchmarkAtomicValueRead(b *testing.B) {
	var v atomic.Value
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_ = v.Load() != nil
	}
}

func BenchmarkAtomicBoolRead(b *testing.B) {
	v := New()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_ = v.IsSet()
	}
}

// Benchmark Write

func BenchmarkMutexWrite(b *testing.B) {
	var m sync.RWMutex
	var v bool
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		m.RLock()
		v = true
		m.RUnlock()
	}
	b.StopTimer()
	_ = v
}

func BenchmarkAtomicValueWrite(b *testing.B) {
	var v atomic.Value
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		v.Store(true)
	}
}

func BenchmarkAtomicBoolWrite(b *testing.B) {
	v := New()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		v.Set()
	}
}

// Benchmark CAS

func BenchmarkMutexCAS(b *testing.B) {
	var m sync.RWMutex
	var v bool
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		m.Lock()
		if !v {
			v = true
		}
		m.Unlock()
	}
	b.StopTimer()
}

func BenchmarkAtomicBoolCAS(b *testing.B) {
	v := New()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		v.SetToIf(false, true)
	}
}

// Benchmark toggle boolean value

func BenchmarkMutexToggle(b *testing.B) {
	var m sync.RWMutex
	var v bool
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		m.Lock()
		v = !v
		m.Unlock()
	}
	b.StopTimer()
}

func BenchmarkAtomicBoolToggle(b *testing.B) {
	v := New()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		v.Toggle()
	}
}
<commit_msg>Enable parallel testing<commit_after>package abool

import (
	"math"
	"sync"
	"sync/atomic"
	"testing"
)

func TestBool(t *testing.T) {
	t.Parallel()

	v := NewBool(true)
	if !v.IsSet() {
		t.Fatal("NewValue(true) failed")
	}

	v = NewBool(false)
	if v.IsSet() {
		t.Fatal("NewValue(false) failed")
	}

	v = New()
	if v.IsSet() {
		t.Fatal("Empty value of AtomicBool should be false")
	}

	v.Set()
	if !v.IsSet() {
		t.Fatal("AtomicBool.Set() failed")
	}

	v.UnSet()
	if v.IsSet() {
		t.Fatal("AtomicBool.UnSet() failed")
	}

	v.SetTo(true)
	if !v.IsSet() {
		t.Fatal("AtomicBool.SetTo(true) failed")
	}

	v.SetTo(false)
	if v.IsSet() {
		t.Fatal("AtomicBool.SetTo(false) failed")
	}

	if set := v.SetToIf(true, false); set || v.IsSet() {
		t.Fatal("AtomicBool.SetTo(true, false) failed")
	}

	if set := v.SetToIf(false, true); !set || !v.IsSet() {
		t.Fatal("AtomicBool.SetTo(false, true) failed")
	}

	v = New()
	if v.IsSet() {
		t.Fatal("Empty value of AtomicBool should be false")
	}

	_ = v.Toggle()
	if !v.IsSet() {
		t.Fatal("AtomicBool.Toggle() to true failed")
	}

	prev := v.Toggle()
	if v.IsSet() == prev.IsSet() {
		t.Fatal("AtomicBool.Toggle() to false failed")
	}
}

func TestToogleMultipleTimes(t *testing.T) {
	t.Parallel()

	v := New()
	pre := NewBool(!v.IsSet())
	for i := 0; i < 100; i++ {
		v.SetTo(false)
		for j := 0; j < i; j++ {
			pre = v.Toggle()
		}

		expected := i%2 != 0
		if v.IsSet() != expected {
			t.Fatalf("AtomicBool.Toogle() doesn't work after %d calls, expected: %v, got %v", i, expected, v.IsSet())
		}

		if pre.IsSet() == v.IsSet() {
			t.Fatalf("AtomicBool.Toogle() returned wrong value at the %dth calls, expected: %v, got %v", i, !v.IsSet(), pre.IsSet())
		}
	}
}

func TestToogleAfterOverflow(t *testing.T) {
	t.Parallel()

	var value int32 = math.MaxInt32
	v := (*AtomicBool)(&value)

	valueBeforeToggle := *(*int32)(v)

	// test first toggle after overflow
	v.Toggle()
	expected := math.MaxInt32%2 == 0
	if v.IsSet() != expected {
		t.Fatalf("AtomicBool.Toogle() doesn't work after overflow, expected: %v, got %v", expected, v.IsSet())
	}

	// make sure overflow happened
	var valueAfterToggle int32 = *(*int32)(v)
	if valueAfterToggle >= valueBeforeToggle {
		t.Fatalf("Overflow does not happen as expected, before %d, after: %d", valueBeforeToggle, valueAfterToggle)
	}

	// test second toggle after overflow
	v.Toggle()
	expected = !expected
	if v.IsSet() != expected {
		t.Fatalf("AtomicBool.Toogle() doesn't work after the second call after overflow, expected: %v, got %v", expected, v.IsSet())
	}
}

func TestRace(t *testing.T) {
	t.Parallel()

	repeat := 10000
	var wg sync.WaitGroup
	wg.Add(repeat * 4)
	v := New()

	// Writer
	go func() {
		for i := 0; i < repeat; i++ {
			v.Set()
			wg.Done()
		}
	}()

	// Reader
	go func() {
		for i := 0; i < repeat; i++ {
			v.IsSet()
			wg.Done()
		}
	}()

	// Writer
	go func() {
		for i := 0; i < repeat; i++ {
			v.UnSet()
			wg.Done()
		}
	}()

	// Reader And Writer
	go func() {
		for i := 0; i < repeat; i++ {
			v.Toggle()
			wg.Done()
		}
	}()

	wg.Wait()
}

func ExampleAtomicBool() {
	cond := New()    // default to false
	cond.Set()       // set to true
	cond.IsSet()     // returns true
	cond.UnSet()     // set to false
	cond.SetTo(true) // set to whatever you want
	cond.Toggle()    // toggles the boolean value
}

// Benchmark Read

func BenchmarkMutexRead(b *testing.B) {
	var m sync.RWMutex
	var v bool
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		m.RLock()
		_ = v
		m.RUnlock()
	}
}

func BenchmarkAtomicValueRead(b *testing.B) {
	var v atomic.Value
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_ = v.Load() != nil
	}
}

func BenchmarkAtomicBoolRead(b *testing.B) {
	v := New()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		_ = v.IsSet()
	}
}

// Benchmark Write

func BenchmarkMutexWrite(b *testing.B) {
	var m sync.RWMutex
	var v bool
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		m.RLock()
		v = true
		m.RUnlock()
	}
	b.StopTimer()
	_ = v
}

func BenchmarkAtomicValueWrite(b *testing.B) {
	var v atomic.Value
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		v.Store(true)
	}
}

func BenchmarkAtomicBoolWrite(b *testing.B) {
	v := New()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		v.Set()
	}
}

// Benchmark CAS

func BenchmarkMutexCAS(b *testing.B) {
	var m sync.RWMutex
	var v bool
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		m.Lock()
		if !v {
			v = true
		}
		m.Unlock()
	}
	b.StopTimer()
}

func BenchmarkAtomicBoolCAS(b *testing.B) {
	v := New()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		v.SetToIf(false, true)
	}
}

// Benchmark toggle boolean value

func BenchmarkMutexToggle(b *testing.B) {
	var m sync.RWMutex
	var v bool
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		m.Lock()
		v = !v
		m.Unlock()
	}
	b.StopTimer()
}

func BenchmarkAtomicBoolToggle(b *testing.B) {
	v := New()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		v.Toggle()
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package watch

import (
	"errors"
	"sync"
	"testing"
	"time"

	"github.com/m3db/m3x/log"
	"github.com/stretchr/testify/assert"
)

func TestSource(t *testing.T) {
	testSource(t, 30, 25, 20)
	testSource(t, 22, 18, 20)
	testSource(t, 15, 10, 20)
	testSource(t, 28, 30, 20)
	testSource(t, 19, 21, 20)
	testSource(t, 13, 15, 20)
	testSource(t, 18, 22, 10)
	testSource(t, 14, 12, 15)
}

func testSource(t *testing.T, errAfter int32, closeAfter int32, watchNum int) {
	s := NewSource(
		&testSourceInput{callCount: 0, errAfter: errAfter, closeAfter: closeAfter}, log.SimpleLogger,
	)

	var wg sync.WaitGroup

	// create a few watches
	for i := 0; i < watchNum; i++ {
		wg.Add(1)
		_, w, err := s.Watch()
		assert.NoError(t, err)

		i := i
		go func() {
			var v interface{}
			count := 0
			for range w.C() {
				if v != nil {
					assert.True(t, w.Get().(int64) >= v.(int64))
				}
				v = w.Get()
				if count > i {
					w.Close()
				}
				count++
			}
			wg.Done()
		}()
	}

	// schedule a thread to close Source
	wg.Add(1)
	go func() {
		for !s.(*source).isClosed() {
			time.Sleep(time.Millisecond)
		}
		_, _, err := s.Watch()
		assert.Error(t, err)
		v := s.Get()
		assert.NotNil(t, v)
		// test Close again
		s.Close()
		assert.True(t, s.(*source).isClosed())
		assert.Equal(t, v, s.Get())
		wg.Done()
	}()

	wg.Wait()
}

type testSourceInput struct {
	callCount, errAfter, closeAfter int32
}

func (i *testSourceInput) Poll() (interface{}, error) {
	if i.callCount >= i.closeAfter {
		return nil, ErrSourceClosed
	}
	i.callCount++
	time.Sleep(time.Millisecond)
	if i.errAfter > 0 {
		i.errAfter--
		return time.Now().Unix(), nil
	}
	return nil, errors.New("mock error")
}
<commit_msg>Fix TestSource (#103)<commit_after>// Copyright (c) 2016 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package watch

import (
	"errors"
	"sync"
	"testing"
	"time"

	"github.com/m3db/m3x/log"
	"github.com/stretchr/testify/assert"
)

func TestSource(t *testing.T) {
	testSource(t, 30, 25, 20)
	testSource(t, 22, 18, 20)
	testSource(t, 15, 10, 20)
	testSource(t, 28, 30, 20)
	testSource(t, 19, 21, 20)
	testSource(t, 13, 15, 20)
	testSource(t, 18, 22, 10)
	testSource(t, 14, 12, 15)
}

func testSource(t *testing.T, errAfter int32, closeAfter int32, watchNum int) {
	input := &testSourceInput{callCount: 0, errAfter: errAfter, closeAfter: closeAfter}
	s := NewSource(input, log.SimpleLogger)

	var wg sync.WaitGroup

	// Create a few watches.
	for i := 0; i < watchNum; i++ {
		wg.Add(1)
		_, w, err := s.Watch()
		assert.NoError(t, err)
		assert.NotNil(t, w)

		i := i
		go func() {
			var v interface{}
			count := 0
			for range w.C() {
				if v != nil {
					assert.True(t, w.Get().(int32) >= v.(int32))
				}
				v = w.Get()
				if count > i {
					w.Close()
				}
				count++
			}
			wg.Done()
		}()
	}

	// Only start serving after all watchers are created.
	input.startServing()

	// Schedule a thread to close Source.
	wg.Add(1)
	go func() {
		for !s.(*source).isClosed() {
			time.Sleep(time.Millisecond)
		}
		_, _, err := s.Watch()
		assert.Error(t, err)
		v := s.Get()
		if errAfter < closeAfter {
			assert.Equal(t, v, errAfter)
		} else {
			assert.Equal(t, v, closeAfter)
		}
		// Test Close again.
		s.Close()
		assert.True(t, s.(*source).isClosed())
		assert.Equal(t, v, s.Get())
		wg.Done()
	}()

	wg.Wait()
}

type testSourceInput struct {
	sync.Mutex

	started    bool
	callCount  int32
	errAfter   int32
	closeAfter int32
}

func (i *testSourceInput) startServing() {
	i.Lock()
	i.started = true
	i.Unlock()
}

func (i *testSourceInput) Poll() (interface{}, error) {
	i.Lock()
	started := i.started
	i.Unlock()
	if !started {
		return i.callCount, nil
	}
	if i.callCount >= i.closeAfter {
		return nil, ErrSourceClosed
	}
	i.callCount++
	time.Sleep(time.Millisecond)
	if i.errAfter > 0 {
		i.errAfter--
		return i.callCount, nil
	}
	return nil, errors.New("mock error")
}
<|endoftext|>


<commit_before>package gateway

const VERSION = "v2.9.2"
<commit_msg>Version update (#2845)<commit_after>package gateway

const VERSION = "v2.9.3"
<|endoftext|>


<commit_before>// Package communicator is a system for reading and writing to http responses
package communicator

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

func New(w http.ResponseWriter) *Communicator {
	return NewCommunicatorWithCtx(w, nil)
}

func NewCommunicatorWithCtx(w http.ResponseWriter, ctx interface{}) *Communicator {
	return &Communicator{
		e:       json.NewEncoder(w),
		w:       w,
		context: ctx,
	}
}

type Communicator struct {
	e       *json.Encoder
	w       http.ResponseWriter
	context interface{}
}

func (c *Communicator) With(d interface{}) *Communicator {
	return NewCommunicatorWithCtx(c.w, d)
}

func (c *Communicator) OK(form string, s ...interface{}) {
	c.write(response{
		Message: fmt.Sprintf(form, s...),
		Error:   false,
		Code:    http.StatusOK,
		Data:    c.context,
	})
}

func (c *Communicator) Fail(form string, s ...interface{}) {
	c.write(response{
		Message: fmt.Sprintf(form, s...),
		Error:   true,
		Code:    http.StatusConflict,
		Data:    c.context,
	})
}

func (c *Communicator) Error(form string, s ...interface{}) {
	c.write(response{
		Message: fmt.Sprintf(form, s...),
		Error:   true,
		Code:    http.StatusInternalServerError,
		Data:    c.context,
	})
}

func (c *Communicator) write(r response) {
	c.w.WriteHeader(r.Code)

	if err := c.e.Encode(r); err != nil {
		c.e.Encode("Error encoding data")
	}
}

type response struct {
	Message string      `json:"message"`
	Error   bool        `json:"error"`
	Code    int         `json:"code"`
	Data    interface{} `json:"data,omitempty"`
}
<commit_msg>Fix everything being a format write<commit_after>// Package communicator is a system for reading and writing to http responses
package communicator

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

func New(w http.ResponseWriter) *Communicator {
	return NewCommunicatorWithCtx(w, nil)
}

func NewCommunicatorWithCtx(w http.ResponseWriter, ctx interface{}) *Communicator {
	return &Communicator{
		e:       json.NewEncoder(w),
		w:       w,
		context: ctx,
	}
}

type Communicator struct {
	e       *json.Encoder
	w       http.ResponseWriter
	context interface{}
}

func (c *Communicator) With(d interface{}) *Communicator {
	return NewCommunicatorWithCtx(c.w, d)
}

func (c *Communicator) OKf(form string, s ...interface{}) {
	c.OK(fmt.Sprintf(form, s...))
}

func (c *Communicator) OK(s ...interface{}) {
	c.write(response{
		Message: format(s...),
		Error:   false,
		Code:    http.StatusOK,
		Data:    c.context,
	})
}

func (c *Communicator) Failf(form string, s ...interface{}) {
	c.Fail(fmt.Sprintf(form, s...))
}

func (c *Communicator) Fail(s ...interface{}) {
	c.write(response{
		Message: format(s...),
		Error:   true,
		Code:    http.StatusConflict,
		Data:    c.context,
	})
}

func (c *Communicator) Errorf(form string, s ...interface{}) {
	c.Error(fmt.Sprintf(form, s...))

}

func (c *Communicator) Error(s ...interface{}) {
	c.write(response{
		Message: format(s...),
		Error:   true,
		Code:    http.StatusInternalServerError,
		Data:    c.context,
	})
}

func (c *Communicator) write(r response) {
	c.w.WriteHeader(r.Code)

	if err := c.e.Encode(r); err != nil {
		c.e.Encode("Error encoding data")
	}
}

type response struct {
	Message string      `json:"message"`
	Error   bool        `json:"error"`
	Code    int         `json:"code"`
	Data    interface{} `json:"data"`
}

func format(s ...interface{}) string {
	var message string
	if len(s) != 0 {
		message = fmt.Sprint(s...)
	}

	return message
}
<|endoftext|>


<commit_before>package net

import (
	"context"
	"github.com/OpenBazaar/openbazaar-go/ipfs"
	"github.com/OpenBazaar/openbazaar-go/net"
	"github.com/OpenBazaar/openbazaar-go/pb"
	"github.com/OpenBazaar/openbazaar-go/repo"
	"github.com/golang/protobuf/proto"
	"github.com/ipfs/go-ipfs/commands"
	"github.com/ipfs/go-ipfs/core"
	routing "github.com/ipfs/go-ipfs/routing/dht"
	"github.com/op/go-logging"
	"golang.org/x/net/proxy"
	libp2p "gx/ipfs/QmPGxZ1DP2w45WcogpW1h43BvseXbfke9N91qotpoQcUeS/go-libp2p-crypto"
	ma "gx/ipfs/QmSWLfmj5frN9xVLMMN846dMDriy5wN5jeghUm7aTW3DAG/go-multiaddr"
	peer "gx/ipfs/QmWUswjn261LSyVxWAEpMVtPdy8zmKBJJfBpG3Qdpa8ZsE/go-libp2p-peer"
	multihash "gx/ipfs/QmbZ6Cee2uHjG7hf19qLHppgKDRtaG4CVtMzdmK9VCVqLu/go-multihash"
	"io/ioutil"
	gonet "net"
	"net/http"
	"sync"
	"time"
)

var log = logging.MustGetLogger("retriever")

type MessageRetriever struct {
	db           repo.Datastore
	node         *core.IpfsNode
	bm           *net.BanManager
	ctx          commands.Context
	service      net.NetworkService
	prefixLen    int
	sendAck      func(peerId string, pointerID peer.ID) error
	messageQueue []pb.Envelope
	httpClient   *http.Client
	queueLock    *sync.Mutex
	*sync.WaitGroup
}

func NewMessageRetriever(db repo.Datastore, ctx commands.Context, node *core.IpfsNode, bm *net.BanManager, service net.NetworkService, prefixLen int, dialer proxy.Dialer, sendAck func(peerId string, pointerID peer.ID) error) *MessageRetriever {
	dial := gonet.Dial
	if dialer != nil {
		dial = dialer.Dial
	}
	tbTransport := &http.Transport{Dial: dial}
	client := &http.Client{Transport: tbTransport, Timeout: time.Second * 10}
	mr := MessageRetriever{db, node, bm, ctx, service, prefixLen, sendAck, nil, client, new(sync.Mutex), new(sync.WaitGroup)}
	// Add one for initial wait at start up
	mr.Add(1)
	return &mr
}

func (m *MessageRetriever) Run() {
	tick := time.NewTicker(time.Hour)
	defer tick.Stop()
	go m.fetchPointers()
	for {
		select {
		case <-tick.C:
			go m.fetchPointers()
		}
	}
}

func (m *MessageRetriever) fetchPointers() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	wg := new(sync.WaitGroup)
	wg.Add(1)
	downloaded := 0
	mh, _ := multihash.FromB58String(m.node.Identity.Pretty())
	peerOut := ipfs.FindPointersAsync(m.node.Routing.(*routing.IpfsDHT), ctx, mh, m.prefixLen)

	// Iterate over the pointers, adding 1 to the waitgroup for each pointer found
	for p := range peerOut {
		if len(p.Addrs) > 0 && !m.db.OfflineMessages().Has(p.Addrs[0].String()) {
			// IPFS
			if len(p.Addrs[0].Protocols()) == 1 && p.Addrs[0].Protocols()[0].Code == ma.P_IPFS {
				wg.Add(1)
				downloaded++
				go m.fetchIPFS(p.ID, m.ctx, p.Addrs[0], wg)
			}

			// HTTPS
			if len(p.Addrs[0].Protocols()) == 2 && p.Addrs[0].Protocols()[0].Code == ma.P_IPFS && p.Addrs[0].Protocols()[1].Code == ma.P_HTTPS {
				enc, err := p.Addrs[0].ValueForProtocol(ma.P_IPFS)
				if err != nil {
					continue
				}
				mh, err := multihash.FromB58String(enc)
				if err != nil {
					continue
				}
				d, err := multihash.Decode(mh)
				if err != nil {
					continue
				}
				wg.Add(1)
				downloaded++
				go m.fetchHTTPS(p.ID, string(d.Digest), p.Addrs[0], wg)
			}
		}
	}
	// We have finished fetching pointers from the DHT
	wg.Done()

	// Wait for each goroutine to finish then process any remaining messages that needed to be processed last
	wg.Wait()
	for _, env := range m.messageQueue {
		m.handleMessage(env, nil)
	}
	m.messageQueue = []pb.Envelope{}

	// For initial start up only
	if m.WaitGroup != nil {
		m.Done()
		m.WaitGroup = nil
	}
}

func (m *MessageRetriever) fetchIPFS(pid peer.ID, ctx commands.Context, addr ma.Multiaddr, wg *sync.WaitGroup) {
	defer wg.Done()
	ciphertext, err := ipfs.Cat(ctx, addr.String())
	if err != nil {
		log.Errorf("Error retrieving offline message: %s", err.Error())
		return
	}
	m.attemptDecrypt(ciphertext, pid)
	m.db.OfflineMessages().Put(addr.String())
}

func (m *MessageRetriever) fetchHTTPS(pid peer.ID, url string, addr ma.Multiaddr, wg *sync.WaitGroup) {
	defer wg.Done()
	resp, err := m.httpClient.Get(url)
	if err != nil {
		log.Errorf("Error retrieving offline message: %s", err.Error())
		return
	}
	ciphertext, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Errorf("Error retrieving offline message: %s", err.Error())
		return
	}
	m.attemptDecrypt(ciphertext, pid)
	m.db.OfflineMessages().Put(addr.String())
}

func (m *MessageRetriever) attemptDecrypt(ciphertext []byte, pid peer.ID) {
	// Decrypt and unmarshal plaintext
	plaintext, err := net.Decrypt(m.node.PrivateKey, ciphertext)
	if err != nil {
		return
	}

	// Unmarshal plaintext
	env := pb.Envelope{}
	err = proto.Unmarshal(plaintext, &env)
	if err != nil {
		return
	}

	// Validate the signature
	ser, err := proto.Marshal(env.Message)
	if err != nil {
		return
	}
	pubkey, err := libp2p.UnmarshalPublicKey(env.Pubkey)
	if err != nil {
		return
	}

	valid, err := pubkey.Verify(ser, env.Signature)
	if err != nil || !valid {
		return
	}

	id, err := peer.IDFromPublicKey(pubkey)
	if err != nil {
		return
	}

	if m.bm.IsBanned(id) {
		return
	}

	m.node.Peerstore.AddPubKey(id, pubkey)

	// Respond with an ACK
	if env.Message.MessageType != pb.Message_OFFLINE_ACK {
		m.sendAck(id.Pretty(), pid)
	}

	/* Order messages need to be processed in the correct order, so cancel
	and dispute close messages need to be processed last. */
	if env.Message.MessageType == pb.Message_ORDER_CANCEL || env.Message.MessageType == pb.Message_DISPUTE_CLOSE {
		m.queueLock.Lock()
		m.messageQueue = append(m.messageQueue, env)
		m.queueLock.Unlock()
		return
	}

	m.handleMessage(env, &id)
}

func (m *MessageRetriever) handleMessage(env pb.Envelope, id *peer.ID) {
	if id == nil {
		// Get the peer ID from the public key
		pubkey, err := libp2p.UnmarshalPublicKey(env.Pubkey)
		if err != nil {
			return
		}
		i, err := peer.IDFromPublicKey(pubkey)
		if err != nil {
			return
		}
		id = &i
	}

	// Get handler for this message type
	handler := m.service.HandlerForMsgType(env.Message.MessageType)
	if handler == nil {
		log.Debug("Got back nil handler from HandlerForMsgType")
		return
	}

	// Dispatch handler
	_, err := handler(*id, env.Message, true)
	if err != nil {
		log.Errorf("Handle message error: %s", err)
		return
	}
}
<commit_msg>Process all offline message in correct order<commit_after>package net

import (
	"context"
	"github.com/OpenBazaar/openbazaar-go/ipfs"
	"github.com/OpenBazaar/openbazaar-go/net"
	"github.com/OpenBazaar/openbazaar-go/pb"
	"github.com/OpenBazaar/openbazaar-go/repo"
	"github.com/golang/protobuf/proto"
	"github.com/ipfs/go-ipfs/commands"
	"github.com/ipfs/go-ipfs/core"
	routing "github.com/ipfs/go-ipfs/routing/dht"
	"github.com/op/go-logging"
	"golang.org/x/net/proxy"
	libp2p "gx/ipfs/QmPGxZ1DP2w45WcogpW1h43BvseXbfke9N91qotpoQcUeS/go-libp2p-crypto"
	ma "gx/ipfs/QmSWLfmj5frN9xVLMMN846dMDriy5wN5jeghUm7aTW3DAG/go-multiaddr"
	peer "gx/ipfs/QmWUswjn261LSyVxWAEpMVtPdy8zmKBJJfBpG3Qdpa8ZsE/go-libp2p-peer"
	multihash "gx/ipfs/QmbZ6Cee2uHjG7hf19qLHppgKDRtaG4CVtMzdmK9VCVqLu/go-multihash"
	"io/ioutil"
	gonet "net"
	"net/http"
	"sync"
	"time"
)

var log = logging.MustGetLogger("retriever")

type MessageRetriever struct {
	db           repo.Datastore
	node         *core.IpfsNode
	bm           *net.BanManager
	ctx          commands.Context
	service      net.NetworkService
	prefixLen    int
	sendAck      func(peerId string, pointerID peer.ID) error
	messageQueue map[pb.Message_MessageType][]pb.Envelope
	httpClient   *http.Client
	queueLock    *sync.Mutex
	*sync.WaitGroup
}

func NewMessageRetriever(db repo.Datastore, ctx commands.Context, node *core.IpfsNode, bm *net.BanManager, service net.NetworkService, prefixLen int, dialer proxy.Dialer, sendAck func(peerId string, pointerID peer.ID) error) *MessageRetriever {
	dial := gonet.Dial
	if dialer != nil {
		dial = dialer.Dial
	}
	tbTransport := &http.Transport{Dial: dial}
	client := &http.Client{Transport: tbTransport, Timeout: time.Second * 10}
	mr := MessageRetriever{db, node, bm, ctx, service, prefixLen, sendAck, make(map[pb.Message_MessageType][]pb.Envelope), client, new(sync.Mutex), new(sync.WaitGroup)}
	// Add one for initial wait at start up
	mr.Add(1)
	return &mr
}

func (m *MessageRetriever) Run() {
	tick := time.NewTicker(time.Hour)
	defer tick.Stop()
	go m.fetchPointers()
	for {
		select {
		case <-tick.C:
			go m.fetchPointers()
		}
	}
}

func (m *MessageRetriever) fetchPointers() {
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()
	wg := new(sync.WaitGroup)
	wg.Add(1)
	downloaded := 0
	mh, _ := multihash.FromB58String(m.node.Identity.Pretty())
	peerOut := ipfs.FindPointersAsync(m.node.Routing.(*routing.IpfsDHT), ctx, mh, m.prefixLen)

	// Iterate over the pointers, adding 1 to the waitgroup for each pointer found
	for p := range peerOut {
		if len(p.Addrs) > 0 && !m.db.OfflineMessages().Has(p.Addrs[0].String()) {
			// IPFS
			if len(p.Addrs[0].Protocols()) == 1 && p.Addrs[0].Protocols()[0].Code == ma.P_IPFS {
				wg.Add(1)
				downloaded++
				go m.fetchIPFS(p.ID, m.ctx, p.Addrs[0], wg)
			}

			// HTTPS
			if len(p.Addrs[0].Protocols()) == 2 && p.Addrs[0].Protocols()[0].Code == ma.P_IPFS && p.Addrs[0].Protocols()[1].Code == ma.P_HTTPS {
				enc, err := p.Addrs[0].ValueForProtocol(ma.P_IPFS)
				if err != nil {
					continue
				}
				mh, err := multihash.FromB58String(enc)
				if err != nil {
					continue
				}
				d, err := multihash.Decode(mh)
				if err != nil {
					continue
				}
				wg.Add(1)
				downloaded++
				go m.fetchHTTPS(p.ID, string(d.Digest), p.Addrs[0], wg)
			}
		}
	}
	// We have finished fetching pointers from the DHT
	wg.Done()

	// Wait for each goroutine to finish then process any remaining messages that needed to be processed last
	wg.Wait()

	processQueue := func(queue []pb.Envelope) {
		for _, env := range queue {
			m.handleMessage(env, nil)
		}
	}

	queue, ok := m.messageQueue[pb.Message_ORDER]
	if ok {
		processQueue(queue)
	}
	queue, ok = m.messageQueue[pb.Message_ORDER_CANCEL]
	if ok {
		processQueue(queue)
	}
	queue, ok = m.messageQueue[pb.Message_ORDER_REJECT]
	if ok {
		processQueue(queue)
	}
	queue, ok = m.messageQueue[pb.Message_ORDER_CONFIRMATION]
	if ok {
		processQueue(queue)
	}
	queue, ok = m.messageQueue[pb.Message_ORDER_FULFILLMENT]
	if ok {
		processQueue(queue)
	}
	queue, ok = m.messageQueue[pb.Message_REFUND]
	if ok {
		processQueue(queue)
	}
	queue, ok = m.messageQueue[pb.Message_DISPUTE_OPEN]
	if ok {
		processQueue(queue)
	}
	queue, ok = m.messageQueue[pb.Message_DISPUTE_UPDATE]
	if ok {
		processQueue(queue)
	}
	queue, ok = m.messageQueue[pb.Message_DISPUTE_CLOSE]
	if ok {
		processQueue(queue)
	}
	queue, ok = m.messageQueue[pb.Message_ORDER_COMPLETION]
	if ok {
		processQueue(queue)
	}
	m.messageQueue = make(map[pb.Message_MessageType][]pb.Envelope)

	// For initial start up only
	if m.WaitGroup != nil {
		m.Done()
		m.WaitGroup = nil
	}
}

func (m *MessageRetriever) fetchIPFS(pid peer.ID, ctx commands.Context, addr ma.Multiaddr, wg *sync.WaitGroup) {
	defer wg.Done()
	ciphertext, err := ipfs.Cat(ctx, addr.String())
	if err != nil {
		log.Errorf("Error retrieving offline message: %s", err.Error())
		return
	}
	m.attemptDecrypt(ciphertext, pid)
	m.db.OfflineMessages().Put(addr.String())
}

func (m *MessageRetriever) fetchHTTPS(pid peer.ID, url string, addr ma.Multiaddr, wg *sync.WaitGroup) {
	defer wg.Done()
	resp, err := m.httpClient.Get(url)
	if err != nil {
		log.Errorf("Error retrieving offline message: %s", err.Error())
		return
	}
	ciphertext, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Errorf("Error retrieving offline message: %s", err.Error())
		return
	}
	m.attemptDecrypt(ciphertext, pid)
	m.db.OfflineMessages().Put(addr.String())
}

func (m *MessageRetriever) attemptDecrypt(ciphertext []byte, pid peer.ID) {
	// Decrypt and unmarshal plaintext
	plaintext, err := net.Decrypt(m.node.PrivateKey, ciphertext)
	if err != nil {
		return
	}

	// Unmarshal plaintext
	env := pb.Envelope{}
	err = proto.Unmarshal(plaintext, &env)
	if err != nil {
		return
	}

	// Validate the signature
	ser, err := proto.Marshal(env.Message)
	if err != nil {
		return
	}
	pubkey, err := libp2p.UnmarshalPublicKey(env.Pubkey)
	if err != nil {
		return
	}

	valid, err := pubkey.Verify(ser, env.Signature)
	if err != nil || !valid {
		return
	}

	id, err := peer.IDFromPublicKey(pubkey)
	if err != nil {
		return
	}

	if m.bm.IsBanned(id) {
		return
	}

	m.node.Peerstore.AddPubKey(id, pubkey)

	// Respond with an ACK
	if env.Message.MessageType != pb.Message_OFFLINE_ACK {
		m.sendAck(id.Pretty(), pid)
	}

	// Order messages need to be processed in the correct order so let's cue them up
	m.queueLock.Lock()
	defer m.queueLock.Unlock()
	switch env.Message.MessageType {
	case pb.Message_ORDER:
		m.messageQueue[pb.Message_ORDER] = append(m.messageQueue[pb.Message_ORDER], env)
	case pb.Message_ORDER_CANCEL:
		m.messageQueue[pb.Message_ORDER_CANCEL] = append(m.messageQueue[pb.Message_ORDER_CANCEL], env)
	case pb.Message_ORDER_REJECT:
		m.messageQueue[pb.Message_ORDER_REJECT] = append(m.messageQueue[pb.Message_ORDER_REJECT], env)
	case pb.Message_ORDER_CONFIRMATION:
		m.messageQueue[pb.Message_ORDER_CONFIRMATION] = append(m.messageQueue[pb.Message_ORDER_CONFIRMATION], env)
	case pb.Message_ORDER_FULFILLMENT:
		m.messageQueue[pb.Message_ORDER_FULFILLMENT] = append(m.messageQueue[pb.Message_ORDER_FULFILLMENT], env)
	case pb.Message_ORDER_COMPLETION:
		m.messageQueue[pb.Message_ORDER_COMPLETION] = append(m.messageQueue[pb.Message_ORDER_COMPLETION], env)
	case pb.Message_DISPUTE_OPEN:
		m.messageQueue[pb.Message_DISPUTE_OPEN] = append(m.messageQueue[pb.Message_DISPUTE_OPEN], env)
	case pb.Message_DISPUTE_UPDATE:
		m.messageQueue[pb.Message_DISPUTE_UPDATE] = append(m.messageQueue[pb.Message_DISPUTE_UPDATE], env)
	case pb.Message_DISPUTE_CLOSE:
		m.messageQueue[pb.Message_DISPUTE_CLOSE] = append(m.messageQueue[pb.Message_DISPUTE_CLOSE], env)
	case pb.Message_REFUND:
		m.messageQueue[pb.Message_REFUND] = append(m.messageQueue[pb.Message_REFUND], env)
	default:
		m.handleMessage(env, &id)
	}
}

func (m *MessageRetriever) handleMessage(env pb.Envelope, id *peer.ID) {
	if id == nil {
		// Get the peer ID from the public key
		pubkey, err := libp2p.UnmarshalPublicKey(env.Pubkey)
		if err != nil {
			return
		}
		i, err := peer.IDFromPublicKey(pubkey)
		if err != nil {
			return
		}
		id = &i
	}

	// Get handler for this message type
	handler := m.service.HandlerForMsgType(env.Message.MessageType)
	if handler == nil {
		log.Debug("Got back nil handler from HandlerForMsgType")
		return
	}

	// Dispatch handler
	_, err := handler(*id, env.Message, true)
	if err != nil {
		log.Errorf("Handle message error: %s", err)
		return
	}
}
<|endoftext|>


<commit_before>package nethlp

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

	"bitbucket.org/pihao/phtool-api/lib/filehlp"
)

type Cookie struct {
	FilePath string
	Data     CookieItems
}
type CookieItems map[string]CookieItem
type CookieItem struct {
	Value string
	Args  string
}

func NewCookie(filePath string) *Cookie {
	c := Cookie{
		FilePath: filePath,
	}
	c.readSaved()
	return &c
}

func (this *Cookie) Value() string {
	arr := []string{}
	for k, v := range this.Data {
		arr = append(arr, fmt.Sprintf("%s=%s", k, v.Value))
	}
	return strings.Join(arr, "; ")
}

func (this *Cookie) Set(rsp *http.Response) {
	new_c := *this.parseResponse(rsp)
	if len(new_c) == 0 {
		fmt.Printf("cookie is null: %v", this.FilePath)
	}
	for k, v := range new_c {
		this.Data[k] = v
	}
	this.save()
}

func (this *Cookie) parseResponse(rsp *http.Response) *CookieItems {
	data := CookieItems{}
	for _, e := range rsp.Header["Set-Cookie"] {
		sp := regexp.MustCompile("; ").Split(e, 2)
		pair := strings.Split(sp[0], "=")
		if len(pair) != 2 {
			fmt.Println("read 'Set-Cookie' failed:", this.FilePath)
			continue
		}
		args := ""
		if len(sp) == 2 {
			args = sp[1]
		}
		data[pair[0]] = CookieItem{pair[1], args}
	}
	return &data
}

func (this *Cookie) readSaved() {
	v := CookieItems{}
	if err := filehlp.ReadJSON(&v, this.FilePath); err != nil && err != io.EOF {
		panic(fmt.Sprintf("read cookie error: %v, %v", this.FilePath, err))
	}
	this.Data = v
}

func (this *Cookie) save() {
	if err := filehlp.WriteJSON(&this.Data, this.FilePath, true); err != nil {
		panic(fmt.Sprintf("write cookie error: %v, %v", this.FilePath, err))
	}
}
<commit_msg>Fix dependency issue<commit_after><|endoftext|>


<commit_before>package main

import (
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"time"

	"github.com/ogier/pflag"
	"github.com/papertrail/remote_syslog2/papertrail"
	"github.com/papertrail/remote_syslog2/syslog"
	"github.com/papertrail/remote_syslog2/utils"
	"launchpad.net/goyaml"
)

const (
	MinimumRefreshInterval = (time.Duration(10) * time.Second)
	DefaultConfigFile      = "/etc/log_files.yml"
)

type ConfigFile struct {
	Files       []string
	Destination struct {
		Host     string `yaml:"host"`
		Port     int    `yaml:"port"`
		Protocol string `yaml:"protocol"`
	}
	Hostname string `yaml:"hostname"`
	//SetYAML is only called on pointers
	RefreshInterval *RefreshInterval `yaml:"new_file_check_interval"`
	ExcludeFiles    *RegexCollection `yaml:"exclude_files"`
	ExcludePatterns *RegexCollection `yaml:"exclude_patterns"`
}

type ConfigManager struct {
	Config    ConfigFile
	FlagFiles []string
	Flags     struct {
		Hostname        string
		DestHost        string
		DestPort        int
		ConfigFile      string
		LogLevels       string
		DebugLogFile    string
		PidFile         string
		RefreshInterval RefreshInterval
		UseTCP          bool
		UseTLS          bool
		NoDaemonize     bool
		Severity        string
		Facility        string
	}
}

type RefreshInterval struct {
	Duration time.Duration
}

func (r *RefreshInterval) String() string {
	return fmt.Sprint(*r)
}

func (r *RefreshInterval) Set(value string) error {
	d, err := time.ParseDuration(value)

	if err != nil {
		return err
	}

	if d < MinimumRefreshInterval {
		return fmt.Errorf("refresh interval must be greater than %s", MinimumRefreshInterval)
	}
	r.Duration = d
	return nil
}

func (r *RefreshInterval) SetYAML(tag string, value interface{}) bool {
	err := r.Set(value.(string))
	if err != nil {
		return false
	}
	return true
}

type RegexCollection []*regexp.Regexp

func (r *RegexCollection) Set(value string) error {
	exp, err := regexp.Compile(value)
	if err != nil {
		return err
	}
	*r = append(*r, exp)
	return nil
}

func (r *RegexCollection) String() string {
	return fmt.Sprint(*r)
}

func (r *RegexCollection) SetYAML(tag string, value interface{}) bool {
	items, ok := value.([]interface{})

	if !ok {
		return false
	}

	for _, item := range items {
		s, ok := item.(string)

		if !ok {
			return false
		}

		err := r.Set(s)
		if err != nil {
			panic(fmt.Sprintf("Failed to compile regex expression \"%s\"", s))
		}
	}

	return true
}

func NewConfigManager() ConfigManager {
	cm := ConfigManager{}
	err := cm.Initialize()

	if err != nil {
		log.Criticalf("Failed to configure the application: %s", err)
		os.Exit(1)
	}

	return cm
}

func (cm *ConfigManager) Initialize() error {
	cm.Config.ExcludeFiles = &RegexCollection{}
	cm.Config.ExcludePatterns = &RegexCollection{}
	cm.parseFlags()

	err := cm.readConfig()
	if err != nil {
		return err
	}
	return nil
}

func (cm *ConfigManager) parseFlags() {
	pflag.StringVarP(&cm.Flags.ConfigFile, "configfile", "c", DefaultConfigFile, "Path to config")
	pflag.StringVarP(&cm.Flags.DestHost, "dest-host", "d", "", "Destination syslog hostname or IP")
	pflag.IntVarP(&cm.Flags.DestPort, "dest-port", "p", 0, "Destination syslog port")
	if utils.CanDaemonize {
		pflag.BoolVarP(&cm.Flags.NoDaemonize, "no-detach", "D", false, "Don't daemonize and detach from the terminal")
	} else {
		cm.Flags.NoDaemonize = true
	}
	pflag.StringVarP(&cm.Flags.Facility, "facility", "f", "user", "Facility")
	pflag.StringVar(&cm.Flags.Hostname, "hostname", "", "Local hostname to send from")
	pflag.StringVar(&cm.Flags.PidFile, "pid-file", "", "Location of the PID file")
	// --parse-syslog
	pflag.StringVarP(&cm.Flags.Severity, "severity", "s", "notice", "Severity")
	// --strip-color
	pflag.BoolVar(&cm.Flags.UseTCP, "tcp", false, "Connect via TCP (no TLS)")
	pflag.BoolVar(&cm.Flags.UseTLS, "tls", false, "Connect via TCP with TLS")
	pflag.Var(&cm.Flags.RefreshInterval, "new-file-check-interval", "How often to check for new files")
	_ = pflag.Bool("no-eventmachine-tail", false, "No action, provided for backwards compatibility")
	_ = pflag.Bool("eventmachine-tail", false, "No action, provided for backwards compatibility")
	pflag.StringVar(&cm.Flags.DebugLogFile, "debug-log-cfg", "", "the debug log file")
	pflag.StringVar(&cm.Flags.LogLevels, "log", "<root>=INFO", "\"logging configuration <root>=INFO;first=TRACE\"")
	pflag.Parse()
	cm.FlagFiles = pflag.Args()
}

func (cm *ConfigManager) readConfig() error {
	log.Infof("Reading configuration file %s", cm.Flags.ConfigFile)
	err := cm.loadConfigFile()
	if err != nil {
		log.Errorf("%s", err)
		return err
	}
	return nil
}

func (cm *ConfigManager) loadConfigFile() error {
	file, err := ioutil.ReadFile(cm.Flags.ConfigFile)
	// don't error if the default config file isn't found
	if os.IsNotExist(err) && cm.Flags.ConfigFile == DefaultConfigFile {
		return nil
	}
	if err != nil {
		return fmt.Errorf("Could not read the config file: %s", err)
	}

	err = goyaml.Unmarshal(file, &cm.Config)
	if err != nil {
		return fmt.Errorf("Could not parse the config file: %s", err)
	}
	return nil
}

func (cm *ConfigManager) Daemonize() bool {
	return !cm.Flags.NoDaemonize
}

func (cm *ConfigManager) Hostname() string {
	switch {
	case cm.Flags.Hostname != "":
		return cm.Flags.Hostname
	case cm.Config.Hostname != "":
		return cm.Config.Hostname
	default:
		hostname, _ := os.Hostname()
		return hostname
	}
}

func (cm *ConfigManager) RootCAs() *x509.CertPool {
	if cm.DestProtocol() == "tls" && cm.DestHost() == "logs.papertrailapp.com" {
		return papertrail.RootCA()
	} else {
		return nil
	}
}

func (cm *ConfigManager) DestHost() string {
	switch {
	case cm.Flags.DestHost != "":
		return cm.Flags.DestHost
	case cm.Config.Destination.Host == "":
		log.Criticalf("No destination hostname specified")
		os.Exit(1)
	}
	return cm.Config.Destination.Host
}

func (cm ConfigManager) DestPort() int {
	switch {
	case cm.Flags.DestPort != 0:
		return cm.Flags.DestPort
	case cm.Config.Destination.Port != 0:
		return cm.Config.Destination.Port
	default:
		return 514
	}
}

func (cm *ConfigManager) DestProtocol() string {
	switch {
	case cm.Flags.UseTLS:
		return "tls"
	case cm.Flags.UseTCP:
		return "tcp"
	case cm.Config.Destination.Protocol != "":
		return cm.Config.Destination.Protocol
	default:
		return "udp"
	}
}

func (cm *ConfigManager) Severity() syslog.Priority {
	s, err := syslog.Severity(cm.Flags.Severity)
	if err != nil {
		log.Criticalf("%s is not a designated facility", cm.Flags.Severity)
		os.Exit(1)
	}
	return s
}

func (cm *ConfigManager) Facility() syslog.Priority {
	f, err := syslog.Facility(cm.Flags.Facility)
	if err != nil {
		log.Criticalf("%s is not a designated facility", cm.Flags.Facility)
		os.Exit(1)
	}
	return f
}

func (cm *ConfigManager) Files() []string {
	return append(cm.FlagFiles, cm.Config.Files...)
}

func (cm *ConfigManager) DebugLogFile() string {
	switch {
	case cm.Flags.DebugLogFile != "":
		return cm.Flags.DebugLogFile
	default:
		return "/dev/null"
	}
}

func (cm *ConfigManager) defaultPidFile() string {
	pidFiles := []string{
		"/var/run/remote_syslog.pid",
		os.Getenv("HOME") + "/run/remote_syslog.pid",
		os.Getenv("HOME") + "/tmp/remote_syslog.pid",
		os.Getenv("HOME") + "/remote_syslog.pid",
		os.TempDir() + "/remote_syslog.pid",
		os.Getenv("TMPDIR") + "/remote_syslog.pid",
	}
	for _, f := range pidFiles {
		dir := filepath.Dir(f)
		dirStat, err := os.Stat(dir)
		if err != nil || dirStat == nil || !dirStat.IsDir() {
			continue
		}
		fd, err := os.OpenFile(f, os.O_WRONLY|os.O_CREATE, 0644)
		if err != nil {
			continue
		}
		fd.Close()
		return f
	}
	return "/tmp/remote_syslog.pid"
}

func (cm *ConfigManager) PidFile() string {
	switch {
	case cm.Flags.PidFile != "":
		return cm.Flags.PidFile
	default:
		return cm.defaultPidFile()
	}
}

func (cm *ConfigManager) LogLevels() string {
	return cm.Flags.LogLevels
}

func (cm *ConfigManager) RefreshInterval() RefreshInterval {
	switch {
	case cm.Config.RefreshInterval != nil && cm.Flags.RefreshInterval.Duration != 0:
		return cm.Flags.RefreshInterval
	case cm.Config.RefreshInterval != nil:
		return *cm.Config.RefreshInterval
	case cm.Flags.RefreshInterval.Duration != 0:
		return cm.Flags.RefreshInterval
	}
	return RefreshInterval{Duration: MinimumRefreshInterval}
}

func (cm *ConfigManager) ExcludeFiles() []*regexp.Regexp {
	return *cm.Config.ExcludeFiles
}

func (cm *ConfigManager) ExcludePatterns() []*regexp.Regexp {
	return *cm.Config.ExcludePatterns
}
<commit_msg>Delete temp pid files<commit_after>package main

import (
	"crypto/x509"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"time"

	"github.com/ogier/pflag"
	"github.com/papertrail/remote_syslog2/papertrail"
	"github.com/papertrail/remote_syslog2/syslog"
	"github.com/papertrail/remote_syslog2/utils"
	"launchpad.net/goyaml"
)

const (
	MinimumRefreshInterval = (time.Duration(10) * time.Second)
	DefaultConfigFile      = "/etc/log_files.yml"
)

type ConfigFile struct {
	Files       []string
	Destination struct {
		Host     string `yaml:"host"`
		Port     int    `yaml:"port"`
		Protocol string `yaml:"protocol"`
	}
	Hostname string `yaml:"hostname"`
	//SetYAML is only called on pointers
	RefreshInterval *RefreshInterval `yaml:"new_file_check_interval"`
	ExcludeFiles    *RegexCollection `yaml:"exclude_files"`
	ExcludePatterns *RegexCollection `yaml:"exclude_patterns"`
}

type ConfigManager struct {
	Config    ConfigFile
	FlagFiles []string
	Flags     struct {
		Hostname        string
		DestHost        string
		DestPort        int
		ConfigFile      string
		LogLevels       string
		DebugLogFile    string
		PidFile         string
		RefreshInterval RefreshInterval
		UseTCP          bool
		UseTLS          bool
		NoDaemonize     bool
		Severity        string
		Facility        string
	}
}

type RefreshInterval struct {
	Duration time.Duration
}

func (r *RefreshInterval) String() string {
	return fmt.Sprint(*r)
}

func (r *RefreshInterval) Set(value string) error {
	d, err := time.ParseDuration(value)

	if err != nil {
		return err
	}

	if d < MinimumRefreshInterval {
		return fmt.Errorf("refresh interval must be greater than %s", MinimumRefreshInterval)
	}
	r.Duration = d
	return nil
}

func (r *RefreshInterval) SetYAML(tag string, value interface{}) bool {
	err := r.Set(value.(string))
	if err != nil {
		return false
	}
	return true
}

type RegexCollection []*regexp.Regexp

func (r *RegexCollection) Set(value string) error {
	exp, err := regexp.Compile(value)
	if err != nil {
		return err
	}
	*r = append(*r, exp)
	return nil
}

func (r *RegexCollection) String() string {
	return fmt.Sprint(*r)
}

func (r *RegexCollection) SetYAML(tag string, value interface{}) bool {
	items, ok := value.([]interface{})

	if !ok {
		return false
	}

	for _, item := range items {
		s, ok := item.(string)

		if !ok {
			return false
		}

		err := r.Set(s)
		if err != nil {
			panic(fmt.Sprintf("Failed to compile regex expression \"%s\"", s))
		}
	}

	return true
}

func NewConfigManager() ConfigManager {
	cm := ConfigManager{}
	err := cm.Initialize()

	if err != nil {
		log.Criticalf("Failed to configure the application: %s", err)
		os.Exit(1)
	}

	return cm
}

func (cm *ConfigManager) Initialize() error {
	cm.Config.ExcludeFiles = &RegexCollection{}
	cm.Config.ExcludePatterns = &RegexCollection{}
	cm.parseFlags()

	err := cm.readConfig()
	if err != nil {
		return err
	}
	return nil
}

func (cm *ConfigManager) parseFlags() {
	pflag.StringVarP(&cm.Flags.ConfigFile, "configfile", "c", DefaultConfigFile, "Path to config")
	pflag.StringVarP(&cm.Flags.DestHost, "dest-host", "d", "", "Destination syslog hostname or IP")
	pflag.IntVarP(&cm.Flags.DestPort, "dest-port", "p", 0, "Destination syslog port")
	if utils.CanDaemonize {
		pflag.BoolVarP(&cm.Flags.NoDaemonize, "no-detach", "D", false, "Don't daemonize and detach from the terminal")
	} else {
		cm.Flags.NoDaemonize = true
	}
	pflag.StringVarP(&cm.Flags.Facility, "facility", "f", "user", "Facility")
	pflag.StringVar(&cm.Flags.Hostname, "hostname", "", "Local hostname to send from")
	pflag.StringVar(&cm.Flags.PidFile, "pid-file", "", "Location of the PID file")
	// --parse-syslog
	pflag.StringVarP(&cm.Flags.Severity, "severity", "s", "notice", "Severity")
	// --strip-color
	pflag.BoolVar(&cm.Flags.UseTCP, "tcp", false, "Connect via TCP (no TLS)")
	pflag.BoolVar(&cm.Flags.UseTLS, "tls", false, "Connect via TCP with TLS")
	pflag.Var(&cm.Flags.RefreshInterval, "new-file-check-interval", "How often to check for new files")
	_ = pflag.Bool("no-eventmachine-tail", false, "No action, provided for backwards compatibility")
	_ = pflag.Bool("eventmachine-tail", false, "No action, provided for backwards compatibility")
	pflag.StringVar(&cm.Flags.DebugLogFile, "debug-log-cfg", "", "the debug log file")
	pflag.StringVar(&cm.Flags.LogLevels, "log", "<root>=INFO", "\"logging configuration <root>=INFO;first=TRACE\"")
	pflag.Parse()
	cm.FlagFiles = pflag.Args()
}

func (cm *ConfigManager) readConfig() error {
	log.Infof("Reading configuration file %s", cm.Flags.ConfigFile)
	err := cm.loadConfigFile()
	if err != nil {
		log.Errorf("%s", err)
		return err
	}
	return nil
}

func (cm *ConfigManager) loadConfigFile() error {
	file, err := ioutil.ReadFile(cm.Flags.ConfigFile)
	// don't error if the default config file isn't found
	if os.IsNotExist(err) && cm.Flags.ConfigFile == DefaultConfigFile {
		return nil
	}
	if err != nil {
		return fmt.Errorf("Could not read the config file: %s", err)
	}

	err = goyaml.Unmarshal(file, &cm.Config)
	if err != nil {
		return fmt.Errorf("Could not parse the config file: %s", err)
	}
	return nil
}

func (cm *ConfigManager) Daemonize() bool {
	return !cm.Flags.NoDaemonize
}

func (cm *ConfigManager) Hostname() string {
	switch {
	case cm.Flags.Hostname != "":
		return cm.Flags.Hostname
	case cm.Config.Hostname != "":
		return cm.Config.Hostname
	default:
		hostname, _ := os.Hostname()
		return hostname
	}
}

func (cm *ConfigManager) RootCAs() *x509.CertPool {
	if cm.DestProtocol() == "tls" && cm.DestHost() == "logs.papertrailapp.com" {
		return papertrail.RootCA()
	} else {
		return nil
	}
}

func (cm *ConfigManager) DestHost() string {
	switch {
	case cm.Flags.DestHost != "":
		return cm.Flags.DestHost
	case cm.Config.Destination.Host == "":
		log.Criticalf("No destination hostname specified")
		os.Exit(1)
	}
	return cm.Config.Destination.Host
}

func (cm ConfigManager) DestPort() int {
	switch {
	case cm.Flags.DestPort != 0:
		return cm.Flags.DestPort
	case cm.Config.Destination.Port != 0:
		return cm.Config.Destination.Port
	default:
		return 514
	}
}

func (cm *ConfigManager) DestProtocol() string {
	switch {
	case cm.Flags.UseTLS:
		return "tls"
	case cm.Flags.UseTCP:
		return "tcp"
	case cm.Config.Destination.Protocol != "":
		return cm.Config.Destination.Protocol
	default:
		return "udp"
	}
}

func (cm *ConfigManager) Severity() syslog.Priority {
	s, err := syslog.Severity(cm.Flags.Severity)
	if err != nil {
		log.Criticalf("%s is not a designated facility", cm.Flags.Severity)
		os.Exit(1)
	}
	return s
}

func (cm *ConfigManager) Facility() syslog.Priority {
	f, err := syslog.Facility(cm.Flags.Facility)
	if err != nil {
		log.Criticalf("%s is not a designated facility", cm.Flags.Facility)
		os.Exit(1)
	}
	return f
}

func (cm *ConfigManager) Files() []string {
	return append(cm.FlagFiles, cm.Config.Files...)
}

func (cm *ConfigManager) DebugLogFile() string {
	switch {
	case cm.Flags.DebugLogFile != "":
		return cm.Flags.DebugLogFile
	default:
		return "/dev/null"
	}
}

func (cm *ConfigManager) defaultPidFile() string {
	pidFiles := []string{
		"/var/run/remote_syslog.pid",
		os.Getenv("HOME") + "/run/remote_syslog.pid",
		os.Getenv("HOME") + "/tmp/remote_syslog.pid",
		os.Getenv("HOME") + "/remote_syslog.pid",
		os.TempDir() + "/remote_syslog.pid",
		os.Getenv("TMPDIR") + "/remote_syslog.pid",
	}
	for _, f := range pidFiles {
		dir := filepath.Dir(f)
		dirStat, err := os.Stat(dir)
		if err != nil || dirStat == nil || !dirStat.IsDir() {
			continue
		}
		fd, err := os.OpenFile(f, os.O_WRONLY|os.O_CREATE, 0644)
		if err != nil {
			continue
		}
		tmpPidFile := fd.Name()
		fd.Close()
		os.Remove(tmpPidFile)
		return f
	}
	return "/tmp/remote_syslog.pid"
}

func (cm *ConfigManager) PidFile() string {
	switch {
	case cm.Flags.PidFile != "":
		return cm.Flags.PidFile
	default:
		return cm.defaultPidFile()
	}
}

func (cm *ConfigManager) LogLevels() string {
	return cm.Flags.LogLevels
}

func (cm *ConfigManager) RefreshInterval() RefreshInterval {
	switch {
	case cm.Config.RefreshInterval != nil && cm.Flags.RefreshInterval.Duration != 0:
		return cm.Flags.RefreshInterval
	case cm.Config.RefreshInterval != nil:
		return *cm.Config.RefreshInterval
	case cm.Flags.RefreshInterval.Duration != 0:
		return cm.Flags.RefreshInterval
	}
	return RefreshInterval{Duration: MinimumRefreshInterval}
}

func (cm *ConfigManager) ExcludeFiles() []*regexp.Regexp {
	return *cm.Config.ExcludeFiles
}

func (cm *ConfigManager) ExcludePatterns() []*regexp.Regexp {
	return *cm.Config.ExcludePatterns
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/urfave/cli"
)

type ThreeG struct {
	IMEI           string `json:"imei"`
	IMSI           string `json:"imsi"`
	APN            string `json:"apn"`
	Dial           string `json:"dial"`
	Username       string `json:"username"`
	Password       string `json:"password"`
	DefaultGateway bool   `json:"defaultGateway"`
}

func (c *ThreeG) Prepare() *ThreeG {
	if c.Username == "" {
		c.Username = "0"
	}
	if c.Password == "" {
		c.Password = "0"
	}
	return c
}

func (c *ThreeG) WriteTo(out io.Writer) error {
	cfgTpl := `
[Dialer Defaults]
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2
Modem Type = USB Modem
; Phone = <Target Phone Number>
Phone = {{.Dial}}
ISDN = 0
; Username = <Your Login Name>, 0 if not specified
Username = {{.Username}}
; Password = <Your Password>, 0 if not specified
Password = {{.Password}}
Init1 = ATZ
; modem command port (by IMSI)
Modem = /dev/{{.IMSI}}.imsi
Baud = 115200
; set APN
Init3 = AT+CGDCONT=1,"IP","{{.APN}}"
Stupid Mode = 1
	`
	tpl, err := template.New("cfg").Parse(cfgTpl)
	if err != nil {
		return err
	}
	return tpl.Execute(out, c)
}

type ThreeGState struct {
	Enabled bool    `json:"enabled"`
	Configg *ThreeG `json:"config"`
}

func ThreegCMD(ctx *cli.Context) error {
	//if ctx.IsSet(enableFlag) {
	//return EnableThreeg(ctx)
	//}
	//if ctx.IsSet(disableFlag) {
	//return DisableThreeg(ctx)
	//}
	//if ctx.IsSet(removeFlag) {
	//return RemoveThreeg(ctx)
	//}
	if ctx.IsSet(configFlag) {
		return configThreegCMD(ctx)
	}
	return nil
}

func configThreegCMD(ctx *cli.Context) error {
	base := ctx.String("dir")
	name := ctx.String("name")
	src := ctx.String("config")
	if src == "" {
		return errors.New("fconf: missing configuration source file")
	}
	var b []byte
	var err error
	if src == "stdin" {
		b, err = ReadFromStdin()
		if err != nil {
			return err
		}
	} else {
		b, err = ioutil.ReadFile(src)
		if err != nil {
			return err
		}
	}
	e := ThreeG{}
	err = json.Unmarshal(b, &e)
	if err != nil {
		return err
	}
	e.Prepare()
	err = checkDir(base)
	if err != nil {
		return err
	}
	if strings.Contains(name, "%s") {
		name = fmt.Sprintf(name, e.IMEI)
	}
	filename := filepath.Join(base, name)
	var buf bytes.Buffer
	err = e.WriteTo(&buf)
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(filename, buf.Bytes(), 0644)
	if err != nil {
		return err
	}
	fmt.Printf("successful written 3G configuration to %s \n", filename)
	state := &ThreeGState{Configg: &e}
	ms, err := threeGState(e.IMEI)
	if err == nil {
		state.Enabled = ms.Enabled
	}
	b, _ = json.Marshal(state)
	return keepState(
		fmt.Sprintf(defaultThreeGGConfig, e.IMEI), b)
}

func threeGState(i string) (*ThreeGState, error) {
	dir := os.Getenv("FCONF_CONFIGDIR")
	if dir == "" {
		dir = fconfConfigDir
	}
	b, err := ioutil.ReadFile(filepath.Join(dir,
		fmt.Sprintf(defaultThreeGGConfig, i)))
	if err != nil {
		return nil, err
	}
	f := &ThreeGState{}
	err = json.Unmarshal(b, f)
	if err != nil {
		return nil, err
	}
	if f.Configg == nil {
		return nil, ErrWrongStateFile
	}
	return f, nil
}
<commit_msg>3g: add enable command<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"

	"github.com/urfave/cli"
)

type ThreeG struct {
	IMEI           string `json:"imei"`
	IMSI           string `json:"imsi"`
	APN            string `json:"apn"`
	Dial           string `json:"dial"`
	Username       string `json:"username"`
	Password       string `json:"password"`
	DefaultGateway bool   `json:"defaultGateway"`
}

func (c *ThreeG) Prepare() *ThreeG {
	if c.Username == "" {
		c.Username = "0"
	}
	if c.Password == "" {
		c.Password = "0"
	}
	return c
}

func (c *ThreeG) WriteTo(out io.Writer) error {
	cfgTpl := `
[Dialer Defaults]
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2
Modem Type = USB Modem
; Phone = <Target Phone Number>
Phone = {{.Dial}}
ISDN = 0
; Username = <Your Login Name>, 0 if not specified
Username = {{.Username}}
; Password = <Your Password>, 0 if not specified
Password = {{.Password}}
Init1 = ATZ
; modem command port (by IMSI)
Modem = /dev/{{.IMSI}}.imsi
Baud = 115200
; set APN
Init3 = AT+CGDCONT=1,"IP","{{.APN}}"
Stupid Mode = 1
	`
	tpl, err := template.New("cfg").Parse(cfgTpl)
	if err != nil {
		return err
	}
	return tpl.Execute(out, c)
}

type ThreeGState struct {
	Enabled bool    `json:"enabled"`
	Configg *ThreeG `json:"config"`
}

func ThreegCMD(ctx *cli.Context) error {
	if ctx.IsSet(enableFlag) {
		return EnableThreeg(ctx)
	}
	//if ctx.IsSet(disableFlag) {
	//return DisableThreeg(ctx)
	//}
	//if ctx.IsSet(removeFlag) {
	//return RemoveThreeg(ctx)
	//}
	if ctx.IsSet(configFlag) {
		return configThreegCMD(ctx)
	}
	return nil
}

func configThreegCMD(ctx *cli.Context) error {
	base := ctx.String("dir")
	name := ctx.String("name")
	src := ctx.String("config")
	if src == "" {
		return errors.New("fconf: missing configuration source file")
	}
	var b []byte
	var err error
	if src == "stdin" {
		b, err = ReadFromStdin()
		if err != nil {
			return err
		}
	} else {
		b, err = ioutil.ReadFile(src)
		if err != nil {
			return err
		}
	}
	e := ThreeG{}
	err = json.Unmarshal(b, &e)
	if err != nil {
		return err
	}
	e.Prepare()
	err = checkDir(base)
	if err != nil {
		return err
	}
	if strings.Contains(name, "%s") {
		name = fmt.Sprintf(name, e.IMEI)
	}
	filename := filepath.Join(base, name)
	var buf bytes.Buffer
	err = e.WriteTo(&buf)
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(filename, buf.Bytes(), 0644)
	if err != nil {
		return err
	}
	fmt.Printf("successful written 3G configuration to %s \n", filename)
	state := &ThreeGState{Configg: &e}
	ms, err := threeGState(e.IMEI)
	if err == nil {
		state.Enabled = ms.Enabled
	}
	b, _ = json.Marshal(state)
	setInterface(ctx, e.IMEI)
	return keepState(
		fmt.Sprintf(defaultThreeGGConfig, e.IMEI), b)
}

func threeGState(i string) (*ThreeGState, error) {
	dir := os.Getenv("FCONF_CONFIGDIR")
	if dir == "" {
		dir = fconfConfigDir
	}
	b, err := ioutil.ReadFile(filepath.Join(dir,
		fmt.Sprintf(defaultThreeGGConfig, i)))
	if err != nil {
		return nil, err
	}
	f := &ThreeGState{}
	err = json.Unmarshal(b, f)
	if err != nil {
		return nil, err
	}
	if f.Configg == nil {
		return nil, ErrWrongStateFile
	}
	return f, nil
}

func EnableThreeg(ctx *cli.Context) error {
	if ctx.IsSet(configFlag) {
		err := configThreegCMD(ctx)
		if err != nil {
			return err
		}
	}
	i := getInterface(ctx)
	if i == "" {
		return errors.New("missing imei , you must specify imei")
	}
	e, err := threeGState(i)
	if err != nil {
		return err
	}
	service := "wvdial"
	err = restartService(service)
	if err != nil {
		return fmt.Errorf("ERROR: restarting systemd %v ", err)
	}
	err = enableService(service)
	if err != nil {
		return fmt.Errorf("ERROR: enabling systemd %v ", err)
	}
	e.Enabled = true
	data, err := json.Marshal(e)
	if err != nil {
		return err
	}
	fmt.Printf("successfully enabled 3g for %s \n", i)
	return keepState(
		fmt.Sprintf(defaultThreeGGConfig, i), data)
}
<|endoftext|>


<commit_before>package ccs

import (
	"encoding/json"
	"math/rand"
	"strconv"
	"time"
)

// Message is an XMPP <message> stanzas used in sending messages to the GCM CCS server.
// https://developer.android.com/google/gcm/ccs.html#format
type Message struct {
	To             string            `json:"to"`
	MessageID      string            `json:"message_id"`
	MessageType    string            `json:"message_type,omitempty"`
	Data           map[string]string `json:"data,omitempty"`
	CollapseKey    string            `json:"collapse_key,omitempty"`
	TimeToLive     int               `json:"time_to_live,omitempty"`
	DelayWhileIdle bool              `json:"delay_while_idle,omitempty"`
	ReturnReceipt  bool              `json:"delivery_receipt_requested,omitempty"`
}

// IncomingMessage is an XMPP <message> stanzas coming from the CCS server.
type IncomingMessage struct {
	From        string            `json:"from"`
	MessageID   string            `json:"message_id"`
	MessageType string            `json:"message_type"`
	Data        map[string]string `json:"data"`
	Error       string            `json:"error"`
}

// NewMessage creates a CCS message.
func NewMessage(id string) *Message {
	r := rand.New(rand.NewSource(time.Now().UnixNano()))

	return &Message{
		To:        id,
		MessageID: "m-" + strconv.Itoa(r.Intn(100000)),
		Data:      make(map[string]string),
	}
}

// SetData is a legacy function not to be used..
func (m *Message) SetData(key string, value string) {
	if m.Data == nil {
		m.Data = make(map[string]string)
	}
	m.Data[key] = value
}

func (m *Message) String() string {
	result, _ := json.Marshal(m)
	return string(result)
}
<commit_msg>fix gcm message structures<commit_after>package ccs

import (
	"encoding/json"
	"math/rand"
	"strconv"
	"time"
)

// Message is an XMPP <message> stanzas used in sending messages to the GCM CCS server.
// https://developer.android.com/google/gcm/ccs.html#format
type Message struct {
	To             string            `json:"to"`
	MessageID      string            `json:"message_id"`
	Data           map[string]string `json:"data,omitempty"`
	MessageType    string            `json:"message_type,omitempty"`
	CollapseKey    string            `json:"collapse_key,omitempty"`
	TimeToLive     int               `json:"time_to_live,omitempty"`               //default:2419200 (in seconds = 4 weeks)
	DelayWhileIdle bool              `json:"delay_while_idle,omitempty"`           //default:false
	ReturnReceipt  bool              `json:"delivery_receipt_requested,omitempty"` //default:false
}

// IncomingMessage is an XMPP <message> stanzas coming from the CCS server.
type IncomingMessage struct {
	From             string            `json:"from"`
	MessageID        string            `json:"message_id"`
	Data             map[string]string `json:"data"`
	MessageType      string            `json:"message_type"`
	ControlType      string            `json:"control_type"`
	Error            string            `json:"error"`
	ErrorDescription string            `json:"error_description"`
}

// NewMessage creates a CCS message.
func NewMessage(id string) *Message {
	r := rand.New(rand.NewSource(time.Now().UnixNano()))

	return &Message{
		To:        id,
		MessageID: "m-" + strconv.Itoa(r.Intn(100000)),
		Data:      make(map[string]string),
	}
}

// SetData adds a key/value pair to the message payload data. Google recommends key/value pairs to be strings and
// keys cannot be reserved words described in GCM server documentation.
func (m *Message) SetData(key string, value string) {
	if m.Data == nil {
		m.Data = make(map[string]string)
	}
	m.Data[key] = value
}

func (m *Message) String() string {
	result, _ := json.Marshal(m)
	return string(result)
}
<|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"
)

//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 doInfoWithValues(b *testing.B, log logr.Logger) {
	log = log.WithValues("k1", "str", "k2", 222, "k3", true, "k4", 1.0)
	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
	}
}

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

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

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

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

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

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

func BenchmarkDiscardLogError(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 noopKV(prefix, args string) {}
func noopJSON(obj string)        {}

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

func BenchmarkFuncrJSONLogInfoOneArg(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doInfoOneArg(b, log)
}

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

func BenchmarkFuncrJSONLogInfoSeveralArgs(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doInfoSeveralArgs(b, log)
}

func BenchmarkFuncrLogInfoWithValues(b *testing.B) {
	var log logr.Logger = funcr.New(noopKV, funcr.Options{})
	doInfoWithValues(b, log)
}

func BenchmarkFuncrJSONLogInfoWithValues(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doInfoWithValues(b, log)
}

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

func BenchmarkFuncrJSONLogV0Info(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doV0Info(b, log)
}

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

func BenchmarkFuncrJSONLogV9Info(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doV9Info(b, log)
}

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

func BenchmarkFuncrJSONLogError(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doError(b, log)
}

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

func BenchmarkFuncrWithName(b *testing.B) {
	var log logr.Logger = funcr.New(noopKV, funcr.Options{})
	doWithName(b, log)
}

func BenchmarkFuncrWithCallDepth(b *testing.B) {
	var log logr.Logger = funcr.New(noopKV, funcr.Options{})
	doWithCallDepth(b, log)
}
<commit_msg>Add stringer, error, marshaler to benchmark<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"
)

//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 doInfoWithValues(b *testing.B, log logr.Logger) {
	log = log.WithValues("k1", "str", "k2", 222, "k3", true, "k4", 1.0)
	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
	}
}

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

type Tstringer struct{ s string }

func (t Tstringer) String() string {
	return t.s
}

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

type Terror struct{ s string }

func (t Terror) Error() string {
	return t.s
}

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

type Tmarshaler struct{ s string }

func (t Tmarshaler) MarshalLog() interface{} {
	return t.s
}

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

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

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

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

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

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

func BenchmarkDiscardLogError(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 noopKV(prefix, args string) {}
func noopJSON(obj string)        {}

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

func BenchmarkFuncrJSONLogInfoOneArg(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doInfoOneArg(b, log)
}

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

func BenchmarkFuncrJSONLogInfoSeveralArgs(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doInfoSeveralArgs(b, log)
}

func BenchmarkFuncrLogInfoWithValues(b *testing.B) {
	var log logr.Logger = funcr.New(noopKV, funcr.Options{})
	doInfoWithValues(b, log)
}

func BenchmarkFuncrJSONLogInfoWithValues(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doInfoWithValues(b, log)
}

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

func BenchmarkFuncrJSONLogV0Info(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doV0Info(b, log)
}

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

func BenchmarkFuncrJSONLogV9Info(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doV9Info(b, log)
}

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

func BenchmarkFuncrJSONLogError(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doError(b, log)
}

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

func BenchmarkFuncrWithName(b *testing.B) {
	var log logr.Logger = funcr.New(noopKV, funcr.Options{})
	doWithName(b, log)
}

func BenchmarkFuncrWithCallDepth(b *testing.B) {
	var log logr.Logger = funcr.New(noopKV, funcr.Options{})
	doWithCallDepth(b, log)
}

func BenchmarkFuncrJSONLogInfoStringerValue(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doStringerValue(b, log)
}

func BenchmarkFuncrJSONLogInfoErrorValue(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doErrorValue(b, log)
}

func BenchmarkFuncrJSONLogInfoMarshalerValue(b *testing.B) {
	var log logr.Logger = funcr.NewJSON(noopJSON, funcr.Options{})
	doMarshalerValue(b, log)
}
<|endoftext|>