<commit_before>package hashmap

import (
	"fmt"
	"math"
	"strconv"
	"sync"
	"sync/atomic"
	"testing"
	"time"

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

func TestNew(t *testing.T) {
	t.Parallel()
	m := New[uintptr, uintptr]()
	assert.Zero(t, m.Len())
}

func TestSetString(t *testing.T) {
	t.Parallel()
	m := New[int, string]()
	elephant := "elephant"
	monkey := "monkey"

	m.Set(1, elephant) // insert
	value, ok := m.Get(1)
	require.True(t, ok)
	assert.Equal(t, elephant, value)

	m.Set(1, monkey) // overwrite
	value, ok = m.Get(1)
	require.True(t, ok)
	assert.Equal(t, monkey, value)

	assert.Equal(t, 1, m.Len())

	m.Set(2, elephant) // insert
	assert.Equal(t, 2, m.Len())
	value, ok = m.Get(2)
	require.True(t, ok)
	assert.Equal(t, elephant, value)
}

func TestSetUint8(t *testing.T) {
	t.Parallel()
	m := New[uint8, int]()

	m.Set(1, 128) // insert
	value, ok := m.Get(1)
	require.True(t, ok)
	assert.Equal(t, 128, value)

	m.Set(2, 200) // insert
	assert.Equal(t, 2, m.Len())
	value, ok = m.Get(2)
	require.True(t, ok)
	assert.Equal(t, 200, value)
}

func TestSetUint16(t *testing.T) {
	t.Parallel()
	m := New[uint16, int]()

	m.Set(1, 128) // insert
	value, ok := m.Get(1)
	require.True(t, ok)
	assert.Equal(t, 128, value)

	m.Set(2, 200) // insert
	assert.Equal(t, 2, m.Len())
	value, ok = m.Get(2)
	require.True(t, ok)
	assert.Equal(t, 200, value)
}

func TestSetFloat32(t *testing.T) {
	t.Parallel()
	m := New[float32, int]()

	m.Set(1.1, 128) // insert
	value, ok := m.Get(1.1)
	require.True(t, ok)
	assert.Equal(t, 128, value)

	m.Set(2.2, 200) // insert
	assert.Equal(t, 2, m.Len())
	value, ok = m.Get(2.2)
	require.True(t, ok)
	assert.Equal(t, 200, value)
}

func TestSetInt64(t *testing.T) {
	t.Parallel()
	m := New[int64, int]()

	m.Set(1, 128) // insert
	value, ok := m.Get(1)
	require.True(t, ok)
	assert.Equal(t, 128, value)

	m.Set(2, 200) // insert
	assert.Equal(t, 2, m.Len())
	value, ok = m.Get(2)
	require.True(t, ok)
	assert.Equal(t, 200, value)
}

func TestSetComplex128(t *testing.T) {
	t.Parallel()
	m := New[complex128, int]()

	comp1 := complex(float64(5), float64(10))
	m.Set(comp1, 128) // insert
	value, ok := m.Get(comp1)
	require.True(t, ok)
	assert.Equal(t, 128, value)

	comp2 := complex(float64(5), float64(20))
	m.Set(comp2, 200) // insert
	assert.Equal(t, 2, m.Len())
	value, ok = m.Get(comp2)
	require.True(t, ok)
	assert.Equal(t, 200, value)
}

func TestInsert(t *testing.T) {
	t.Parallel()
	m := New[int, string]()
	elephant := "elephant"
	monkey := "monkey"

	inserted := m.Insert(1, elephant)
	require.True(t, inserted)
	value, ok := m.Get(1)
	require.True(t, ok)
	assert.Equal(t, elephant, value)

	inserted = m.Insert(1, monkey)
	require.False(t, inserted)
	value, ok = m.Get(1)
	require.True(t, ok)
	assert.Equal(t, elephant, value)

	assert.Equal(t, 1, m.Len())

	inserted = m.Insert(2, monkey)
	require.True(t, inserted)
	assert.Equal(t, 2, m.Len())
	value, ok = m.Get(2)
	require.True(t, ok)
	assert.Equal(t, monkey, value)
}

func TestGetNonExistingItem(t *testing.T) {
	t.Parallel()
	m := New[int, string]()
	value, ok := m.Get(1)
	require.False(t, ok)
	assert.Equal(t, "", value)
}

func TestGrow(t *testing.T) {
	t.Parallel()
	m := New[int, string]()
	m.Grow(uintptr(63))

	for { // make sure to wait for resize operation to finish
		if m.resizing.Load() == 0 {
			break
		}
		time.Sleep(time.Microsecond * 50)
	}

	d := m.store.Load()
	log := int(math.Log2(64))
	expectedSize := uintptr(strconv.IntSize - log)
	assert.EqualValues(t, expectedSize, d.keyShifts)
}

func TestResize(t *testing.T) {
	t.Parallel()
	m := NewSized[uintptr, string](2)
	itemCount := uintptr(50)

	for i := uintptr(0); i < itemCount; i++ {
		m.Set(i, strconv.Itoa(int(i)))
	}

	assert.EqualValues(t, itemCount, m.Len())

	for { // make sure to wait for resize operation to finish
		if m.resizing.Load() == 0 {
			break
		}
		time.Sleep(time.Microsecond * 50)
	}

	assert.True(t, m.FillRate() > 30)

	for i := uintptr(0); i < itemCount; i++ {
		value, ok := m.Get(i)
		require.True(t, ok)
		expected := strconv.Itoa(int(i))
		assert.Equal(t, expected, value)
	}
}

func TestStringer(t *testing.T) {
	t.Parallel()
	m := New[int, string]()
	elephant := "elephant"
	monkey := "monkey"

	assert.Equal(t, "[]", m.String())

	m.Set(1, elephant)
	hashedKey0 := m.hasher(1)
	expected := fmt.Sprintf("[%v]", hashedKey0)
	assert.Equal(t, expected, m.String())

	m.Set(2, monkey)
	hashedKey1 := m.hasher(2)
	if hashedKey0 < hashedKey1 {
		expected = fmt.Sprintf("[%v,%v]", hashedKey0, hashedKey1)
	} else {
		expected = fmt.Sprintf("[%v,%v]", hashedKey1, hashedKey0)
	}
	assert.Equal(t, expected, m.String())
}

func TestDelete(t *testing.T) {
	t.Parallel()
	m := New[int, string]()
	elephant := "elephant"
	monkey := "monkey"

	deleted := m.Del(1)
	assert.False(t, deleted)

	m.Set(1, elephant)
	m.Set(2, monkey)

	deleted = m.Del(0)
	assert.False(t, deleted)
	deleted = m.Del(3)
	assert.False(t, deleted)
	assert.Equal(t, 2, m.Len())

	deleted = m.Del(1)
	assert.True(t, deleted)
	deleted = m.Del(1)
	assert.False(t, deleted)
	deleted = m.Del(2)
	assert.True(t, deleted)
	assert.Equal(t, 0, m.Len())
}

func TestRange(t *testing.T) {
	t.Parallel()
	m := New[int, string]()

	items := map[int]string{}
	m.Range(func(key int, value string) bool {
		items[key] = value
		return true
	})
	assert.Equal(t, 0, len(items))

	itemCount := 16
	for i := itemCount; i > 0; i-- {
		m.Set(i, strconv.Itoa(i))
	}

	items = map[int]string{}
	m.Range(func(key int, value string) bool {
		items[key] = value
		return true
	})

	assert.Len(t, items, itemCount)
	for i := 1; i <= itemCount; i++ {
		value, ok := items[i]
		require.True(t, ok)
		expected := strconv.Itoa(i)
		assert.Equal(t, expected, value)
	}

	items = map[int]string{} // test aborting range
	m.Range(func(key int, value string) bool {
		items[key] = value
		return false
	})
	assert.Len(t, items, 1)
}

// nolint: funlen, gocognit
func TestHashMap_parallel(t *testing.T) {
	m := New[int, int]()

	max := 10
	dur := 2 * time.Second

	do := func(t *testing.T, max int, d time.Duration, fn func(*testing.T, int)) <-chan error {
		t.Helper()
		done := make(chan error)
		var times int64
		// This goroutines will terminate test in case if closure hangs.
		go func() {
			for {
				select {
				case <-time.After(d + 500*time.Millisecond):
					if atomic.LoadInt64(&times) == 0 {
						done <- fmt.Errorf("closure was not executed even once, something blocks it")
					}
					close(done)
				case <-done:
				}
			}
		}()
		go func() {
			timer := time.NewTimer(d)
			defer timer.Stop()
		InfLoop:
			for {
				for i := 0; i < max; i++ {
					select {
					case <-timer.C:
						break InfLoop
					default:
					}
					fn(t, i)
					atomic.AddInt64(&times, 1)
				}
			}
			close(done)
		}()
		return done
	}

	wait := func(t *testing.T, done <-chan error) {
		t.Helper()
		if err := <-done; err != nil {
			t.Error(err)
		}
	}

	// Initial fill.
	for i := 0; i < max; i++ {
		m.Set(i, i)
	}
	t.Run("set_get", func(t *testing.T) {
		doneSet := do(t, max, dur, func(t *testing.T, i int) {
			t.Helper()
			m.Set(i, i)
		})
		doneGet := do(t, max, dur, func(t *testing.T, i int) {
			t.Helper()
			if _, ok := m.Get(i); !ok {
				t.Errorf("missing value for key: %d", i)
			}
		})
		wait(t, doneSet)
		wait(t, doneGet)
	})
	t.Run("get-or-insert-and-delete", func(t *testing.T) {
		doneGetOrInsert := do(t, max, dur, func(t *testing.T, i int) {
			t.Helper()
			m.GetOrInsert(i, i)
		})
		doneDel := do(t, max, dur, func(t *testing.T, i int) {
			t.Helper()
			m.Del(i)
		})
		wait(t, doneGetOrInsert)
		wait(t, doneDel)
	})
}

func TestHashMap_SetConcurrent(t *testing.T) {
	t.Parallel()
	m := New[string, int]()

	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)

		go func(i int) {
			defer wg.Done()

			m.Set(strconv.Itoa(i), i)

			wg.Add(1)
			go func(i int) {
				defer wg.Done()

				m.Get(strconv.Itoa(i))
			}(i)
		}(i)
	}

	wg.Wait()
}
<commit_msg>add test for a bug<commit_after>package hashmap

import (
	"fmt"
	"math"
	"math/rand"
	"strconv"
	"sync"
	"sync/atomic"
	"testing"
	"time"

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

func TestNew(t *testing.T) {
	t.Parallel()
	m := New[uintptr, uintptr]()
	assert.Zero(t, m.Len())
}

func TestSetString(t *testing.T) {
	t.Parallel()
	m := New[int, string]()
	elephant := "elephant"
	monkey := "monkey"

	m.Set(1, elephant) // insert
	value, ok := m.Get(1)
	require.True(t, ok)
	assert.Equal(t, elephant, value)

	m.Set(1, monkey) // overwrite
	value, ok = m.Get(1)
	require.True(t, ok)
	assert.Equal(t, monkey, value)

	assert.Equal(t, 1, m.Len())

	m.Set(2, elephant) // insert
	assert.Equal(t, 2, m.Len())
	value, ok = m.Get(2)
	require.True(t, ok)
	assert.Equal(t, elephant, value)
}

func TestSetUint8(t *testing.T) {
	t.Parallel()
	m := New[uint8, int]()

	m.Set(1, 128) // insert
	value, ok := m.Get(1)
	require.True(t, ok)
	assert.Equal(t, 128, value)

	m.Set(2, 200) // insert
	assert.Equal(t, 2, m.Len())
	value, ok = m.Get(2)
	require.True(t, ok)
	assert.Equal(t, 200, value)
}

func TestSetUint16(t *testing.T) {
	t.Parallel()
	m := New[uint16, int]()

	m.Set(1, 128) // insert
	value, ok := m.Get(1)
	require.True(t, ok)
	assert.Equal(t, 128, value)

	m.Set(2, 200) // insert
	assert.Equal(t, 2, m.Len())
	value, ok = m.Get(2)
	require.True(t, ok)
	assert.Equal(t, 200, value)
}

func TestSetFloat32(t *testing.T) {
	t.Parallel()
	m := New[float32, int]()

	m.Set(1.1, 128) // insert
	value, ok := m.Get(1.1)
	require.True(t, ok)
	assert.Equal(t, 128, value)

	m.Set(2.2, 200) // insert
	assert.Equal(t, 2, m.Len())
	value, ok = m.Get(2.2)
	require.True(t, ok)
	assert.Equal(t, 200, value)
}

func TestSetInt64(t *testing.T) {
	t.Parallel()
	m := New[int64, int]()

	m.Set(1, 128) // insert
	value, ok := m.Get(1)
	require.True(t, ok)
	assert.Equal(t, 128, value)

	m.Set(2, 200) // insert
	assert.Equal(t, 2, m.Len())
	value, ok = m.Get(2)
	require.True(t, ok)
	assert.Equal(t, 200, value)
}

func TestSetComplex128(t *testing.T) {
	t.Parallel()
	m := New[complex128, int]()

	comp1 := complex(float64(5), float64(10))
	m.Set(comp1, 128) // insert
	value, ok := m.Get(comp1)
	require.True(t, ok)
	assert.Equal(t, 128, value)

	comp2 := complex(float64(5), float64(20))
	m.Set(comp2, 200) // insert
	assert.Equal(t, 2, m.Len())
	value, ok = m.Get(comp2)
	require.True(t, ok)
	assert.Equal(t, 200, value)
}

func TestInsert(t *testing.T) {
	t.Parallel()
	m := New[int, string]()
	elephant := "elephant"
	monkey := "monkey"

	inserted := m.Insert(1, elephant)
	require.True(t, inserted)
	value, ok := m.Get(1)
	require.True(t, ok)
	assert.Equal(t, elephant, value)

	inserted = m.Insert(1, monkey)
	require.False(t, inserted)
	value, ok = m.Get(1)
	require.True(t, ok)
	assert.Equal(t, elephant, value)

	assert.Equal(t, 1, m.Len())

	inserted = m.Insert(2, monkey)
	require.True(t, inserted)
	assert.Equal(t, 2, m.Len())
	value, ok = m.Get(2)
	require.True(t, ok)
	assert.Equal(t, monkey, value)
}

func TestGetNonExistingItem(t *testing.T) {
	t.Parallel()
	m := New[int, string]()
	value, ok := m.Get(1)
	require.False(t, ok)
	assert.Equal(t, "", value)
}

func TestGrow(t *testing.T) {
	t.Parallel()
	m := New[int, string]()
	m.Grow(uintptr(63))

	for { // make sure to wait for resize operation to finish
		if m.resizing.Load() == 0 {
			break
		}
		time.Sleep(time.Microsecond * 50)
	}

	d := m.store.Load()
	log := int(math.Log2(64))
	expectedSize := uintptr(strconv.IntSize - log)
	assert.EqualValues(t, expectedSize, d.keyShifts)
}

func TestResize(t *testing.T) {
	t.Parallel()
	m := NewSized[uintptr, string](2)
	itemCount := uintptr(50)

	for i := uintptr(0); i < itemCount; i++ {
		m.Set(i, strconv.Itoa(int(i)))
	}

	assert.EqualValues(t, itemCount, m.Len())

	for { // make sure to wait for resize operation to finish
		if m.resizing.Load() == 0 {
			break
		}
		time.Sleep(time.Microsecond * 50)
	}

	assert.True(t, m.FillRate() > 30)

	for i := uintptr(0); i < itemCount; i++ {
		value, ok := m.Get(i)
		require.True(t, ok)
		expected := strconv.Itoa(int(i))
		assert.Equal(t, expected, value)
	}
}

func TestStringer(t *testing.T) {
	t.Parallel()
	m := New[int, string]()
	elephant := "elephant"
	monkey := "monkey"

	assert.Equal(t, "[]", m.String())

	m.Set(1, elephant)
	hashedKey0 := m.hasher(1)
	expected := fmt.Sprintf("[%v]", hashedKey0)
	assert.Equal(t, expected, m.String())

	m.Set(2, monkey)
	hashedKey1 := m.hasher(2)
	if hashedKey0 < hashedKey1 {
		expected = fmt.Sprintf("[%v,%v]", hashedKey0, hashedKey1)
	} else {
		expected = fmt.Sprintf("[%v,%v]", hashedKey1, hashedKey0)
	}
	assert.Equal(t, expected, m.String())
}

func TestDelete(t *testing.T) {
	t.Parallel()
	m := New[int, string]()
	elephant := "elephant"
	monkey := "monkey"

	deleted := m.Del(1)
	assert.False(t, deleted)

	m.Set(1, elephant)
	m.Set(2, monkey)

	deleted = m.Del(0)
	assert.False(t, deleted)
	deleted = m.Del(3)
	assert.False(t, deleted)
	assert.Equal(t, 2, m.Len())

	deleted = m.Del(1)
	assert.True(t, deleted)
	deleted = m.Del(1)
	assert.False(t, deleted)
	deleted = m.Del(2)
	assert.True(t, deleted)
	assert.Equal(t, 0, m.Len())
}

func TestRange(t *testing.T) {
	t.Parallel()
	m := New[int, string]()

	items := map[int]string{}
	m.Range(func(key int, value string) bool {
		items[key] = value
		return true
	})
	assert.Equal(t, 0, len(items))

	itemCount := 16
	for i := itemCount; i > 0; i-- {
		m.Set(i, strconv.Itoa(i))
	}

	items = map[int]string{}
	m.Range(func(key int, value string) bool {
		items[key] = value
		return true
	})

	assert.Len(t, items, itemCount)
	for i := 1; i <= itemCount; i++ {
		value, ok := items[i]
		require.True(t, ok)
		expected := strconv.Itoa(i)
		assert.Equal(t, expected, value)
	}

	items = map[int]string{} // test aborting range
	m.Range(func(key int, value string) bool {
		items[key] = value
		return false
	})
	assert.Len(t, items, 1)
}

// nolint: funlen, gocognit
func TestHashMap_parallel(t *testing.T) {
	m := New[int, int]()

	max := 10
	dur := 2 * time.Second

	do := func(t *testing.T, max int, d time.Duration, fn func(*testing.T, int)) <-chan error {
		t.Helper()
		done := make(chan error)
		var times int64
		// This goroutines will terminate test in case if closure hangs.
		go func() {
			for {
				select {
				case <-time.After(d + 500*time.Millisecond):
					if atomic.LoadInt64(&times) == 0 {
						done <- fmt.Errorf("closure was not executed even once, something blocks it")
					}
					close(done)
				case <-done:
				}
			}
		}()
		go func() {
			timer := time.NewTimer(d)
			defer timer.Stop()
		InfLoop:
			for {
				for i := 0; i < max; i++ {
					select {
					case <-timer.C:
						break InfLoop
					default:
					}
					fn(t, i)
					atomic.AddInt64(&times, 1)
				}
			}
			close(done)
		}()
		return done
	}

	wait := func(t *testing.T, done <-chan error) {
		t.Helper()
		if err := <-done; err != nil {
			t.Error(err)
		}
	}

	// Initial fill.
	for i := 0; i < max; i++ {
		m.Set(i, i)
	}
	t.Run("set_get", func(t *testing.T) {
		doneSet := do(t, max, dur, func(t *testing.T, i int) {
			t.Helper()
			m.Set(i, i)
		})
		doneGet := do(t, max, dur, func(t *testing.T, i int) {
			t.Helper()
			if _, ok := m.Get(i); !ok {
				t.Errorf("missing value for key: %d", i)
			}
		})
		wait(t, doneSet)
		wait(t, doneGet)
	})
	t.Run("get-or-insert-and-delete", func(t *testing.T) {
		doneGetOrInsert := do(t, max, dur, func(t *testing.T, i int) {
			t.Helper()
			m.GetOrInsert(i, i)
		})
		doneDel := do(t, max, dur, func(t *testing.T, i int) {
			t.Helper()
			m.Del(i)
		})
		wait(t, doneGetOrInsert)
		wait(t, doneDel)
	})
}

func TestHashMap_SetConcurrent(t *testing.T) {
	t.Parallel()
	m := New[string, int]()

	var wg sync.WaitGroup
	for i := 0; i < 100; i++ {
		wg.Add(1)

		go func(i int) {
			defer wg.Done()

			m.Set(strconv.Itoa(i), i)

			wg.Add(1)
			go func(i int) {
				defer wg.Done()

				m.Get(strconv.Itoa(i))
			}(i)
		}(i)
	}

	wg.Wait()
}

func TestConcurrentInsertDelete(t *testing.T) {
	for i := 0; i < 200; i++ {
		el1 := &ListElement[int, int]{
			key:     111,
			keyHash: 111,
		}
		el2 := &ListElement[int, int]{
			key:     222,
			keyHash: 222,
		}
		el3 := &ListElement[int, int]{
			key:     333,
			keyHash: 333,
		}
		newIl := &ListElement[int, int]{
			key:     223,
			keyHash: 223,
		}
		l := NewList[int, int]()
		l.Add(el1, nil)
		l.Add(el2, nil)
		l.Add(el3, nil)
		wg := sync.WaitGroup{}
		wg.Add(2)

		go func() {
			rand.Seed(int64(time.Now().Nanosecond()))
			time.Sleep(time.Duration(rand.Intn(10)))
			l.Delete(el2)
			wg.Done()
		}()
		go func() {
			defer wg.Done()
			rand.Seed(int64(time.Now().Nanosecond()))
			time.Sleep(time.Duration(rand.Intn(10)))
			for {
				if _, inserted := l.Add(newIl, nil); inserted {
					return
				}
			}
		}()
		wg.Wait()

		if le := l.Len(); le != 3 {
			t.Error("l.Len() != 3", le)
			return
		}
		if _, found, _ := l.search(nil, newIl); found == nil {
			t.Error("newIl not found")
			return
		}
	}
}
<|endoftext|>


<commit_before>package ast

import "fmt"

// Walk traverses an AST in depth-first order: It starts by calling fn(node);
// node must not be nil.  If f returns true, Walk invokes f recursively for
// each of the non-nil children of node, followed by a call of f(nil).
func Walk(node Node, fn func(Node) bool) {
	if !fn(node) {
		return
	}

	switch n := node.(type) {
	case *File:
		Walk(n.Node, fn)
	case *ObjectList:
		for _, item := range n.Items {
			Walk(item, fn)
		}
	case *ObjectKey:
		// nothing to do
	case *ObjectItem:
		for _, k := range n.Keys {
			Walk(k, fn)
		}
		Walk(n.Val, fn)
	case *LiteralType:
		// nothing to do
	case *ListType:
		for _, l := range n.List {
			Walk(l, fn)
		}
	case *ObjectType:
		for _, l := range n.List.Items {
			Walk(l, fn)
		}
	default:
		fmt.Printf(" unknown type: %T\n", n)
	}

	fn(nil)
}
<commit_msg>hcl/ast: walk the objectlist within an objecttype<commit_after>package ast

import "fmt"

// Walk traverses an AST in depth-first order: It starts by calling fn(node);
// node must not be nil.  If f returns true, Walk invokes f recursively for
// each of the non-nil children of node, followed by a call of f(nil).
func Walk(node Node, fn func(Node) bool) {
	if !fn(node) {
		return
	}

	switch n := node.(type) {
	case *File:
		Walk(n.Node, fn)
	case *ObjectList:
		for _, item := range n.Items {
			Walk(item, fn)
		}
	case *ObjectKey:
		// nothing to do
	case *ObjectItem:
		for _, k := range n.Keys {
			Walk(k, fn)
		}
		Walk(n.Val, fn)
	case *LiteralType:
		// nothing to do
	case *ListType:
		for _, l := range n.List {
			Walk(l, fn)
		}
	case *ObjectType:
		Walk(n.List, fn)
	default:
		fmt.Printf(" unknown type: %T\n", n)
	}

	fn(nil)
}
<|endoftext|>


<commit_before>// Copyright 2016 The Serviced 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 health

import (
	"encoding/json"
	"os/exec"
	"time"
)

// DefaultTolerance is the default coefficient used to determine when a health
// check is expired
const DefaultTolerance int = 2

// DefaultTimeout is the default timeout setting used to determine when a
// health check is non-responsive
const DefaultTimeout time.Duration = 30 * time.Second

// DefaultExpiration is the default expiration for deprecated health status
// updates.
const DefaultExpiration time.Duration = time.Minute

const (
	// OK means health check is passing
	OK = "passed"
	// Failed means health check is responsive, but failing
	Failed = "failed"
	// Timeout means health check is non-responsive in the given time
	Timeout = "timeout"
	// NotRunning means the instance is not running
	NotRunning = "not running"
	// Unknown means the instance hasn't checked in within the provided time
	// limit.
	Unknown = "unknown"
)

// HealthStatus is the output from a provided health check.
type HealthStatus struct {
	Status    string
	StartedAt time.Time
	Duration  time.Duration
}

// HealthCheck is the health check object.
type HealthCheck struct {
	Script    string
	Timeout   time.Duration
	Interval  time.Duration
	Tolerance int
}

// MarshalJSON implements json.Marshaller
func (hc HealthCheck) MarshalJSON() ([]byte, error) {
	jhc := struct {
		Script    string
		Timeout   float64
		Interval  float64
		Tolerance int
	}{
		Script:    hc.Script,
		Timeout:   hc.Timeout.Seconds(),
		Interval:  hc.Interval.Seconds(),
		Tolerance: hc.Tolerance,
	}
	return json.Marshal(jhc)
}

// UnmarshalJSON implements json.Unmarshaller
func (hc *HealthCheck) UnmarshalJSON(data []byte) error {
	jhc := struct {
		Script    string
		Timeout   float64
		Interval  float64
		Tolerance int
	}{}
	if err := json.Unmarshal(data, &jhc); err != nil {
		return err
	}
	*hc = HealthCheck{
		Script:    jhc.Script,
		Timeout:   time.Duration(jhc.Timeout) * time.Second,
		Interval:  time.Duration(jhc.Interval) * time.Second,
		Tolerance: jhc.Tolerance,
	}
	return nil
}

// GetTimeout returns the timeout duration.
func (hc *HealthCheck) GetTimeout() time.Duration {
	timeout := hc.Timeout
	if timeout <= 0 {
		timeout = DefaultTimeout
	}
	return timeout
}

// Expires calculates the time to live on the cache item.
func (hc *HealthCheck) Expires() time.Duration {
	tolerance := hc.Tolerance
	if tolerance <= 0 {
		tolerance = DefaultTolerance
	}
	return time.Duration(tolerance) * (hc.GetTimeout() + hc.Interval)
}

// NotRunning returns the health status for a service instance that is not
// running.
func (hc *HealthCheck) NotRunning() HealthStatus {
	return HealthStatus{
		Status:    NotRunning,
		StartedAt: time.Now(),
	}
}

// Unknown returns the health status for a service instance whose health check
// response is unknown.
func (hc *HealthCheck) Unknown() HealthStatus {
	return HealthStatus{
		Status:    Unknown,
		StartedAt: time.Now(),
	}
}

// Run returns the health status as a result of running the health check
// script.
func (hc *HealthCheck) Run() (stat HealthStatus) {
	stat.StartedAt = time.Now()
	cmd := exec.Command("sh", "-c", hc.Script)
	cmd.Start()
	timer := time.NewTimer(hc.GetTimeout())
	errC := make(chan error)
	go func() { errC <- cmd.Wait() }()
	select {
	case err := <-errC:
		timer.Stop()
		if err != nil {
			stat.Status = Failed
		} else {
			stat.Status = OK
		}
	case <-timer.C:
		cmd.Process.Kill()
		<-errC
		stat.Status = Timeout
	}
	stat.Duration = time.Since(stat.StartedAt)
	return
}

// Ping performs the health check on the specified interval.
func (hc *HealthCheck) Ping(cancel <-chan struct{}, report func(HealthStatus)) {
	timer := time.NewTimer(0)
	defer timer.Stop()
	for {
		select {
		case <-timer.C:
			stat := hc.Run()
			timer.Reset(hc.Interval)
			report(stat)
		case <-cancel:
			return
		}
	}
}
<commit_msg>add underscore to not_running const<commit_after>// Copyright 2016 The Serviced 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 health

import (
	"encoding/json"
	"os/exec"
	"time"
)

// DefaultTolerance is the default coefficient used to determine when a health
// check is expired
const DefaultTolerance int = 2

// DefaultTimeout is the default timeout setting used to determine when a
// health check is non-responsive
const DefaultTimeout time.Duration = 30 * time.Second

// DefaultExpiration is the default expiration for deprecated health status
// updates.
const DefaultExpiration time.Duration = time.Minute

const (
	// OK means health check is passing
	OK = "passed"
	// Failed means health check is responsive, but failing
	Failed = "failed"
	// Timeout means health check is non-responsive in the given time
	Timeout = "timeout"
	// NotRunning means the instance is not running
	NotRunning = "not_running"
	// Unknown means the instance hasn't checked in within the provided time
	// limit.
	Unknown = "unknown"
)

// HealthStatus is the output from a provided health check.
type HealthStatus struct {
	Status    string
	StartedAt time.Time
	Duration  time.Duration
}

// HealthCheck is the health check object.
type HealthCheck struct {
	Script    string
	Timeout   time.Duration
	Interval  time.Duration
	Tolerance int
}

// MarshalJSON implements json.Marshaller
func (hc HealthCheck) MarshalJSON() ([]byte, error) {
	jhc := struct {
		Script    string
		Timeout   float64
		Interval  float64
		Tolerance int
	}{
		Script:    hc.Script,
		Timeout:   hc.Timeout.Seconds(),
		Interval:  hc.Interval.Seconds(),
		Tolerance: hc.Tolerance,
	}
	return json.Marshal(jhc)
}

// UnmarshalJSON implements json.Unmarshaller
func (hc *HealthCheck) UnmarshalJSON(data []byte) error {
	jhc := struct {
		Script    string
		Timeout   float64
		Interval  float64
		Tolerance int
	}{}
	if err := json.Unmarshal(data, &jhc); err != nil {
		return err
	}
	*hc = HealthCheck{
		Script:    jhc.Script,
		Timeout:   time.Duration(jhc.Timeout) * time.Second,
		Interval:  time.Duration(jhc.Interval) * time.Second,
		Tolerance: jhc.Tolerance,
	}
	return nil
}

// GetTimeout returns the timeout duration.
func (hc *HealthCheck) GetTimeout() time.Duration {
	timeout := hc.Timeout
	if timeout <= 0 {
		timeout = DefaultTimeout
	}
	return timeout
}

// Expires calculates the time to live on the cache item.
func (hc *HealthCheck) Expires() time.Duration {
	tolerance := hc.Tolerance
	if tolerance <= 0 {
		tolerance = DefaultTolerance
	}
	return time.Duration(tolerance) * (hc.GetTimeout() + hc.Interval)
}

// NotRunning returns the health status for a service instance that is not
// running.
func (hc *HealthCheck) NotRunning() HealthStatus {
	return HealthStatus{
		Status:    NotRunning,
		StartedAt: time.Now(),
	}
}

// Unknown returns the health status for a service instance whose health check
// response is unknown.
func (hc *HealthCheck) Unknown() HealthStatus {
	return HealthStatus{
		Status:    Unknown,
		StartedAt: time.Now(),
	}
}

// Run returns the health status as a result of running the health check
// script.
func (hc *HealthCheck) Run() (stat HealthStatus) {
	stat.StartedAt = time.Now()
	cmd := exec.Command("sh", "-c", hc.Script)
	cmd.Start()
	timer := time.NewTimer(hc.GetTimeout())
	errC := make(chan error)
	go func() { errC <- cmd.Wait() }()
	select {
	case err := <-errC:
		timer.Stop()
		if err != nil {
			stat.Status = Failed
		} else {
			stat.Status = OK
		}
	case <-timer.C:
		cmd.Process.Kill()
		<-errC
		stat.Status = Timeout
	}
	stat.Duration = time.Since(stat.StartedAt)
	return
}

// Ping performs the health check on the specified interval.
func (hc *HealthCheck) Ping(cancel <-chan struct{}, report func(HealthStatus)) {
	timer := time.NewTimer(0)
	defer timer.Stop()
	for {
		select {
		case <-timer.C:
			stat := hc.Run()
			timer.Reset(hc.Interval)
			report(stat)
		case <-cancel:
			return
		}
	}
}
<|endoftext|>


<commit_before>package raws

import (
	"reflect"
	"testing"
)

func checkErrors(t *testing.T, name string, index int, err error, expected error) {
	if err != nil && !reflect.DeepEqual(err, expected) {
		t.Errorf("%s [%d] - errors: received=%+v | expected=%+v",
			name, index, err.Error(), expected.Error())
	}
}
<commit_msg>helper_test: Mark the helper func<commit_after>package raws

import (
	"reflect"
	"testing"
)

func checkErrors(t *testing.T, name string, index int, err error, expected error) {
	t.Helper()

	if err != nil && !reflect.DeepEqual(err, expected) {
		t.Errorf("%s [%d] - errors: received=%+v | expected=%+v",
			name, index, err.Error(), expected.Error())
	}
}
<|endoftext|>


<commit_before>package node

import (
	"fmt"
	"github.com/AutoRoute/l2"
	"testing"
	"time"
)

type testInterface struct {
	in  chan l2.EthFrame
	out chan l2.EthFrame
}

func (t testInterface) ReadFrame() (l2.EthFrame, error) {
	return <-t.in, nil // TODO: return error
}

func (t testInterface) WriteFrame(e l2.EthFrame) error {
	t.out <- e
	return nil // TODO: return error
}

func CreatePairedInterface() (l2.FrameReadWriter, l2.FrameReadWriter) {
	one := make(chan l2.EthFrame)
	two := make(chan l2.EthFrame)
	return testInterface{one, two}, testInterface{two, one}
}

func PrintFromChannel(cs <-chan string) {
	var msg string = <-cs
	fmt.Println(msg)
}

func TestBasicExchange(t *testing.T) {
	var test_mac1 string = "aa:bb:cc:dd:ee:00"
	var test_mac2 string = "aa:bb:cc:dd:ee:11"

	var public_key1 PublicKey = pktest("test1")
	var public_key2 PublicKey = pktest("test2")

	one, two := CreatePairedInterface()

	nf1 := NewNeighborData(public_key1)
	nf2 := NewNeighborData(public_key2)

	var outone <-chan string
	var outtwo <-chan string
	var err1 error
	var err2 error
	go func() {
		outone, err1 = nf1.Find(test_mac1, one)
		if err1 != nil {
			panic(err1)
		}
	}()
	go func() {
		outtwo, err2 = nf2.Find(test_mac2, two)
		if err2 != nil {
			panic(err2)
		}
	}()
	for i := 0; i < 100; i++ {
		go PrintFromChannel(outone)
		go PrintFromChannel(outtwo)
		time.Sleep(1 * 1e9)
	}
}
<commit_msg>Made channels buffered. Testing for nodes coming online works.<commit_after>package node

import (
	"fmt"
	"github.com/AutoRoute/l2"
	"testing"
	"time"
)

type testInterface struct {
	in  chan l2.EthFrame
	out chan l2.EthFrame
}

func (t testInterface) ReadFrame() (l2.EthFrame, error) {
	return <-t.in, nil // TODO: return error
}

func (t testInterface) WriteFrame(e l2.EthFrame) error {
	t.out <- e
	return nil // TODO: return error
}

func CreatePairedInterface() (l2.FrameReadWriter, l2.FrameReadWriter) {
	one := make(chan l2.EthFrame, 100)
	two := make(chan l2.EthFrame, 100)
	return testInterface{one, two}, testInterface{two, one}
}

func PrintFromChannel(cs <-chan string) {
	var msg string = <-cs
	fmt.Println(msg)
}

func TestBasicExchange(t *testing.T) {
	var test_mac1 string = "aa:bb:cc:dd:ee:00"
	var test_mac2 string = "aa:bb:cc:dd:ee:11"

	var public_key1 PublicKey = pktest("test1")
	var public_key2 PublicKey = pktest("test2")

	one, two := CreatePairedInterface()

	nf1 := NewNeighborData(public_key1)
	nf2 := NewNeighborData(public_key2)

	var outone <-chan string
	var outtwo <-chan string
	var err1 error
	var err2 error
	go func() {
		outone, err1 = nf1.Find(test_mac1, one)
		if err1 != nil {
			panic(err1)
		}
	}()
	go func() {
		outtwo, err2 = nf2.Find(test_mac2, two)
		if err2 != nil {
			panic(err2)
		}
	}()
	for i := 0; i < 100; i++ {
		go PrintFromChannel(outone)
		go PrintFromChannel(outtwo)
		time.Sleep(1 * 1e9)
	}
}
<|endoftext|>


<commit_before>package swarm

import (
	"errors"
	"fmt"
	"sync"

	conn "github.com/jbenet/go-ipfs/p2p/net/conn"
	addrutil "github.com/jbenet/go-ipfs/p2p/net/swarm/addr"
	peer "github.com/jbenet/go-ipfs/p2p/peer"
	lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"

	context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
	ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
)

// dialsync is a small object that helps manage ongoing dials.
// this way, if we receive many simultaneous dial requests, one
// can do its thing, while the rest wait.
//
// this interface is so would-be dialers can just:
//
//  for {
//  	c := findConnectionToPeer(peer)
//  	if c != nil {
//  		return c
//  	}
//
//  	// ok, no connections. should we dial?
//  	if ok, wait := dialsync.Lock(peer); !ok {
//  		<-wait // can optionally wait
//  		continue
//  	}
//  	defer dialsync.Unlock(peer)
//
//  	c := actuallyDial(peer)
//  	return c
//  }
//
type dialsync struct {
	// ongoing is a map of tickets for the current peers being dialed.
	// this way, we dont kick off N dials simultaneously.
	ongoing map[peer.ID]chan struct{}
	lock    sync.Mutex
}

// Lock governs the beginning of a dial attempt.
// If there are no ongoing dials, it returns true, and the client is now
// scheduled to dial. Every other goroutine that calls startDial -- with
//the same dst -- will block until client is done. The client MUST call
// ds.Unlock(p) when it is done, to unblock the other callers.
// The client is not reponsible for achieving a successful dial, only for
// reporting the end of the attempt (calling ds.Unlock(p)).
//
// see the example below `dialsync`
func (ds *dialsync) Lock(dst peer.ID) (bool, chan struct{}) {
	ds.lock.Lock()
	if ds.ongoing == nil { // init if not ready
		ds.ongoing = make(map[peer.ID]chan struct{})
	}
	wait, found := ds.ongoing[dst]
	if !found {
		ds.ongoing[dst] = make(chan struct{})
	}
	ds.lock.Unlock()

	if found {
		return false, wait
	}

	// ok! you're signed up to dial!
	return true, nil
}

// Unlock releases waiters to a dial attempt. see Lock.
// if Unlock(p) is called without calling Lock(p) first, Unlock panics.
func (ds *dialsync) Unlock(dst peer.ID) {
	ds.lock.Lock()
	wait, found := ds.ongoing[dst]
	if !found {
		panic("called dialDone with no ongoing dials to peer: " + dst.Pretty())
	}
	delete(ds.ongoing, dst) // remove ongoing dial
	close(wait)             // release everyone else
	ds.lock.Unlock()
}

// Dial connects to a peer.
//
// The idea is that the client of Swarm does not need to know what network
// the connection will happen over. Swarm can use whichever it choses.
// This allows us to use various transport protocols, do NAT traversal/relay,
// etc. to achive connection.
func (s *Swarm) Dial(ctx context.Context, p peer.ID) (*Conn, error) {
	if p == s.local {
		return nil, errors.New("Attempted connection to self!")
	}

	// this loop is here because dials take time, and we should not be dialing
	// the same peer concurrently (silly waste). Additonally, it's structured
	// to check s.ConnectionsToPeer(p) _first_, and _between_ attempts because we
	// may have received an incoming connection! if so, we no longer must dial.
	//
	// dial attempts. we may be doing the dialing. if not, we wait.
	attempts := 3
	var err error
	var conn *Conn
	for i := 0; i < attempts; i++ {
		// check if we already have an open connection first
		cs := s.ConnectionsToPeer(p)
		for _, conn = range cs {
			if conn != nil { // dump out the first one we find. (TODO pick better)
				return conn, nil
			}
		}

		// check if there's an ongoing dial to this peer
		if ok, wait := s.dsync.Lock(p); !ok {
			select {
			case <-wait: // wait for that dial to finish.
				continue // and see if it worked (loop), OR we got an incoming dial.
			case <-ctx.Done(): // or we may have to bail...
				return nil, ctx.Err()
			}
		}

		// ok, we have been charged to dial! let's do it.
		conn, err = s.dial(ctx, p)
		s.dsync.Unlock(p)
		if err != nil {
			continue // ok, we failed. try again. (if loop is done, our error is output)
		}
		return conn, nil
	}
	return nil, err
}

// dial is the actual swarm's dial logic, gated by Dial.
func (s *Swarm) dial(ctx context.Context, p peer.ID) (*Conn, error) {
	if p == s.local {
		return nil, errors.New("Attempted connection to self!")
	}

	sk := s.peers.PrivKey(s.local)
	if sk == nil {
		// may be fine for sk to be nil, just log a warning.
		log.Warning("Dial not given PrivateKey, so WILL NOT SECURE conn.")
	}

	// get our own addrs
	localAddrs := s.peers.Addresses(s.local)
	if len(localAddrs) == 0 {
		log.Debug("Dialing out with no local addresses.")
	}

	// get remote peer addrs
	remoteAddrs := s.peers.Addresses(p)
	// make sure we can use the addresses.
	remoteAddrs = addrutil.FilterUsableAddrs(remoteAddrs)
	// drop out any addrs that would just dial ourselves. use ListenAddresses
	// as that is a more authoritative view than localAddrs.
	remoteAddrs = addrutil.Subtract(remoteAddrs, s.ListenAddresses())
	if len(remoteAddrs) == 0 {
		return nil, errors.New("peer has no addresses")
	}

	// open connection to peer
	d := &conn.Dialer{
		LocalPeer:  s.local,
		LocalAddrs: localAddrs,
		PrivateKey: sk,
	}

	// try to get a connection to any addr
	connC, err := s.dialAddrs(ctx, d, p, remoteAddrs)
	if err != nil {
		return nil, err
	}

	// ok try to setup the new connection.
	swarmC, err := dialConnSetup(ctx, s, connC)
	if err != nil {
		log.Error("Dial newConnSetup failed. disconnecting.")
		log.Event(ctx, "dialFailureDisconnect", lgbl.NetConn(connC), lgbl.Error(err))
		swarmC.Close() // close the connection. didn't work out :(
		return nil, err
	}

	log.Event(ctx, "dial", p)
	return swarmC, nil
}

func (s *Swarm) dialAddrs(ctx context.Context, d *conn.Dialer, p peer.ID, remoteAddrs []ma.Multiaddr) (conn.Conn, error) {

	// try to connect to one of the peer's known addresses.
	// for simplicity, we do this sequentially.
	// A future commit will do this asynchronously.
	for _, addr := range remoteAddrs {
		connC, err := d.Dial(ctx, addr, p)
		if err != nil {
			continue
		}

		// if the connection is not to whom we thought it would be...
		if connC.RemotePeer() != p {
			log.Infof("misdial to %s through %s (got %s)", p, addr, connC.RemoteMultiaddr())
			connC.Close()
			continue
		}

		// if the connection is to ourselves...
		// this can happen TONS when Loopback addrs are advertized.
		// (this should be caught by two checks above, but let's just make sure.)
		if connC.RemotePeer() == s.local {
			log.Infof("misdial to %s through %s", p, addr)
			connC.Close()
			continue
		}

		// success! we got one!
		return connC, nil
	}
	return nil, fmt.Errorf("failed to dial %s", p)
}

// dialConnSetup is the setup logic for a connection from the dial side. it
// needs to add the Conn to the StreamSwarm, then run newConnSetup
func dialConnSetup(ctx context.Context, s *Swarm, connC conn.Conn) (*Conn, error) {

	psC, err := s.swarm.AddConn(connC)
	if err != nil {
		// connC is closed by caller if we fail.
		return nil, fmt.Errorf("failed to add conn to ps.Swarm: %s", err)
	}

	// ok try to setup the new connection. (newConnSetup will add to group)
	swarmC, err := s.newConnSetup(ctx, psC)
	if err != nil {
		log.Error("Dial newConnSetup failed. disconnecting.")
		log.Event(ctx, "dialFailureDisconnect", lgbl.NetConn(connC), lgbl.Error(err))
		swarmC.Close() // we need to call this to make sure psC is Closed.
		return nil, err
	}

	return swarmC, err
}
<commit_msg>p2p/net/swarm: const dial attempts<commit_after>package swarm

import (
	"errors"
	"fmt"
	"sync"

	conn "github.com/jbenet/go-ipfs/p2p/net/conn"
	addrutil "github.com/jbenet/go-ipfs/p2p/net/swarm/addr"
	peer "github.com/jbenet/go-ipfs/p2p/peer"
	lgbl "github.com/jbenet/go-ipfs/util/eventlog/loggables"

	context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
	ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
)

// dialAttempts governs how many times a goroutine will try to dial a given peer.
const dialAttempts = 3

// dialsync is a small object that helps manage ongoing dials.
// this way, if we receive many simultaneous dial requests, one
// can do its thing, while the rest wait.
//
// this interface is so would-be dialers can just:
//
//  for {
//  	c := findConnectionToPeer(peer)
//  	if c != nil {
//  		return c
//  	}
//
//  	// ok, no connections. should we dial?
//  	if ok, wait := dialsync.Lock(peer); !ok {
//  		<-wait // can optionally wait
//  		continue
//  	}
//  	defer dialsync.Unlock(peer)
//
//  	c := actuallyDial(peer)
//  	return c
//  }
//
type dialsync struct {
	// ongoing is a map of tickets for the current peers being dialed.
	// this way, we dont kick off N dials simultaneously.
	ongoing map[peer.ID]chan struct{}
	lock    sync.Mutex
}

// Lock governs the beginning of a dial attempt.
// If there are no ongoing dials, it returns true, and the client is now
// scheduled to dial. Every other goroutine that calls startDial -- with
//the same dst -- will block until client is done. The client MUST call
// ds.Unlock(p) when it is done, to unblock the other callers.
// The client is not reponsible for achieving a successful dial, only for
// reporting the end of the attempt (calling ds.Unlock(p)).
//
// see the example below `dialsync`
func (ds *dialsync) Lock(dst peer.ID) (bool, chan struct{}) {
	ds.lock.Lock()
	if ds.ongoing == nil { // init if not ready
		ds.ongoing = make(map[peer.ID]chan struct{})
	}
	wait, found := ds.ongoing[dst]
	if !found {
		ds.ongoing[dst] = make(chan struct{})
	}
	ds.lock.Unlock()

	if found {
		return false, wait
	}

	// ok! you're signed up to dial!
	return true, nil
}

// Unlock releases waiters to a dial attempt. see Lock.
// if Unlock(p) is called without calling Lock(p) first, Unlock panics.
func (ds *dialsync) Unlock(dst peer.ID) {
	ds.lock.Lock()
	wait, found := ds.ongoing[dst]
	if !found {
		panic("called dialDone with no ongoing dials to peer: " + dst.Pretty())
	}
	delete(ds.ongoing, dst) // remove ongoing dial
	close(wait)             // release everyone else
	ds.lock.Unlock()
}

// Dial connects to a peer.
//
// The idea is that the client of Swarm does not need to know what network
// the connection will happen over. Swarm can use whichever it choses.
// This allows us to use various transport protocols, do NAT traversal/relay,
// etc. to achive connection.
func (s *Swarm) Dial(ctx context.Context, p peer.ID) (*Conn, error) {
	if p == s.local {
		return nil, errors.New("Attempted connection to self!")
	}

	// this loop is here because dials take time, and we should not be dialing
	// the same peer concurrently (silly waste). Additonally, it's structured
	// to check s.ConnectionsToPeer(p) _first_, and _between_ attempts because we
	// may have received an incoming connection! if so, we no longer must dial.
	//
	// During the dial attempts, we may be doing the dialing. if not, we wait.
	var err error
	var conn *Conn
	for i := 0; i < dialAttempts; i++ {
		// check if we already have an open connection first
		cs := s.ConnectionsToPeer(p)
		for _, conn = range cs {
			if conn != nil { // dump out the first one we find. (TODO pick better)
				return conn, nil
			}
		}

		// check if there's an ongoing dial to this peer
		if ok, wait := s.dsync.Lock(p); !ok {
			select {
			case <-wait: // wait for that dial to finish.
				continue // and see if it worked (loop), OR we got an incoming dial.
			case <-ctx.Done(): // or we may have to bail...
				return nil, ctx.Err()
			}
		}

		// ok, we have been charged to dial! let's do it.
		conn, err = s.dial(ctx, p)
		s.dsync.Unlock(p)
		if err != nil {
			continue // ok, we failed. try again. (if loop is done, our error is output)
		}
		return conn, nil
	}
	return nil, err
}

// dial is the actual swarm's dial logic, gated by Dial.
func (s *Swarm) dial(ctx context.Context, p peer.ID) (*Conn, error) {
	if p == s.local {
		return nil, errors.New("Attempted connection to self!")
	}

	sk := s.peers.PrivKey(s.local)
	if sk == nil {
		// may be fine for sk to be nil, just log a warning.
		log.Warning("Dial not given PrivateKey, so WILL NOT SECURE conn.")
	}

	// get our own addrs
	localAddrs := s.peers.Addresses(s.local)
	if len(localAddrs) == 0 {
		log.Debug("Dialing out with no local addresses.")
	}

	// get remote peer addrs
	remoteAddrs := s.peers.Addresses(p)
	// make sure we can use the addresses.
	remoteAddrs = addrutil.FilterUsableAddrs(remoteAddrs)
	// drop out any addrs that would just dial ourselves. use ListenAddresses
	// as that is a more authoritative view than localAddrs.
	remoteAddrs = addrutil.Subtract(remoteAddrs, s.ListenAddresses())
	if len(remoteAddrs) == 0 {
		return nil, errors.New("peer has no addresses")
	}

	// open connection to peer
	d := &conn.Dialer{
		LocalPeer:  s.local,
		LocalAddrs: localAddrs,
		PrivateKey: sk,
	}

	// try to get a connection to any addr
	connC, err := s.dialAddrs(ctx, d, p, remoteAddrs)
	if err != nil {
		return nil, err
	}

	// ok try to setup the new connection.
	swarmC, err := dialConnSetup(ctx, s, connC)
	if err != nil {
		log.Error("Dial newConnSetup failed. disconnecting.")
		log.Event(ctx, "dialFailureDisconnect", lgbl.NetConn(connC), lgbl.Error(err))
		swarmC.Close() // close the connection. didn't work out :(
		return nil, err
	}

	log.Event(ctx, "dial", p)
	return swarmC, nil
}

func (s *Swarm) dialAddrs(ctx context.Context, d *conn.Dialer, p peer.ID, remoteAddrs []ma.Multiaddr) (conn.Conn, error) {

	// try to connect to one of the peer's known addresses.
	// for simplicity, we do this sequentially.
	// A future commit will do this asynchronously.
	for _, addr := range remoteAddrs {
		connC, err := d.Dial(ctx, addr, p)
		if err != nil {
			continue
		}

		// if the connection is not to whom we thought it would be...
		if connC.RemotePeer() != p {
			log.Infof("misdial to %s through %s (got %s)", p, addr, connC.RemoteMultiaddr())
			connC.Close()
			continue
		}

		// if the connection is to ourselves...
		// this can happen TONS when Loopback addrs are advertized.
		// (this should be caught by two checks above, but let's just make sure.)
		if connC.RemotePeer() == s.local {
			log.Infof("misdial to %s through %s", p, addr)
			connC.Close()
			continue
		}

		// success! we got one!
		return connC, nil
	}
	return nil, fmt.Errorf("failed to dial %s", p)
}

// dialConnSetup is the setup logic for a connection from the dial side. it
// needs to add the Conn to the StreamSwarm, then run newConnSetup
func dialConnSetup(ctx context.Context, s *Swarm, connC conn.Conn) (*Conn, error) {

	psC, err := s.swarm.AddConn(connC)
	if err != nil {
		// connC is closed by caller if we fail.
		return nil, fmt.Errorf("failed to add conn to ps.Swarm: %s", err)
	}

	// ok try to setup the new connection. (newConnSetup will add to group)
	swarmC, err := s.newConnSetup(ctx, psC)
	if err != nil {
		log.Error("Dial newConnSetup failed. disconnecting.")
		log.Event(ctx, "dialFailureDisconnect", lgbl.NetConn(connC), lgbl.Error(err))
		swarmC.Close() // we need to call this to make sure psC is Closed.
		return nil, err
	}

	return swarmC, err
}
<|endoftext|>


<commit_before>package test

import (
	"XML-Comp/comparer"
	"testing"
)

func TestCompareFolder(t *testing.T) {
	//Testing for non-existing directories
	instance := comparer.Data{PathA: "fakeDir1", PathB: "fakeDir2"}
	if instance.CompareContainingFoldersAndFiles() == nil {
		//If error = nil, then the function failed to notice fakeDirectories
		t.Error("Oops! looks like error in existance of folders")
	}

	//Testing for blank values
	instance = comparer.Data{}
	if instance.CompareContainingFoldersAndFiles() == nil {
		//If error nil, then the validation was somehow bypassed
		t.Error("Oops! Error in Path validation")
	}
}
<commit_msg>Few changes<commit_after>package test

import (
	"XML-Comp/comparer"
	"os"
	"testing"
)

func TestCompareFolder(t *testing.T) {
	//Testing for non-existing directories
	instance := comparer.Data{PathA: "fakeDir1", PathB: "fakeDir2"}
	if instance.CompareContainingFoldersAndFiles() == nil {
		//If error = nil, then the function failed to notice fakeDirectories
		t.Error("Oops! looks like error in existance of folders")
	}

	//Testing for blank values
	instance = comparer.Data{}
	if instance.CompareContainingFoldersAndFiles() == nil {
		//If error nil, then the validation was somehow bypassed
		t.Error("Oops! Error in Path validation")
	}

	//Testing for actual folders
	//the code will create 2 directories with files
	tmpDir := os.TempDir()
	pathA := tmpDir + "/_Dir1/subDir/superSub"
	err := os.MkdirAll(pathA, 0777)
	if err != nil {
		t.Fatalf("MkdirAll %q: %s", pathA, err)
	}

	pathB := tmpDir + "/_Dir2/subDir"
	err = os.MkdirAll(pathB, 0777)
	if err != nil {
		t.Fatalf("MkdirAll %q: %s", pathB, err)
	}
	//Temporary directories created

	instance = comparer.Data{PathA: pathA, PathB: pathB}
	if instance.CompareContainingFoldersAndFiles() != nil {
		t.Error("Oops! seems like a logical error")
	}
}
<|endoftext|>


<commit_before>// Copyright © 2015 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

package mqtt

import (
	"reflect"
	"testing"
	"time"

	MQTT "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
	. "github.com/TheThingsNetwork/ttn/core/errors"
	core "github.com/TheThingsNetwork/ttn/refactor"
	"github.com/TheThingsNetwork/ttn/utils/errors"
	. "github.com/TheThingsNetwork/ttn/utils/testing"
	//"github.com/TheThingsNetwork/ttn/utils/pointer"
)

const brokerUrl = "0.0.0.0:1683"

func TestMQTTSend(t *testing.T) {
	tests := []struct {
		Desc       string          // Test Description
		Packet     []byte          // Handy representation of the packet to send
		Recipients []testRecipient // List of recipient to send

		WantData     []byte  // Expected Data on the recipient
		WantResponse []byte  // Expected Response from the Send method
		WantError    *string // Expected error nature returned by the Send method
	}{}

	for _, test := range tests {
		// Describe
		Desc(t, test.Desc)

		// Build
		aclient, adapter := createAdapter(t)
		sclient, chresp := createServers(test.Recipients)

		// Operate
		data, err := trySend(adapter, test.Packet, test.Recipients)
		var resp []byte
		select {
		case resp = <-chresp:
		case <-time.After(time.Millisecond * 100):
		}

		// Check
		checkErrors(t, test.WantError, err)
		checkData(t, test.WantData, data)
		checkResponses(t, test.WantResponse, resp)

		// Clean
		aclient.Disconnect(0)
		sclient.Disconnect(0)
	}
}

// ----- TYPE utilities
type testRecipient struct {
	Response  []byte
	TopicUp   string
	TopicDown string
}

type testPacket struct {
	payload []byte
}

// MarshalBinary implements the encoding.BinaryMarshaler interface
func (p testPacket) MarshalBinary() ([]byte, error) {
	if p.payload == nil {
		return nil, errors.New(ErrInvalidStructure, "Fake error")
	}

	return p.payload, nil
}

// String implements the core.Packet interface
func (p testPacket) String() string {
	return string(p.payload)
}

// ----- BUILD utilities
func createAdapter(t *testing.T) (*MQTT.Client, core.Adapter) {
	client, err := NewClient("testClient", brokerUrl, Tcp)
	if err != nil {
		panic(err)
	}

	adapter := NewAdapter(client, GetLogger(t, "adapter"))
	return client, adapter
}

func createServers(recipients []testRecipient) (*MQTT.Client, chan []byte) {
	client, err := NewClient("FakeServerClient", brokerUrl, Tcp)
	if err != nil {
		panic(err)
	}

	chresp := make(chan []byte, len(recipients))
	for _, r := range recipients {
		token := client.Subscribe(r.TopicUp, 2, func(client *MQTT.Client, msg MQTT.Message) {
			if r.Response != nil {
				token := client.Publish(r.TopicDown, 2, false, r.Response)
				if token.Wait() && token.Error() != nil {
					panic(token.Error())
				}
			}
			chresp <- msg.Payload()
		})
		if token.Wait() && token.Error() != nil {
			panic(token.Error())
		}
	}
	return client, chresp
}

// ----- OPERATE utilities
func trySend(adapter core.Adapter, packet []byte, recipients []testRecipient) ([]byte, error) {
	// Convert testRecipient to core.Recipient using the mqtt recipient
	var coreRecipients []core.Recipient
	for _, r := range recipients {
		coreRecipients = append(coreRecipients, NewRecipient(r.TopicUp, r.TopicDown))
	}

	// Try send the packet
	chresp := make(chan struct {
		Data  []byte
		Error error
	})
	go func() {
		data, err := adapter.Send(testPacket{packet}, coreRecipients...)
		chresp <- struct {
			Data  []byte
			Error error
		}{data, err}
	}()

	select {
	case resp := <-chresp:
		return resp.Data, resp.Error
	case <-time.After(time.Millisecond * 200):
		return nil, nil
	}
}

// ----- CHECK utilities
func checkErrors(t *testing.T, want *string, got error) {
	if got == nil {
		if want == nil {
			Ok(t, "Check errors")
			return
		}
		Ko(t, "Expected error to be {%s} but got nothing", *want)
		return
	}

	if want == nil {
		Ko(t, "Expected no error but got {%v}", got)
		return
	}

	if got.(errors.Failure).Nature == *want {
		Ok(t, "Check errors")
		return
	}
	Ko(t, "Expected error to be {%s} but got {%v}", *want, got)
}

func checkResponses(t *testing.T, want []byte, got []byte) {
	if reflect.DeepEqual(want, got) {
		Ok(t, "Check responses")
		return
	}
	Ko(t, "Received response does not match expectations.\nWant: %s\nGot:  %s", string(want), string(got))
}

func checkData(t *testing.T, want []byte, got []byte) {
	if reflect.DeepEqual(want, got) {
		Ok(t, "Check data")
		return
	}
	Ko(t, "Received data does not match expectations.\nWant: %s\nGot:  %s", string(want), string(got))
}
<commit_msg>[refactor] Fix timeout delays in test procedure + write first test procedure<commit_after>// Copyright © 2015 The Things Network
// Use of this source code is governed by the MIT license that can be found in the LICENSE file.

package mqtt

import (
	"reflect"
	"testing"
	"time"

	MQTT "git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.golang.git"
	. "github.com/TheThingsNetwork/ttn/core/errors"
	core "github.com/TheThingsNetwork/ttn/refactor"
	"github.com/TheThingsNetwork/ttn/utils/errors"
	"github.com/TheThingsNetwork/ttn/utils/pointer"
	. "github.com/TheThingsNetwork/ttn/utils/testing"
)

const brokerUrl = "0.0.0.0:1683"

func TestMQTTSend(t *testing.T) {
	tests := []struct {
		Desc       string          // Test Description
		Packet     []byte          // Handy representation of the packet to send
		Recipients []testRecipient // List of recipient to send

		WantData     []byte  // Expected Data on the recipient
		WantResponse []byte  // Expected Response from the Send method
		WantError    *string // Expected error nature returned by the Send method
	}{
		{
			Desc:   "1 packet | 1 recipient | No response",
			Packet: []byte("TheThingsNetwork"),
			Recipients: []testRecipient{
				{
					Response:  nil,
					TopicUp:   "up1",
					TopicDown: "down1",
				},
			},

			WantData:     []byte("TheThingsNetwork"),
			WantResponse: nil,
			WantError:    pointer.String(ErrWrongBehavior),
		},
	}

	for _, test := range tests {
		// Describe
		Desc(t, test.Desc)

		// Build
		aclient, adapter := createAdapter(t)
		sclient, chresp := createServers(test.Recipients)
		<-time.After(time.Millisecond * 50)

		// Operate
		resp, err := trySend(adapter, test.Packet, test.Recipients)
		var data []byte
		select {
		case data = <-chresp:
		case <-time.After(time.Millisecond * 100):
		}

		// Check
		checkErrors(t, test.WantError, err)
		checkData(t, test.WantData, data)
		checkResponses(t, test.WantResponse, resp)

		// Clean
		aclient.Disconnect(0)
		sclient.Disconnect(0)
		<-time.After(time.Millisecond * 50)
	}
}

// ----- TYPE utilities
type testRecipient struct {
	Response  []byte
	TopicUp   string
	TopicDown string
}

type testPacket struct {
	payload []byte
}

// MarshalBinary implements the encoding.BinaryMarshaler interface
func (p testPacket) MarshalBinary() ([]byte, error) {
	if p.payload == nil {
		return nil, errors.New(ErrInvalidStructure, "Fake error")
	}

	return p.payload, nil
}

// String implements the core.Packet interface
func (p testPacket) String() string {
	return string(p.payload)
}

// ----- BUILD utilities
func createAdapter(t *testing.T) (*MQTT.Client, core.Adapter) {
	client, err := NewClient("testClient", brokerUrl, Tcp)
	if err != nil {
		panic(err)
	}

	adapter := NewAdapter(client, GetLogger(t, "adapter"))
	return client, adapter
}

func createServers(recipients []testRecipient) (*MQTT.Client, chan []byte) {
	client, err := NewClient("FakeServerClient", brokerUrl, Tcp)
	if err != nil {
		panic(err)
	}

	chresp := make(chan []byte, len(recipients))
	for _, r := range recipients {
		go func(r testRecipient) {
			token := client.Subscribe(r.TopicUp, 2, func(client *MQTT.Client, msg MQTT.Message) {
				if r.Response != nil {
					token := client.Publish(r.TopicDown, 2, false, r.Response)
					if token.Wait() && token.Error() != nil {
						panic(token.Error())
					}
				}
				chresp <- msg.Payload()
			})
			if token.Wait() && token.Error() != nil {
				panic(token.Error())
			}
		}(r)
	}
	return client, chresp
}

// ----- OPERATE utilities
func trySend(adapter core.Adapter, packet []byte, recipients []testRecipient) ([]byte, error) {
	// Convert testRecipient to core.Recipient using the mqtt recipient
	var coreRecipients []core.Recipient
	for _, r := range recipients {
		coreRecipients = append(coreRecipients, NewRecipient(r.TopicUp, r.TopicDown))
	}

	// Try send the packet
	chresp := make(chan struct {
		Data  []byte
		Error error
	})
	go func() {
		data, err := adapter.Send(testPacket{packet}, coreRecipients...)
		chresp <- struct {
			Data  []byte
			Error error
		}{data, err}
	}()

	select {
	case resp := <-chresp:
		return resp.Data, resp.Error
	case <-time.After(time.Millisecond * 1250):
		return nil, nil
	}
}

// ----- CHECK utilities
func checkErrors(t *testing.T, want *string, got error) {
	if got == nil {
		if want == nil {
			Ok(t, "Check errors")
			return
		}
		Ko(t, "Expected error to be {%s} but got nothing", *want)
		return
	}

	if want == nil {
		Ko(t, "Expected no error but got {%v}", got)
		return
	}

	if got.(errors.Failure).Nature == *want {
		Ok(t, "Check errors")
		return
	}
	Ko(t, "Expected error to be {%s} but got {%v}", *want, got)
}

func checkResponses(t *testing.T, want []byte, got []byte) {
	if reflect.DeepEqual(want, got) {
		Ok(t, "Check responses")
		return
	}
	Ko(t, "Received response does not match expectations.\nWant: %s\nGot:  %s", string(want), string(got))
}

func checkData(t *testing.T, want []byte, got []byte) {
	if reflect.DeepEqual(want, got) {
		Ok(t, "Check data")
		return
	}
	Ko(t, "Received data does not match expectations.\nWant: %s\nGot:  %s", string(want), string(got))
}
<|endoftext|>


<commit_before>package trillian_client

import (
	"context"
	"fmt"
	"log"

	"github.com/google/trillian"
	"google.golang.org/grpc"
)

const CHUNK = 10

type LogScanner interface {
	Leaf(leaf *trillian.LogLeaf) error
}

type TrillianClient interface {
	Scan(logID int64, s LogScanner) error
	Close()
}

type trillianClient struct {
	g  *grpc.ClientConn
	tc trillian.TrillianLogClient
}

func New(logAddr string) TrillianClient {
	g, err := grpc.Dial(logAddr, grpc.WithInsecure())
	if err != nil {
		log.Fatalf("Failed to dial Trillian Log: %v", err)
	}

	tc := trillian.NewTrillianLogClient(g)

	return &trillianClient{g, tc}
}

func (t *trillianClient) Scan(logID int64, s LogScanner) error {
	ctx := context.Background()

	rr := &trillian.GetLatestSignedLogRootRequest{LogId: logID}
	lr, err := t.tc.GetLatestSignedLogRoot(ctx, rr)
	if err != nil {
		log.Fatalf("Can't get log root: %v", err)
	}

	ts := lr.SignedLogRoot.TreeSize
	for n := int64(0); n < ts; {
		g := &trillian.GetLeavesByRangeRequest{LogId: logID, StartIndex: n, Count: CHUNK}
		r, err := t.tc.GetLeavesByRange(ctx, g)
		if err != nil {
			return fmt.Errorf("Can't get leaf %d: %v", n, err)
		}

		// Deal with server skew, if tree size has reduced.
		// Don't allow increases so this terminates eventually.
		rts := r.SignedLogRoot.TreeSize
		if rts < ts {
			ts = rts
		}

		if n < ts && len(r.Leaves) == 0 {
			return fmt.Errorf("No progress at leaf %d", n)
		}

		for m := 0; m < len(r.Leaves) && n < ts; n++ {
			if r.Leaves[m] == nil {
				return fmt.Errorf("Can't get leaf %d (no error)", n)
			}
			if r.Leaves[m].LeafIndex != n {
				return fmt.Errorf("Got index %d expected %d", r.Leaves[n].LeafIndex, n)
			}
			err := s.Leaf(r.Leaves[m])
			if err != nil {
				return err
			}
			m++
		}
	}
	return nil
}

func (t *trillianClient) Close() {
	t.g.Close()
}
<commit_msg>Document.<commit_after>// Package trillian_client provides some useful utilities for
// interacting with Trillian.
package trillian_client

import (
	"context"
	"fmt"
	"log"

	"github.com/google/trillian"
	"google.golang.org/grpc"
)

const chunk = 10

// A type that is passed to TrillianClient.Scan(). Leaf() is called on
// it for each leaf in the log.
type LogScanner interface {
	Leaf(leaf *trillian.LogLeaf) error
}

// A Trillian client. Create a new one with trillian_client.New().
type TrillianClient interface {
	Scan(logID int64, s LogScanner) error
	Close()
}

type trillianClient struct {
	g  *grpc.ClientConn
	tc trillian.TrillianLogClient
}

// New creates and connects new TrillianClient, given the URL of the
// Trillian server.
func New(logAddr string) TrillianClient {
	g, err := grpc.Dial(logAddr, grpc.WithInsecure())
	if err != nil {
		log.Fatalf("Failed to dial Trillian Log: %v", err)
	}

	tc := trillian.NewTrillianLogClient(g)

	return &trillianClient{g, tc}
}

func (t *trillianClient) Scan(logID int64, s LogScanner) error {
	ctx := context.Background()

	rr := &trillian.GetLatestSignedLogRootRequest{LogId: logID}
	lr, err := t.tc.GetLatestSignedLogRoot(ctx, rr)
	if err != nil {
		log.Fatalf("Can't get log root: %v", err)
	}

	ts := lr.SignedLogRoot.TreeSize
	for n := int64(0); n < ts; {
		g := &trillian.GetLeavesByRangeRequest{LogId: logID, StartIndex: n, Count: chunk}
		r, err := t.tc.GetLeavesByRange(ctx, g)
		if err != nil {
			return fmt.Errorf("Can't get leaf %d: %v", n, err)
		}

		// Deal with server skew, if tree size has reduced.
		// Don't allow increases so this terminates eventually.
		rts := r.SignedLogRoot.TreeSize
		if rts < ts {
			ts = rts
		}

		if n < ts && len(r.Leaves) == 0 {
			return fmt.Errorf("No progress at leaf %d", n)
		}

		for m := 0; m < len(r.Leaves) && n < ts; n++ {
			if r.Leaves[m] == nil {
				return fmt.Errorf("Can't get leaf %d (no error)", n)
			}
			if r.Leaves[m].LeafIndex != n {
				return fmt.Errorf("Got index %d expected %d", r.Leaves[n].LeafIndex, n)
			}
			err := s.Leaf(r.Leaves[m])
			if err != nil {
				return err
			}
			m++
		}
	}
	return nil
}

func (t *trillianClient) Close() {
	t.g.Close()
}
<|endoftext|>


<commit_before>package xcassets

import (
	"strconv"
	"strings"
)

type Contents struct {
	Images []Image `json:"images"`
	Info   Info    `json:"info"`
}

type Image struct {
	Size                 string `json:"size"`
	Idiom                string `json:"idiom"`
	Filename             string `json:"filename"`
	Scale                string `json:"scale"`
	Subtype              string `json:"subtype,omitempty"`
	Extent               string `json:"extent,omitempty"`
	MinimumSystemVersion string `json:"minimum-system-version,omitempty"`
	Orientation          string `json:"orientation,omitempty"`
}

func (i Image) Px() uint {
	size := strings.Split(i.Size, "x")
	sizePX, _ := strconv.ParseUint(size[0], 10, 32)
	scale, _ := strconv.ParseUint(string(i.Scale[0]), 10, 32)
	return uint(sizePX * scale)
}

type Info struct {
	Version int    `json:"version"`
	Author  string `json:"author"`
}

func NewContents() Contents {
	contents := Contents{}
	contents.Info = Info{
		Version: 1,
		Author:  "xcode",
	}
	contents.Images = make([]Image, 0)
	return contents
}
<commit_msg>Add godoc comments<commit_after>package xcassets

import (
	"strconv"
	"strings"
)

//Contents represents a Contents.json file.
type Contents struct {
	Images []Image `json:"images"`
	Info   Info    `json:"info"`
}

//Image is a particular image within an image set.
type Image struct {
	Size                 string `json:"size"`
	Idiom                string `json:"idiom"`
	Filename             string `json:"filename"`
	Scale                string `json:"scale"`
	Subtype              string `json:"subtype,omitempty"`
	Extent               string `json:"extent,omitempty"`
	MinimumSystemVersion string `json:"minimum-system-version,omitempty"`
	Orientation          string `json:"orientation,omitempty"`
}

//Px returns the dimensions in pixels of this image.
func (i Image) Px() uint {
	size := strings.Split(i.Size, "x")
	sizePX, _ := strconv.ParseUint(size[0], 10, 32)
	scale, _ := strconv.ParseUint(string(i.Scale[0]), 10, 32)
	return uint(sizePX * scale)
}

//Info contains metadata about this image set.
type Info struct {
	Version int    `json:"version"`
	Author  string `json:"author"`
}

//NewContents creates a new Contents, containing no images.
func NewContents() Contents {
	contents := Contents{}
	contents.Info = Info{
		Version: 1,
		Author:  "xcode",
	}
	contents.Images = make([]Image, 0)
	return contents
}
<|endoftext|>


<commit_before>// Package entitlement provides entitlement certificate based authentication
// scheme that checks whether the requested path is present in the entitlement
// certificate or not.
//
// This authentication must be used under TLS, as non SSL requests won't have the
// certificate data in the request
package entitlement

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

	log "github.com/Sirupsen/logrus"
	"github.com/docker/distribution/context"
	"github.com/docker/distribution/registry/auth"
)

// accessController provides a implementation of auth.AccessController
// that checks for a non-empty SSL CLIENT header, which is then used for
// entitlement cert based authentication. It is useful for
// candlepin issued entitlement cert based auth.
type accessController struct {
	realm   string
	service *Entitlement
}

var _ auth.AccessController = &accessController{}

func newAccessController(options map[string]interface{}) (auth.AccessController, error) {
	realm, present := options["realm"]
	if _, ok := realm.(string); !present || !ok {
		return nil, fmt.Errorf(`"realm" must be set for entitlement access controller`)
	}

	service, present := options["servicePath"]
	if _, ok := service.(string); !present || !ok {
		return nil, fmt.Errorf(`"servicePath" must be set for entitlement access controller`)
	}

	//var e Entitlement
	e := NewEntitlement(service.(string))

	return &accessController{realm: realm.(string), service: e}, nil
}

// Authorized simply checks for the existence of the SSL CLIENT headers,
// using which entitlement check is done
func (ac *accessController) Authorized(ctx context.Context, accessRecords ...auth.Access) (context.Context, error) {
	var resData ResponseData
	var err1 error
	req, err := context.GetRequest(ctx)
	if err != nil {
		return nil, err
	}

	if req.Header.Get("SSL_CLIENT_CERT") == "" {
		log.Debugln("repo name: %s", getName(ctx))

		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	pemStr := req.Header.Get("SSL_CLIENT_CERT")
	log.Debugln("SSL CERT: %s", pemStr)
	repoName := getName(ctx)
	//if it is a push request
	//or the the URI requested is /v2/ (ping)
	//then don't call authentication service
	log.Debugln("requestURI: ", req.RequestURI)
	log.Debugln("requested repo name: ", getName(ctx))
	if skipAuth(req) {
		log.Debugln("Returning without calling authentication servie")
		return auth.WithUser(ctx, auth.UserInfo{Name: "entitled-ping"}), nil
	}

	// check for repo name being empty. If repo name is empty
	// and the URI is not for ping, return authentication error
	if "/v2/" != req.RequestURI && repoName == "" {
		log.Errorln("No repo name retrieved. This should not happen")
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure as no repo name has been supplied"),
		}
	}

	libraryName := repoName[:strings.LastIndex(repoName, "/")+1]
	log.Debugln("Computed library name: ", libraryName)
	path := fmt.Sprintf("/content/dist/rhel/server/7/7Server/x86_64/containers/registry/%s", libraryName)

	if resData, err1 = ac.service.CheckEntitlement(pemStr, path); err1 != nil {
		log.Errorln("Service returned error: ", err1)
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	if resData.Verified != "true" {
		log.Errorln("Service returned unauthenticated/unauthorized")
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	return auth.WithUser(ctx, auth.UserInfo{Name: "entitled"}), nil
}

type challenge struct {
	realm string
	err   error
}

// Error returns the internal error string for this authChallenge.
func (ac challenge) Error() string {
	return ac.err.Error()
}

// SetChallenge sets the WWW-Authenticate value for the response. However
// that is not required for entitlement based auth. Hence, providing empty
// implementation
func (ac challenge) SetHeaders(w http.ResponseWriter) {

}

var _ auth.Challenge = challenge{}

// init handles registering the entitlement auth backend.
func init() {
	auth.Register("entitlement", auth.InitFunc(newAccessController))
}

func getName(ctx context.Context) (name string) {
	return context.GetStringValue(ctx, "vars.name")
}

func skipAuth(req *http.Request) bool {
	return "/v2/" == req.RequestURI || req.Method == "POST" || req.Method == "HEAD" || req.Method == "PATCH" || req.Method == "PUT"
}
<commit_msg>NA: Redirect request<commit_after>// Package entitlement provides entitlement certificate based authentication
// scheme that checks whether the requested path is present in the entitlement
// certificate or not.
//
// This authentication must be used under TLS, as non SSL requests won't have the
// certificate data in the request
package entitlement

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

	log "github.com/Sirupsen/logrus"
	"github.com/docker/distribution/context"
	"github.com/docker/distribution/registry/auth"
)

// accessController provides a implementation of auth.AccessController
// that checks for a non-empty SSL CLIENT header, which is then used for
// entitlement cert based authentication. It is useful for
// candlepin issued entitlement cert based auth.
type accessController struct {
	realm   string
	service *Entitlement
}

var _ auth.AccessController = &accessController{}

func newAccessController(options map[string]interface{}) (auth.AccessController, error) {
	realm, present := options["realm"]
	if _, ok := realm.(string); !present || !ok {
		return nil, fmt.Errorf(`"realm" must be set for entitlement access controller`)
	}

	service, present := options["servicePath"]
	if _, ok := service.(string); !present || !ok {
		return nil, fmt.Errorf(`"servicePath" must be set for entitlement access controller`)
	}

	//var e Entitlement
	e := NewEntitlement(service.(string))

	return &accessController{realm: realm.(string), service: e}, nil
}

// Authorized simply checks for the existence of the SSL CLIENT headers,
// using which entitlement check is done
func (ac *accessController) Authorized(ctx context.Context, accessRecords ...auth.Access) (context.Context, error) {
	var resData ResponseData
	var err1 error
	req, err := context.GetRequest(ctx)
	if err != nil {
		return nil, err
	}

	if req.Header.Get("SSL_CLIENT_CERT") == "" {
		log.Debugln("repo name: %s", getName(ctx))

		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	pemStr := req.Header.Get("SSL_CLIENT_CERT")
	log.Debugln("SSL CERT: %s", pemStr)
	repoName := getName(ctx)
	//if it is a push request
	//or the the URI requested is /v2/ (ping)
	//then don't call authentication service
	log.Debugln("requestURI: ", req.RequestURI)
	log.Debugln("requested repo name: ", getName(ctx))
	if skipAuth(req) {
		log.Debugln("Returning without calling authentication servie")
		return auth.WithUser(ctx, auth.UserInfo{Name: "entitled-ping"}), nil
	}

	// check for repo name being empty. If repo name is empty
	// and the URI is not for ping, return authentication error
	if "/v2/" != req.RequestURI && repoName == "" {
		log.Errorln("No repo name retrieved. This should not happen")
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure as no repo name has been supplied"),
		}
	}

	libraryName := repoName[:strings.LastIndex(repoName, "/")+1]
	log.Debugln("Computed library name: ", libraryName)
	path := fmt.Sprintf("/content/dist/rhel/server/7/7Server/x86_64/containers/registry/%s", libraryName)
	http.Redirect(req, ac.service.EndPoint, 302)
	if resData, err1 = ac.service.CheckEntitlement(pemStr, path); err1 != nil {
		log.Errorln("Service returned error: ", err1)
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	if resData.Verified != "true" {
		log.Errorln("Service returned unauthenticated/unauthorized")
		return nil, &challenge{
			realm: ac.realm,
			err:   fmt.Errorf("Authentication Failure"),
		}
	}

	return auth.WithUser(ctx, auth.UserInfo{Name: "entitled"}), nil
}

type challenge struct {
	realm string
	err   error
}

// Error returns the internal error string for this authChallenge.
func (ac challenge) Error() string {
	return ac.err.Error()
}

// SetChallenge sets the WWW-Authenticate value for the response. However
// that is not required for entitlement based auth. Hence, providing empty
// implementation
func (ac challenge) SetHeaders(w http.ResponseWriter) {

}

var _ auth.Challenge = challenge{}

// init handles registering the entitlement auth backend.
func init() {
	auth.Register("entitlement", auth.InitFunc(newAccessController))
}

func getName(ctx context.Context) (name string) {
	return context.GetStringValue(ctx, "vars.name")
}

func skipAuth(req *http.Request) bool {
	return "/v2/" == req.RequestURI || req.Method == "POST" || req.Method == "HEAD" || req.Method == "PATCH" || req.Method == "PUT"
}
<|endoftext|>


<commit_before>package adyen

/* One-click functionality gives the shopper the option to store their payment details with the merchant, within the Adyen environment. In this type of transaction, the shopper needs to enter the CVC code for the transaction to get through.
Same than for ONECLICK except than the shopper doesn't need to enter the CVC */
const (
	ONECLICK  = "ONECLICK"
	RECURRING = "RECURRING"
)

// AuthoriseEncrypted structure for Authorisation request (with encrypted card information)
type AuthoriseEncrypted struct {
	AdditionalData  *AdditionalData `json:"additionalData"`
	Amount          *Amount         `json:"amount"`
	Reference       string          `json:"reference"`
	MerchantAccount string          `json:"merchantAccount"`
	// Mandatory for recurring payment
	ShopperReference string     `json:"shopperReference,omitempty"`
	Recurring        *Recurring `json:"recurring,omitempty"`
	// Required for a 3DS process
	BrowserInfo *BrowserInfo `json:"browserInfo,omitempty"`
}

// Authorise structure for Authorisation request (card is not encrypted)
type Authorise struct {
	Card            *Card   `json:"card"`
	Amount          *Amount `json:"amount"`
	Reference       string  `json:"reference"`
	MerchantAccount string  `json:"merchantAccount"`
	// Mandatory for recurring payment
	ShopperReference string     `json:"shopperReference,omitempty"`
	Recurring        *Recurring `json:"recurring,omitempty"`
	// Required for a 3DS process
	BrowserInfo *BrowserInfo `json:"browserInfo,omitempty"`
}

// AuthoriseResponse is a response structure for Adyen
type AuthoriseResponse struct {
	PspReference  string `json:"pspReference"`
	ResultCode    string `json:"resultCode"`
	AuthCode      string `json:"authCode"`
	RefusalReason string `json:"refusalReason"`
	IssuerURL     string `json:"issuerUrl"`
	MD            string `json:"md"`
	PaRequest     string `json:"paRequest"`
}

// AdditionalData stores encrypted information about customer's credit card
type AdditionalData struct {
	Content string `json:"card.encrypted.json"`
}

// BrowserInfo hold information on the user browser
type BrowserInfo struct {
	AcceptHeader string `json:"acceptHeader"`
	UserAgent    string `json:"userAgent"`
}

// Recurring hold the behavior for a future payment : could be ONECLICK or RECURRING
type Recurring struct {
	Contract string `json:"contract"`
}
<commit_msg>Add new fields and const to allow a recurring authorisation request<commit_after>package adyen

/* One-click functionality gives the shopper the option to store their payment details with the merchant, within the Adyen environment. In this type of transaction, the shopper needs to enter the CVC code for the transaction to get through.
Same than for ONECLICK except than the shopper doesn't need to enter the CVC */
const (
	ONECLICK                                 = "ONECLICK"
	RECURRING                                = "RECURRING"
	SHOPPER_INTERACTION_CONTAUTH             = "ContAuth"
	SELECT_RECURRING_DETAIL_REFERENCE_LATEST = "LATEST"
)

// AuthoriseEncrypted structure for Authorisation request (with encrypted card information)
type AuthoriseEncrypted struct {
	AdditionalData  *AdditionalData `json:"additionalData,omitempty"`
	Amount          *Amount         `json:"amount"`
	Reference       string          `json:"reference"`
	MerchantAccount string          `json:"merchantAccount"`
	// Mandatory for recurring payment
	ShopperReference                 string     `json:"shopperReference,omitempty"`
	Recurring                        *Recurring `json:"recurring,omitempty"`
	ShopperInteraction               string     `json:"shopperInteraction,omitempty"`
	SelectedRecurringDetailReference string     `json:"selectedRecurringDetailReference,omitempty"`
	// Required for a 3DS process
	BrowserInfo *BrowserInfo `json:"browserInfo,omitempty"`
}

// Authorise structure for Authorisation request (card is not encrypted)
type Authorise struct {
	Card            *Card   `json:"card,omitempty"`
	Amount          *Amount `json:"amount"`
	Reference       string  `json:"reference"`
	MerchantAccount string  `json:"merchantAccount"`
	// Mandatory for recurring payment
	ShopperReference                 string     `json:"shopperReference,omitempty"`
	Recurring                        *Recurring `json:"recurring,omitempty"`
	ShopperInteraction               string     `json:"shopperInteraction,omitempty"`
	SelectedRecurringDetailReference string     `json:"selectedRecurringDetailReference,omitempty"`
	// Required for a 3DS process
	BrowserInfo *BrowserInfo `json:"browserInfo,omitempty"`
}

// AuthoriseResponse is a response structure for Adyen
type AuthoriseResponse struct {
	PspReference  string `json:"pspReference"`
	ResultCode    string `json:"resultCode"`
	AuthCode      string `json:"authCode"`
	RefusalReason string `json:"refusalReason"`
	IssuerURL     string `json:"issuerUrl"`
	MD            string `json:"md"`
	PaRequest     string `json:"paRequest"`
}

// AdditionalData stores encrypted information about customer's credit card
type AdditionalData struct {
	Content string `json:"card.encrypted.json"`
}

// BrowserInfo hold information on the user browser
type BrowserInfo struct {
	AcceptHeader string `json:"acceptHeader"`
	UserAgent    string `json:"userAgent"`
}

// Recurring hold the behavior for a future payment : could be ONECLICK or RECURRING
type Recurring struct {
	Contract string `json:"contract"`
}
<|endoftext|>


<commit_before>package main

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha1"
	"crypto/x509"
	"encoding/json"
	"encoding/pem"
	"errors"
	"flag"
	"fmt"
	"go/scanner"
	"io"
	"io/ioutil"
	"math"
	"os"
	"time"

	"github.com/howeyc/gopass"
)

const filechunk = 8192

const (
	rsaPrivateKeyPEMBlockType = "RSA PRIVATE KEY"
)

var (
	file     = flag.String("f", "file.tar.gz", "the file to sign")
	key      = flag.String("k", "key.pem", "the private key to use when signing")
	product  = flag.String("p", "", "the name of the product in the file (if applicable)")
	company  = flag.String("c", "", "the name of the signing organization")
	exitCode = 0
)

type Manifest struct {
	Company     string `json:",omitempty"`
	Product     string `json:",omitempty"`
	PackageName string
	PackageSha1 string // use string so value easy to compare with shasum output
	ReleaseDate time.Time
	Signature   []byte `json:",omitempty"`
}

func usage() {
	fmt.Fprintf(os.Stderr, "\nusage: pkgsign -f [path] -k [path]\n")
	flag.PrintDefaults()
	fmt.Fprintf(os.Stderr, "\n")
	os.Exit(2)
}

func report(err error) {
	scanner.PrintError(os.Stderr, err)
	exitCode = 2
}

func main() {
	pkgSignMain()
	os.Exit(exitCode)
}

func pkgSignMain() {
	flag.Usage = usage
	flag.Parse()

	// open the file to sign and calculate the file's Sha1
	fileToSign, err := os.Open(*file)
	if err != nil {
		report(err)
		return
	}
	defer fileToSign.Close()
	pkgSha1 := calcSha(fileToSign)

	// build the manifest object
	manifest := Manifest{
		Company:     *company,
		Product:     *product,
		PackageName: fileToSign.Name(),
		PackageSha1: fmt.Sprintf("%x", pkgSha1),
		ReleaseDate: time.Now(),
	}

	// open the key, parse it and decrypt it (if needed)
	keyBytes, err := ioutil.ReadFile(*key)
	if err != nil {
		report(err)
		return
	}
	privKey, err := loadKey(keyBytes, askPassPhrase())
	if err != nil {
		report(err)
		return
	}

	// sign the manifest and write it to disk
	manBytes, err := signManifest(manifest, privKey)
	if err != nil {
		report(err)
		return
	}
	err = ioutil.WriteFile(fileToSign.Name()+".manifest", manBytes, 0777)
	if err != nil {
		report(err)
		return
	}

	fmt.Printf("Signed manifest written to %s\n", fileToSign.Name()+".manifest")
	return
}

func signManifest(manifest Manifest, privKey *rsa.PrivateKey) ([]byte, error) {
	// marshal the manifest (without the signature field set)
	manifestToSign, err := json.Marshal(manifest)
	if err != nil {
		return nil, err
	}

	// calculate the Sha1 of the manifest bytes
	var h crypto.Hash
	manifestSha1 := sha1.New()
	manifestSha1.Write(manifestToSign)
	manShaVal := manifestSha1.Sum(nil)

	// calculate the signature of the manifest
	sig, err := rsa.SignPKCS1v15(rand.Reader, privKey, h, manShaVal)
	if err != nil {
		return nil, err
	}

	// set the Signature field of the manifest
	manifest.Signature = sig

	// marshal the manifest with signature
	return json.Marshal(manifest)
}

func calcSha(fileToSign *os.File) []byte {
	info, _ := fileToSign.Stat()
	filesize := info.Size()
	blocks := uint64(math.Ceil(float64(filesize) / float64(filechunk)))
	hash := sha1.New()
	for i := uint64(0); i < blocks; i++ {
		blocksize := int(math.Min(filechunk, float64(filesize-int64(i*filechunk))))
		buf := make([]byte, blocksize)
		fileToSign.Read(buf)
		io.WriteString(hash, string(buf))
	}
	return hash.Sum(nil)
}

func loadKey(keyBytes, passphrase []byte) (*rsa.PrivateKey, error) {
	pemBlock, _ := pem.Decode(keyBytes)
	if pemBlock == nil {
		return nil, errors.New("cannot find the next PEM formatted block")
	}
	if pemBlock.Type != rsaPrivateKeyPEMBlockType {
		return nil, errors.New("unmatched type or headers")
	}

	return parseKey(pemBlock, passphrase)
}

func parseKey(block *pem.Block, passphrase []byte) (*rsa.PrivateKey, error) {
	var blockBytes []byte
	if x509.IsEncryptedPEMBlock(block) {
		b, err := x509.DecryptPEMBlock(block, passphrase)
		if err != nil {
			return nil, err
		}
		blockBytes = b
	} else {
		blockBytes = block.Bytes
	}
	return x509.ParsePKCS1PrivateKey(blockBytes)
}

func askPassPhrase() []byte {
	fmt.Fprint(os.Stderr, "Enter passphrase (empty for no passphrase): ")
	pass := gopass.GetPasswd()
	fmt.Fprintln(os.Stderr)
	return pass
}
<commit_msg>verify cmd line args present<commit_after>package main

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha1"
	"crypto/x509"
	"encoding/json"
	"encoding/pem"
	"errors"
	"flag"
	"fmt"
	"go/scanner"
	"io"
	"io/ioutil"
	"math"
	"os"
	"time"

	"github.com/howeyc/gopass"
)

const filechunk = 8192

const (
	rsaPrivateKeyPEMBlockType = "RSA PRIVATE KEY"
)

var (
	file     = flag.String("f", "", "the file to sign")
	key      = flag.String("k", "", "the private key to use when signing")
	product  = flag.String("p", "", "the name of the product in the file (if applicable)")
	company  = flag.String("c", "", "the name of the signing organization")
	exitCode = 0
)

type Manifest struct {
	Company     string `json:",omitempty"`
	Product     string `json:",omitempty"`
	PackageName string
	PackageSha1 string // use string so value easy to compare with shasum output
	ReleaseDate time.Time
	Signature   []byte `json:",omitempty"`
}

func usage() {
	fmt.Fprintf(os.Stderr, "\nusage: pkgsign -f [path] -k [path]\n")
	flag.PrintDefaults()
	fmt.Fprintf(os.Stderr, "\n")
	os.Exit(2)
}

func report(err error) {
	scanner.PrintError(os.Stderr, err)
	exitCode = 2
}

func main() {
	pkgSignMain()
	os.Exit(exitCode)
}

func pkgSignMain() {
	flag.Usage = usage
	flag.Parse()

	if *file == "" || *key == "" {
		usage()
	}

	// open the file to sign and calculate the file's Sha1
	fileToSign, err := os.Open(*file)
	if err != nil {
		report(err)
		return
	}
	defer fileToSign.Close()
	pkgSha1 := calcSha(fileToSign)

	// build the manifest object
	manifest := Manifest{
		Company:     *company,
		Product:     *product,
		PackageName: fileToSign.Name(),
		PackageSha1: fmt.Sprintf("%x", pkgSha1),
		ReleaseDate: time.Now(),
	}

	// open the key, parse it and decrypt it (if needed)
	keyBytes, err := ioutil.ReadFile(*key)
	if err != nil {
		report(err)
		return
	}
	privKey, err := loadKey(keyBytes, askPassPhrase())
	if err != nil {
		report(err)
		return
	}

	// sign the manifest and write it to disk
	manBytes, err := signManifest(manifest, privKey)
	if err != nil {
		report(err)
		return
	}
	err = ioutil.WriteFile(fileToSign.Name()+".manifest", manBytes, 0777)
	if err != nil {
		report(err)
		return
	}

	fmt.Printf("Signed manifest written to %s\n", fileToSign.Name()+".manifest")
	return
}

func signManifest(manifest Manifest, privKey *rsa.PrivateKey) ([]byte, error) {
	// marshal the manifest (without the signature field set)
	manifestToSign, err := json.Marshal(manifest)
	if err != nil {
		return nil, err
	}

	// calculate the Sha1 of the manifest bytes
	var h crypto.Hash
	manifestSha1 := sha1.New()
	manifestSha1.Write(manifestToSign)
	manShaVal := manifestSha1.Sum(nil)

	// calculate the signature of the manifest
	sig, err := rsa.SignPKCS1v15(rand.Reader, privKey, h, manShaVal)
	if err != nil {
		return nil, err
	}

	// set the Signature field of the manifest
	manifest.Signature = sig

	// marshal the manifest with signature
	return json.Marshal(manifest)
}

func calcSha(fileToSign *os.File) []byte {
	info, _ := fileToSign.Stat()
	filesize := info.Size()
	blocks := uint64(math.Ceil(float64(filesize) / float64(filechunk)))
	hash := sha1.New()
	for i := uint64(0); i < blocks; i++ {
		blocksize := int(math.Min(filechunk, float64(filesize-int64(i*filechunk))))
		buf := make([]byte, blocksize)
		fileToSign.Read(buf)
		io.WriteString(hash, string(buf))
	}
	return hash.Sum(nil)
}

func loadKey(keyBytes, passphrase []byte) (*rsa.PrivateKey, error) {
	pemBlock, _ := pem.Decode(keyBytes)
	if pemBlock == nil {
		return nil, errors.New("cannot find the next PEM formatted block")
	}
	if pemBlock.Type != rsaPrivateKeyPEMBlockType {
		return nil, errors.New("unmatched type or headers")
	}

	return parseKey(pemBlock, passphrase)
}

func parseKey(block *pem.Block, passphrase []byte) (*rsa.PrivateKey, error) {
	var blockBytes []byte
	if x509.IsEncryptedPEMBlock(block) {
		b, err := x509.DecryptPEMBlock(block, passphrase)
		if err != nil {
			return nil, err
		}
		blockBytes = b
	} else {
		blockBytes = block.Bytes
	}
	return x509.ParsePKCS1PrivateKey(blockBytes)
}

func askPassPhrase() []byte {
	fmt.Fprint(os.Stderr, "Enter passphrase (empty for no passphrase): ")
	pass := gopass.GetPasswd()
	fmt.Fprintln(os.Stderr)
	return pass
}
<|endoftext|>