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

package ring

import (
	"fmt"
	"testing"
)

// For debugging - keep around.
func dump(r *Ring) {
	if r == nil {
		fmt.Println("empty")
		return
	}
	i, n := 0, r.Len()
	for p := r; i < n; p = p.next {
		fmt.Printf("%4d: %p = {<- %p | %p ->}\n", i, p, p.prev, p.next)
		i++
	}
	fmt.Println()
}

func verify(t *testing.T, r *Ring, N int, sum int) {
	// Len
	n := r.Len()
	if n != N {
		t.Errorf("r.Len() == %d; expected %d", n, N)
	}

	// iteration
	n = 0
	s := 0
	r.Do(func(p interface{}) {
		n++
		if p != nil {
			s += p.(int)
		}
	})
	if n != N {
		t.Errorf("number of forward iterations == %d; expected %d", n, N)
	}
	if sum >= 0 && s != sum {
		t.Errorf("forward ring sum = %d; expected %d", s, sum)
	}

	if r == nil {
		return
	}

	// connections
	if r.next != nil {
		var p *Ring // previous element
		for q := r; p == nil || q != r; q = q.next {
			if p != nil && p != q.prev {
				t.Errorf("prev = %p, expected q.prev = %p\n", p, q.prev)
			}
			p = q
		}
		if p != r.prev {
			t.Errorf("prev = %p, expected r.prev = %p\n", p, r.prev)
		}
	}

	// Next, Prev
	if r.Next() != r.next {
		t.Errorf("r.Next() != r.next")
	}
	if r.Prev() != r.prev {
		t.Errorf("r.Prev() != r.prev")
	}

	// Move
	if r.Move(0) != r {
		t.Errorf("r.Move(0) != r")
	}
	if r.Move(N) != r {
		t.Errorf("r.Move(%d) != r", N)
	}
	if r.Move(-N) != r {
		t.Errorf("r.Move(%d) != r", -N)
	}
	for i := 0; i < 10; i++ {
		ni := N + i
		mi := ni % N
		if r.Move(ni) != r.Move(mi) {
			t.Errorf("r.Move(%d) != r.Move(%d)", ni, mi)
		}
		if r.Move(-ni) != r.Move(-mi) {
			t.Errorf("r.Move(%d) != r.Move(%d)", -ni, -mi)
		}
	}
}

func TestCornerCases(t *testing.T) {
	var (
		r0 *Ring
		r1 Ring
	)
	// Basics
	verify(t, r0, 0, 0)
	verify(t, &r1, 1, 0)
	// Insert
	r1.Link(r0)
	verify(t, r0, 0, 0)
	verify(t, &r1, 1, 0)
	// Insert
	r1.Link(r0)
	verify(t, r0, 0, 0)
	verify(t, &r1, 1, 0)
	// Unlink
	r1.Unlink(0)
	verify(t, &r1, 1, 0)
}

func makeN(n int) *Ring {
	r := New(n)
	for i := 1; i <= n; i++ {
		r.Value = i
		r = r.Next()
	}
	return r
}

func sumN(n int) int { return (n*n + n) / 2 }

func TestNew(t *testing.T) {
	for i := 0; i < 10; i++ {
		r := New(i)
		verify(t, r, i, -1)
	}
	for i := 0; i < 10; i++ {
		r := makeN(i)
		verify(t, r, i, sumN(i))
	}
}

func TestLink1(t *testing.T) {
	r1a := makeN(1)
	var r1b Ring
	r2a := r1a.Link(&r1b)
	verify(t, r2a, 2, 1)
	if r2a != r1a {
		t.Errorf("a) 2-element link failed")
	}

	r2b := r2a.Link(r2a.Next())
	verify(t, r2b, 2, 1)
	if r2b != r2a.Next() {
		t.Errorf("b) 2-element link failed")
	}

	r1c := r2b.Link(r2b)
	verify(t, r1c, 1, 1)
	verify(t, r2b, 1, 0)
}

func TestLink2(t *testing.T) {
	var r0 *Ring
	r1a := &Ring{Value: 42}
	r1b := &Ring{Value: 77}
	r10 := makeN(10)

	r1a.Link(r0)
	verify(t, r1a, 1, 42)

	r1a.Link(r1b)
	verify(t, r1a, 2, 42+77)

	r10.Link(r0)
	verify(t, r10, 10, sumN(10))

	r10.Link(r1a)
	verify(t, r10, 12, sumN(10)+42+77)
}

func TestLink3(t *testing.T) {
	var r Ring
	n := 1
	for i := 1; i < 100; i++ {
		n += i
		verify(t, r.Link(New(i)), n, -1)
	}
}

func TestUnlink(t *testing.T) {
	r10 := makeN(10)
	s10 := r10.Move(6)

	sum10 := sumN(10)

	verify(t, r10, 10, sum10)
	verify(t, s10, 10, sum10)

	r0 := r10.Unlink(0)
	verify(t, r0, 0, 0)

	r1 := r10.Unlink(1)
	verify(t, r1, 1, 2)
	verify(t, r10, 9, sum10-2)

	r9 := r10.Unlink(9)
	verify(t, r9, 9, sum10-2)
	verify(t, r10, 9, sum10-2)
}

func TestLinkUnlink(t *testing.T) {
	for i := 1; i < 4; i++ {
		ri := New(i)
		for j := 0; j < i; j++ {
			rj := ri.Unlink(j)
			verify(t, rj, j, -1)
			verify(t, ri, i-j, -1)
			ri.Link(rj)
			verify(t, ri, i, -1)
		}
	}
}
<commit_msg>container/ring: add test for Move with empty Ring<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package ring

import (
	"fmt"
	"testing"
)

// For debugging - keep around.
func dump(r *Ring) {
	if r == nil {
		fmt.Println("empty")
		return
	}
	i, n := 0, r.Len()
	for p := r; i < n; p = p.next {
		fmt.Printf("%4d: %p = {<- %p | %p ->}\n", i, p, p.prev, p.next)
		i++
	}
	fmt.Println()
}

func verify(t *testing.T, r *Ring, N int, sum int) {
	// Len
	n := r.Len()
	if n != N {
		t.Errorf("r.Len() == %d; expected %d", n, N)
	}

	// iteration
	n = 0
	s := 0
	r.Do(func(p interface{}) {
		n++
		if p != nil {
			s += p.(int)
		}
	})
	if n != N {
		t.Errorf("number of forward iterations == %d; expected %d", n, N)
	}
	if sum >= 0 && s != sum {
		t.Errorf("forward ring sum = %d; expected %d", s, sum)
	}

	if r == nil {
		return
	}

	// connections
	if r.next != nil {
		var p *Ring // previous element
		for q := r; p == nil || q != r; q = q.next {
			if p != nil && p != q.prev {
				t.Errorf("prev = %p, expected q.prev = %p\n", p, q.prev)
			}
			p = q
		}
		if p != r.prev {
			t.Errorf("prev = %p, expected r.prev = %p\n", p, r.prev)
		}
	}

	// Next, Prev
	if r.Next() != r.next {
		t.Errorf("r.Next() != r.next")
	}
	if r.Prev() != r.prev {
		t.Errorf("r.Prev() != r.prev")
	}

	// Move
	if r.Move(0) != r {
		t.Errorf("r.Move(0) != r")
	}
	if r.Move(N) != r {
		t.Errorf("r.Move(%d) != r", N)
	}
	if r.Move(-N) != r {
		t.Errorf("r.Move(%d) != r", -N)
	}
	for i := 0; i < 10; i++ {
		ni := N + i
		mi := ni % N
		if r.Move(ni) != r.Move(mi) {
			t.Errorf("r.Move(%d) != r.Move(%d)", ni, mi)
		}
		if r.Move(-ni) != r.Move(-mi) {
			t.Errorf("r.Move(%d) != r.Move(%d)", -ni, -mi)
		}
	}
}

func TestCornerCases(t *testing.T) {
	var (
		r0 *Ring
		r1 Ring
	)
	// Basics
	verify(t, r0, 0, 0)
	verify(t, &r1, 1, 0)
	// Insert
	r1.Link(r0)
	verify(t, r0, 0, 0)
	verify(t, &r1, 1, 0)
	// Insert
	r1.Link(r0)
	verify(t, r0, 0, 0)
	verify(t, &r1, 1, 0)
	// Unlink
	r1.Unlink(0)
	verify(t, &r1, 1, 0)
}

func makeN(n int) *Ring {
	r := New(n)
	for i := 1; i <= n; i++ {
		r.Value = i
		r = r.Next()
	}
	return r
}

func sumN(n int) int { return (n*n + n) / 2 }

func TestNew(t *testing.T) {
	for i := 0; i < 10; i++ {
		r := New(i)
		verify(t, r, i, -1)
	}
	for i := 0; i < 10; i++ {
		r := makeN(i)
		verify(t, r, i, sumN(i))
	}
}

func TestLink1(t *testing.T) {
	r1a := makeN(1)
	var r1b Ring
	r2a := r1a.Link(&r1b)
	verify(t, r2a, 2, 1)
	if r2a != r1a {
		t.Errorf("a) 2-element link failed")
	}

	r2b := r2a.Link(r2a.Next())
	verify(t, r2b, 2, 1)
	if r2b != r2a.Next() {
		t.Errorf("b) 2-element link failed")
	}

	r1c := r2b.Link(r2b)
	verify(t, r1c, 1, 1)
	verify(t, r2b, 1, 0)
}

func TestLink2(t *testing.T) {
	var r0 *Ring
	r1a := &Ring{Value: 42}
	r1b := &Ring{Value: 77}
	r10 := makeN(10)

	r1a.Link(r0)
	verify(t, r1a, 1, 42)

	r1a.Link(r1b)
	verify(t, r1a, 2, 42+77)

	r10.Link(r0)
	verify(t, r10, 10, sumN(10))

	r10.Link(r1a)
	verify(t, r10, 12, sumN(10)+42+77)
}

func TestLink3(t *testing.T) {
	var r Ring
	n := 1
	for i := 1; i < 100; i++ {
		n += i
		verify(t, r.Link(New(i)), n, -1)
	}
}

func TestUnlink(t *testing.T) {
	r10 := makeN(10)
	s10 := r10.Move(6)

	sum10 := sumN(10)

	verify(t, r10, 10, sum10)
	verify(t, s10, 10, sum10)

	r0 := r10.Unlink(0)
	verify(t, r0, 0, 0)

	r1 := r10.Unlink(1)
	verify(t, r1, 1, 2)
	verify(t, r10, 9, sum10-2)

	r9 := r10.Unlink(9)
	verify(t, r9, 9, sum10-2)
	verify(t, r10, 9, sum10-2)
}

func TestLinkUnlink(t *testing.T) {
	for i := 1; i < 4; i++ {
		ri := New(i)
		for j := 0; j < i; j++ {
			rj := ri.Unlink(j)
			verify(t, rj, j, -1)
			verify(t, ri, i-j, -1)
			ri.Link(rj)
			verify(t, ri, i, -1)
		}
	}
}

// Test that calling Move() on an empty Ring initializes it.
func TestMoveEmptyRing(t *testing.T) {
	var r Ring

	r.Move(1)
	verify(t, &r, 1, 0)
}
<|endoftext|>


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

package plan9obj

import (
	"reflect"
	"testing"
)

type fileTest struct {
	file     string
	hdr      FileHeader
	sections []*SectionHeader
}

var fileTests = []fileTest{
	{
		"testdata/386-plan9-exec",
		FileHeader{Magic386, 0x324, 0x14, 4},
		[]*SectionHeader{
			{"text", 0x4c5f, 0x20},
			{"data", 0x94c, 0x4c7f},
			{"syms", 0x2c2b, 0x55cb},
			{"spsz", 0x0, 0x81f6},
			{"pcsz", 0xf7a, 0x81f6},
		},
	},
	{
		"testdata/amd64-plan9-exec",
		FileHeader{MagicAMD64, 0x618, 0x13, 8},
		[]*SectionHeader{
			{"text", 0x4213, 0x28},
			{"data", 0xa80, 0x423b},
			{"syms", 0x2c8c, 0x4cbb},
			{"spsz", 0x0, 0x7947},
			{"pcsz", 0xca0, 0x7947},
		},
	},
}

func TestOpen(t *testing.T) {
	for i := range fileTests {
		tt := &fileTests[i]

		f, err := Open(tt.file)
		if err != nil {
			t.Error(err)
			continue
		}
		if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
			continue
		}

		for i, sh := range f.Sections {
			if i >= len(tt.sections) {
				break
			}
			have := &sh.SectionHeader
			want := tt.sections[i]
			if !reflect.DeepEqual(have, want) {
				t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
			}
		}
		tn := len(tt.sections)
		fn := len(f.Sections)
		if tn != fn {
			t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
		}
	}
}

func TestOpenFailure(t *testing.T) {
	filename := "file.go"    // not a Plan 9 a.out file
	_, err := Open(filename) // don't crash
	if err == nil {
		t.Errorf("open %s: succeeded unexpectedly", filename)
	}
}
<commit_msg>debug/plan9obj: fix test build<commit_after>// Copyright 2014 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package plan9obj

import (
	"reflect"
	"testing"
)

type fileTest struct {
	file     string
	hdr      FileHeader
	sections []*SectionHeader
}

var fileTests = []fileTest{
	{
		"testdata/386-plan9-exec",
		FileHeader{Magic386, 0x324, 0x14, 4, 0x1000, 32},
		[]*SectionHeader{
			{"text", 0x4c5f, 0x20},
			{"data", 0x94c, 0x4c7f},
			{"syms", 0x2c2b, 0x55cb},
			{"spsz", 0x0, 0x81f6},
			{"pcsz", 0xf7a, 0x81f6},
		},
	},
	{
		"testdata/amd64-plan9-exec",
		FileHeader{MagicAMD64, 0x618, 0x13, 8, 0x200000, 40},
		[]*SectionHeader{
			{"text", 0x4213, 0x28},
			{"data", 0xa80, 0x423b},
			{"syms", 0x2c8c, 0x4cbb},
			{"spsz", 0x0, 0x7947},
			{"pcsz", 0xca0, 0x7947},
		},
	},
}

func TestOpen(t *testing.T) {
	for i := range fileTests {
		tt := &fileTests[i]

		f, err := Open(tt.file)
		if err != nil {
			t.Error(err)
			continue
		}
		if !reflect.DeepEqual(f.FileHeader, tt.hdr) {
			t.Errorf("open %s:\n\thave %#v\n\twant %#v\n", tt.file, f.FileHeader, tt.hdr)
			continue
		}

		for i, sh := range f.Sections {
			if i >= len(tt.sections) {
				break
			}
			have := &sh.SectionHeader
			want := tt.sections[i]
			if !reflect.DeepEqual(have, want) {
				t.Errorf("open %s, section %d:\n\thave %#v\n\twant %#v\n", tt.file, i, have, want)
			}
		}
		tn := len(tt.sections)
		fn := len(f.Sections)
		if tn != fn {
			t.Errorf("open %s: len(Sections) = %d, want %d", tt.file, fn, tn)
		}
	}
}

func TestOpenFailure(t *testing.T) {
	filename := "file.go"    // not a Plan 9 a.out file
	_, err := Open(filename) // don't crash
	if err == nil {
		t.Errorf("open %s: succeeded unexpectedly", filename)
	}
}
<|endoftext|>


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

package utf16_test

import (
	"reflect"
	"testing"
	"unicode"
	. "unicode/utf16"
)

// Validate the constants redefined from unicode.
func TestConstants(t *testing.T) {
	if MaxRune != unicode.MaxRune {
		t.Errorf("utf16.maxRune is wrong: %x should be %x", MaxRune, unicode.MaxRune)
	}
	if ReplacementChar != unicode.ReplacementChar {
		t.Errorf("utf16.replacementChar is wrong: %x should be %x", ReplacementChar, unicode.ReplacementChar)
	}
}

type encodeTest struct {
	in  []rune
	out []uint16
}

var encodeTests = []encodeTest{
	{[]rune{1, 2, 3, 4}, []uint16{1, 2, 3, 4}},
	{[]rune{0xffff, 0x10000, 0x10001, 0x12345, 0x10ffff},
		[]uint16{0xffff, 0xd800, 0xdc00, 0xd800, 0xdc01, 0xd808, 0xdf45, 0xdbff, 0xdfff}},
	{[]rune{'a', 'b', 0xd7ff, 0xd800, 0xdfff, 0xe000, 0x110000, -1},
		[]uint16{'a', 'b', 0xd7ff, 0xfffd, 0xfffd, 0xe000, 0xfffd, 0xfffd}},
}

func TestEncode(t *testing.T) {
	for _, tt := range encodeTests {
		out := Encode(tt.in)
		if !reflect.DeepEqual(out, tt.out) {
			t.Errorf("Encode(%x) = %x; want %x", tt.in, out, tt.out)
		}
	}
}

func TestEncodeRune(t *testing.T) {
	for i, tt := range encodeTests {
		j := 0
		for _, r := range tt.in {
			r1, r2 := EncodeRune(r)
			if r < 0x10000 || r > unicode.MaxRune {
				if j >= len(tt.out) {
					t.Errorf("#%d: ran out of tt.out", i)
					break
				}
				if r1 != unicode.ReplacementChar || r2 != unicode.ReplacementChar {
					t.Errorf("EncodeRune(%#x) = %#x, %#x; want 0xfffd, 0xfffd", r, r1, r2)
				}
				j++
			} else {
				if j+1 >= len(tt.out) {
					t.Errorf("#%d: ran out of tt.out", i)
					break
				}
				if r1 != rune(tt.out[j]) || r2 != rune(tt.out[j+1]) {
					t.Errorf("EncodeRune(%#x) = %#x, %#x; want %#x, %#x", r, r1, r2, tt.out[j], tt.out[j+1])
				}
				j += 2
				dec := DecodeRune(r1, r2)
				if dec != r {
					t.Errorf("DecodeRune(%#x, %#x) = %#x; want %#x", r1, r2, dec, r)
				}
			}
		}
		if j != len(tt.out) {
			t.Errorf("#%d: EncodeRune didn't generate enough output", i)
		}
	}
}

type decodeTest struct {
	in  []uint16
	out []rune
}

var decodeTests = []decodeTest{
	{[]uint16{1, 2, 3, 4}, []rune{1, 2, 3, 4}},
	{[]uint16{0xffff, 0xd800, 0xdc00, 0xd800, 0xdc01, 0xd808, 0xdf45, 0xdbff, 0xdfff},
		[]rune{0xffff, 0x10000, 0x10001, 0x12345, 0x10ffff}},
	{[]uint16{0xd800, 'a'}, []rune{0xfffd, 'a'}},
	{[]uint16{0xdfff}, []rune{0xfffd}},
}

func TestDecode(t *testing.T) {
	for _, tt := range decodeTests {
		out := Decode(tt.in)
		if !reflect.DeepEqual(out, tt.out) {
			t.Errorf("Decode(%x) = %x; want %x", tt.in, out, tt.out)
		}
	}
}
<commit_msg>unicode/utf16: add explicit tests for IsSurrogate<commit_after>// Copyright 2010 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package utf16_test

import (
	"reflect"
	"testing"
	"unicode"
	. "unicode/utf16"
)

// Validate the constants redefined from unicode.
func TestConstants(t *testing.T) {
	if MaxRune != unicode.MaxRune {
		t.Errorf("utf16.maxRune is wrong: %x should be %x", MaxRune, unicode.MaxRune)
	}
	if ReplacementChar != unicode.ReplacementChar {
		t.Errorf("utf16.replacementChar is wrong: %x should be %x", ReplacementChar, unicode.ReplacementChar)
	}
}

type encodeTest struct {
	in  []rune
	out []uint16
}

var encodeTests = []encodeTest{
	{[]rune{1, 2, 3, 4}, []uint16{1, 2, 3, 4}},
	{[]rune{0xffff, 0x10000, 0x10001, 0x12345, 0x10ffff},
		[]uint16{0xffff, 0xd800, 0xdc00, 0xd800, 0xdc01, 0xd808, 0xdf45, 0xdbff, 0xdfff}},
	{[]rune{'a', 'b', 0xd7ff, 0xd800, 0xdfff, 0xe000, 0x110000, -1},
		[]uint16{'a', 'b', 0xd7ff, 0xfffd, 0xfffd, 0xe000, 0xfffd, 0xfffd}},
}

func TestEncode(t *testing.T) {
	for _, tt := range encodeTests {
		out := Encode(tt.in)
		if !reflect.DeepEqual(out, tt.out) {
			t.Errorf("Encode(%x) = %x; want %x", tt.in, out, tt.out)
		}
	}
}

func TestEncodeRune(t *testing.T) {
	for i, tt := range encodeTests {
		j := 0
		for _, r := range tt.in {
			r1, r2 := EncodeRune(r)
			if r < 0x10000 || r > unicode.MaxRune {
				if j >= len(tt.out) {
					t.Errorf("#%d: ran out of tt.out", i)
					break
				}
				if r1 != unicode.ReplacementChar || r2 != unicode.ReplacementChar {
					t.Errorf("EncodeRune(%#x) = %#x, %#x; want 0xfffd, 0xfffd", r, r1, r2)
				}
				j++
			} else {
				if j+1 >= len(tt.out) {
					t.Errorf("#%d: ran out of tt.out", i)
					break
				}
				if r1 != rune(tt.out[j]) || r2 != rune(tt.out[j+1]) {
					t.Errorf("EncodeRune(%#x) = %#x, %#x; want %#x, %#x", r, r1, r2, tt.out[j], tt.out[j+1])
				}
				j += 2
				dec := DecodeRune(r1, r2)
				if dec != r {
					t.Errorf("DecodeRune(%#x, %#x) = %#x; want %#x", r1, r2, dec, r)
				}
			}
		}
		if j != len(tt.out) {
			t.Errorf("#%d: EncodeRune didn't generate enough output", i)
		}
	}
}

type decodeTest struct {
	in  []uint16
	out []rune
}

var decodeTests = []decodeTest{
	{[]uint16{1, 2, 3, 4}, []rune{1, 2, 3, 4}},
	{[]uint16{0xffff, 0xd800, 0xdc00, 0xd800, 0xdc01, 0xd808, 0xdf45, 0xdbff, 0xdfff},
		[]rune{0xffff, 0x10000, 0x10001, 0x12345, 0x10ffff}},
	{[]uint16{0xd800, 'a'}, []rune{0xfffd, 'a'}},
	{[]uint16{0xdfff}, []rune{0xfffd}},
}

func TestDecode(t *testing.T) {
	for _, tt := range decodeTests {
		out := Decode(tt.in)
		if !reflect.DeepEqual(out, tt.out) {
			t.Errorf("Decode(%x) = %x; want %x", tt.in, out, tt.out)
		}
	}
}

var surrogateTests = []struct {
	r    rune
	want bool
}{
	// from http://en.wikipedia.org/wiki/UTF-16
	{'\u007A', false},     // LATIN SMALL LETTER Z
	{'\u6C34', false},     // CJK UNIFIED IDEOGRAPH-6C34 (water)
	{'\uFEFF', false},     // Byte Order Mark
	{'\U00010000', false}, // LINEAR B SYLLABLE B008 A (first non-BMP code point)
	{'\U0001D11E', false}, // MUSICAL SYMBOL G CLEF
	{'\U0010FFFD', false}, // PRIVATE USE CHARACTER-10FFFD (last Unicode code point)

	{rune(0xd7ff), false}, // surr1-1
	{rune(0xd800), true},  // surr1
	{rune(0xdc00), true},  // surr2
	{rune(0xe000), false}, // surr3
	{rune(0xdfff), true},  // surr3-1
}

func TestIsSurrogate(t *testing.T) {
	for i, tt := range surrogateTests {
		got := IsSurrogate(tt.r)
		if got != tt.want {
			t.Errorf("%d: IsSurrogate(%q) = %v; want %v", i, tt.r, got, tt.want)
		}
	}
}
<|endoftext|>


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

package websocket

import (
	"bufio"
	"bytes"
	"fmt"
	"http"
	"io"
	"log"
	"net"
	"sync"
	"testing"
)

var serverAddr string
var once sync.Once

func echoServer(ws *Conn) { io.Copy(ws, ws) }

func startServer() {
	l, e := net.Listen("tcp", "127.0.0.1:0") // any available address
	if e != nil {
		log.Fatalf("net.Listen tcp :0 %v", e)
	}
	serverAddr = l.Addr().String()
	log.Print("Test WebSocket server listening on ", serverAddr)
	http.Handle("/echo", Handler(echoServer))
	http.Handle("/echoDraft75", Draft75Handler(echoServer))
	go http.Serve(l, nil)
}

// Test the getChallengeResponse function with values from section
// 5.1 of the specification steps 18, 26, and 43 from
// http://www.whatwg.org/specs/web-socket-protocol/
func TestChallenge(t *testing.T) {
	var part1 uint32 = 777007543
	var part2 uint32 = 114997259
	key3 := []byte{0x47, 0x30, 0x22, 0x2D, 0x5A, 0x3F, 0x47, 0x58}
	expected := []byte("0st3Rl&q-2ZU^weu")

	response, err := getChallengeResponse(part1, part2, key3)
	if err != nil {
		t.Errorf("getChallengeResponse: returned error %v", err)
		return
	}
	if !bytes.Equal(expected, response) {
		t.Errorf("getChallengeResponse: expected %q got %q", expected, response)
	}
}

func TestEcho(t *testing.T) {
	once.Do(startServer)

	// websocket.Dial()
	client, err := net.Dial("tcp", "", serverAddr)
	if err != nil {
		t.Fatal("dialing", err)
	}
	ws, err := newClient("/echo", "localhost", "http://localhost",
		"ws://localhost/echo", "", client, handshake)
	if err != nil {
		t.Errorf("WebSocket handshake error: %v", err)
		return
	}

	msg := []byte("hello, world\n")
	if _, err := ws.Write(msg); err != nil {
		t.Errorf("Write: %v", err)
	}
	var actual_msg = make([]byte, 512)
	n, err := ws.Read(actual_msg)
	if err != nil {
		t.Errorf("Read: %v", err)
	}
	actual_msg = actual_msg[0:n]
	if !bytes.Equal(msg, actual_msg) {
		t.Errorf("Echo: expected %q got %q", msg, actual_msg)
	}
	ws.Close()
}

func TestEchoDraft75(t *testing.T) {
	once.Do(startServer)

	// websocket.Dial()
	client, err := net.Dial("tcp", "", serverAddr)
	if err != nil {
		t.Fatal("dialing", err)
	}
	ws, err := newClient("/echoDraft75", "localhost", "http://localhost",
		"ws://localhost/echoDraft75", "", client, draft75handshake)
	if err != nil {
		t.Errorf("WebSocket handshake: %v", err)
		return
	}

	msg := []byte("hello, world\n")
	if _, err := ws.Write(msg); err != nil {
		t.Errorf("Write: error %v", err)
	}
	var actual_msg = make([]byte, 512)
	n, err := ws.Read(actual_msg)
	if err != nil {
		t.Errorf("Read: error %v", err)
	}
	actual_msg = actual_msg[0:n]
	if !bytes.Equal(msg, actual_msg) {
		t.Errorf("Echo: expected %q got %q", msg, actual_msg)
	}
	ws.Close()
}

func TestWithQuery(t *testing.T) {
	once.Do(startServer)

	client, err := net.Dial("tcp", "", serverAddr)
	if err != nil {
		t.Fatal("dialing", err)
	}

	ws, err := newClient("/echo?q=v", "localhost", "http://localhost",
		"ws://localhost/echo?q=v", "", client, handshake)
	if err != nil {
		t.Errorf("WebSocket handshake: %v", err)
		return
	}
	ws.Close()
}

func TestWithProtocol(t *testing.T) {
	once.Do(startServer)

	client, err := net.Dial("tcp", "", serverAddr)
	if err != nil {
		t.Fatal("dialing", err)
	}

	ws, err := newClient("/echo", "localhost", "http://localhost",
		"ws://localhost/echo", "test", client, handshake)
	if err != nil {
		t.Errorf("WebSocket handshake: %v", err)
		return
	}
	ws.Close()
}

func TestHTTP(t *testing.T) {
	once.Do(startServer)

	// If the client did not send a handshake that matches the protocol
	// specification, the server should abort the WebSocket connection.
	_, _, err := http.Get(fmt.Sprintf("http://%s/echo", serverAddr))
	if err == nil {
		t.Error("Get: unexpected success")
		return
	}
	urlerr, ok := err.(*http.URLError)
	if !ok {
		t.Errorf("Get: not URLError %#v", err)
		return
	}
	if urlerr.Error != io.ErrUnexpectedEOF {
		t.Errorf("Get: error %#v", err)
		return
	}
}

func TestHTTPDraft75(t *testing.T) {
	once.Do(startServer)

	r, _, err := http.Get(fmt.Sprintf("http://%s/echoDraft75", serverAddr))
	if err != nil {
		t.Errorf("Get: error %#v", err)
		return
	}
	if r.StatusCode != http.StatusBadRequest {
		t.Errorf("Get: got status %d", r.StatusCode)
	}
}

func TestTrailingSpaces(t *testing.T) {
	// http://code.google.com/p/go/issues/detail?id=955
	// The last runs of this create keys with trailing spaces that should not be
	// generated by the client.
	once.Do(startServer)
	for i := 0; i < 30; i++ {
		// body
		_, err := Dial(fmt.Sprintf("ws://%s/echo", serverAddr), "",
			"http://localhost/")
		if err != nil {
			panic("Dial failed: " + err.String())
		}
	}
}

func TestSmallBuffer(t *testing.T) {
	// http://code.google.com/p/go/issues/detail?id=1145
	// Read should be able to handle reading a fragment of a frame.
	once.Do(startServer)

	// websocket.Dial()
	client, err := net.Dial("tcp", "", serverAddr)
	if err != nil {
		t.Fatal("dialing", err)
	}
	ws, err := newClient("/echo", "localhost", "http://localhost",
		"ws://localhost/echo", "", client, handshake)
	if err != nil {
		t.Errorf("WebSocket handshake error: %v", err)
		return
	}

	msg := []byte("hello, world\n")
	if _, err := ws.Write(msg); err != nil {
		t.Errorf("Write: %v", err)
	}
	var small_msg = make([]byte, 8)
	n, err := ws.Read(small_msg)
	if err != nil {
		t.Errorf("Read: %v", err)
	}
	if !bytes.Equal(msg[:len(small_msg)], small_msg) {
		t.Errorf("Echo: expected %q got %q", msg[:len(small_msg)], small_msg)
	}
	var second_msg = make([]byte, len(msg))
	n, err = ws.Read(second_msg)
	if err != nil {
		t.Errorf("Read: %v", err)
	}
	second_msg = second_msg[0:n]
	if !bytes.Equal(msg[len(small_msg):], second_msg) {
		t.Errorf("Echo: expected %q got %q", msg[len(small_msg):], second_msg)
	}
	ws.Close()

}

func testSkipLengthFrame(t *testing.T) {
	b := []byte{'\x80', '\x01', 'x', 0, 'h', 'e', 'l', 'l', 'o', '\xff'}
	buf := bytes.NewBuffer(b)
	br := bufio.NewReader(buf)
	bw := bufio.NewWriter(buf)
	ws := newConn("http://127.0.0.1/", "ws://127.0.0.1/", "", bufio.NewReadWriter(br, bw), nil)
	msg := make([]byte, 5)
	n, err := ws.Read(msg)
	if err != nil {
		t.Errorf("Read: %v", err)
	}
	if !bytes.Equal(b[4:8], msg[0:n]) {
		t.Errorf("Read: expected %q got %q", msg[4:8], msg[0:n])
	}
}

func testSkipNoUTF8Frame(t *testing.T) {
	b := []byte{'\x01', 'n', '\xff', 0, 'h', 'e', 'l', 'l', 'o', '\xff'}
	buf := bytes.NewBuffer(b)
	br := bufio.NewReader(buf)
	bw := bufio.NewWriter(buf)
	ws := newConn("http://127.0.0.1/", "ws://127.0.0.1/", "", bufio.NewReadWriter(br, bw), nil)
	msg := make([]byte, 5)
	n, err := ws.Read(msg)
	if err != nil {
		t.Errorf("Read: %v", err)
	}
	if !bytes.Equal(b[4:8], msg[0:n]) {
		t.Errorf("Read: expected %q got %q", msg[4:8], msg[0:n])
	}
}
<commit_msg>websocket: use httptest.Server for tests<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package websocket

import (
	"bufio"
	"bytes"
	"fmt"
	"http"
	"http/httptest"
	"io"
	"log"
	"net"
	"sync"
	"testing"
)

var serverAddr string
var once sync.Once

func echoServer(ws *Conn) { io.Copy(ws, ws) }

func startServer() {
	http.Handle("/echo", Handler(echoServer))
	http.Handle("/echoDraft75", Draft75Handler(echoServer))
	server := httptest.NewServer(nil)
	serverAddr = server.Listener.Addr().String()
	log.Print("Test WebSocket server listening on ", serverAddr)
}

// Test the getChallengeResponse function with values from section
// 5.1 of the specification steps 18, 26, and 43 from
// http://www.whatwg.org/specs/web-socket-protocol/
func TestChallenge(t *testing.T) {
	var part1 uint32 = 777007543
	var part2 uint32 = 114997259
	key3 := []byte{0x47, 0x30, 0x22, 0x2D, 0x5A, 0x3F, 0x47, 0x58}
	expected := []byte("0st3Rl&q-2ZU^weu")

	response, err := getChallengeResponse(part1, part2, key3)
	if err != nil {
		t.Errorf("getChallengeResponse: returned error %v", err)
		return
	}
	if !bytes.Equal(expected, response) {
		t.Errorf("getChallengeResponse: expected %q got %q", expected, response)
	}
}

func TestEcho(t *testing.T) {
	once.Do(startServer)

	// websocket.Dial()
	client, err := net.Dial("tcp", "", serverAddr)
	if err != nil {
		t.Fatal("dialing", err)
	}
	ws, err := newClient("/echo", "localhost", "http://localhost",
		"ws://localhost/echo", "", client, handshake)
	if err != nil {
		t.Errorf("WebSocket handshake error: %v", err)
		return
	}

	msg := []byte("hello, world\n")
	if _, err := ws.Write(msg); err != nil {
		t.Errorf("Write: %v", err)
	}
	var actual_msg = make([]byte, 512)
	n, err := ws.Read(actual_msg)
	if err != nil {
		t.Errorf("Read: %v", err)
	}
	actual_msg = actual_msg[0:n]
	if !bytes.Equal(msg, actual_msg) {
		t.Errorf("Echo: expected %q got %q", msg, actual_msg)
	}
	ws.Close()
}

func TestEchoDraft75(t *testing.T) {
	once.Do(startServer)

	// websocket.Dial()
	client, err := net.Dial("tcp", "", serverAddr)
	if err != nil {
		t.Fatal("dialing", err)
	}
	ws, err := newClient("/echoDraft75", "localhost", "http://localhost",
		"ws://localhost/echoDraft75", "", client, draft75handshake)
	if err != nil {
		t.Errorf("WebSocket handshake: %v", err)
		return
	}

	msg := []byte("hello, world\n")
	if _, err := ws.Write(msg); err != nil {
		t.Errorf("Write: error %v", err)
	}
	var actual_msg = make([]byte, 512)
	n, err := ws.Read(actual_msg)
	if err != nil {
		t.Errorf("Read: error %v", err)
	}
	actual_msg = actual_msg[0:n]
	if !bytes.Equal(msg, actual_msg) {
		t.Errorf("Echo: expected %q got %q", msg, actual_msg)
	}
	ws.Close()
}

func TestWithQuery(t *testing.T) {
	once.Do(startServer)

	client, err := net.Dial("tcp", "", serverAddr)
	if err != nil {
		t.Fatal("dialing", err)
	}

	ws, err := newClient("/echo?q=v", "localhost", "http://localhost",
		"ws://localhost/echo?q=v", "", client, handshake)
	if err != nil {
		t.Errorf("WebSocket handshake: %v", err)
		return
	}
	ws.Close()
}

func TestWithProtocol(t *testing.T) {
	once.Do(startServer)

	client, err := net.Dial("tcp", "", serverAddr)
	if err != nil {
		t.Fatal("dialing", err)
	}

	ws, err := newClient("/echo", "localhost", "http://localhost",
		"ws://localhost/echo", "test", client, handshake)
	if err != nil {
		t.Errorf("WebSocket handshake: %v", err)
		return
	}
	ws.Close()
}

func TestHTTP(t *testing.T) {
	once.Do(startServer)

	// If the client did not send a handshake that matches the protocol
	// specification, the server should abort the WebSocket connection.
	_, _, err := http.Get(fmt.Sprintf("http://%s/echo", serverAddr))
	if err == nil {
		t.Error("Get: unexpected success")
		return
	}
	urlerr, ok := err.(*http.URLError)
	if !ok {
		t.Errorf("Get: not URLError %#v", err)
		return
	}
	if urlerr.Error != io.ErrUnexpectedEOF {
		t.Errorf("Get: error %#v", err)
		return
	}
}

func TestHTTPDraft75(t *testing.T) {
	once.Do(startServer)

	r, _, err := http.Get(fmt.Sprintf("http://%s/echoDraft75", serverAddr))
	if err != nil {
		t.Errorf("Get: error %#v", err)
		return
	}
	if r.StatusCode != http.StatusBadRequest {
		t.Errorf("Get: got status %d", r.StatusCode)
	}
}

func TestTrailingSpaces(t *testing.T) {
	// http://code.google.com/p/go/issues/detail?id=955
	// The last runs of this create keys with trailing spaces that should not be
	// generated by the client.
	once.Do(startServer)
	for i := 0; i < 30; i++ {
		// body
		_, err := Dial(fmt.Sprintf("ws://%s/echo", serverAddr), "",
			"http://localhost/")
		if err != nil {
			panic("Dial failed: " + err.String())
		}
	}
}

func TestSmallBuffer(t *testing.T) {
	// http://code.google.com/p/go/issues/detail?id=1145
	// Read should be able to handle reading a fragment of a frame.
	once.Do(startServer)

	// websocket.Dial()
	client, err := net.Dial("tcp", "", serverAddr)
	if err != nil {
		t.Fatal("dialing", err)
	}
	ws, err := newClient("/echo", "localhost", "http://localhost",
		"ws://localhost/echo", "", client, handshake)
	if err != nil {
		t.Errorf("WebSocket handshake error: %v", err)
		return
	}

	msg := []byte("hello, world\n")
	if _, err := ws.Write(msg); err != nil {
		t.Errorf("Write: %v", err)
	}
	var small_msg = make([]byte, 8)
	n, err := ws.Read(small_msg)
	if err != nil {
		t.Errorf("Read: %v", err)
	}
	if !bytes.Equal(msg[:len(small_msg)], small_msg) {
		t.Errorf("Echo: expected %q got %q", msg[:len(small_msg)], small_msg)
	}
	var second_msg = make([]byte, len(msg))
	n, err = ws.Read(second_msg)
	if err != nil {
		t.Errorf("Read: %v", err)
	}
	second_msg = second_msg[0:n]
	if !bytes.Equal(msg[len(small_msg):], second_msg) {
		t.Errorf("Echo: expected %q got %q", msg[len(small_msg):], second_msg)
	}
	ws.Close()

}

func testSkipLengthFrame(t *testing.T) {
	b := []byte{'\x80', '\x01', 'x', 0, 'h', 'e', 'l', 'l', 'o', '\xff'}
	buf := bytes.NewBuffer(b)
	br := bufio.NewReader(buf)
	bw := bufio.NewWriter(buf)
	ws := newConn("http://127.0.0.1/", "ws://127.0.0.1/", "", bufio.NewReadWriter(br, bw), nil)
	msg := make([]byte, 5)
	n, err := ws.Read(msg)
	if err != nil {
		t.Errorf("Read: %v", err)
	}
	if !bytes.Equal(b[4:8], msg[0:n]) {
		t.Errorf("Read: expected %q got %q", msg[4:8], msg[0:n])
	}
}

func testSkipNoUTF8Frame(t *testing.T) {
	b := []byte{'\x01', 'n', '\xff', 0, 'h', 'e', 'l', 'l', 'o', '\xff'}
	buf := bytes.NewBuffer(b)
	br := bufio.NewReader(buf)
	bw := bufio.NewWriter(buf)
	ws := newConn("http://127.0.0.1/", "ws://127.0.0.1/", "", bufio.NewReadWriter(br, bw), nil)
	msg := make([]byte, 5)
	n, err := ws.Read(msg)
	if err != nil {
		t.Errorf("Read: %v", err)
	}
	if !bytes.Equal(b[4:8], msg[0:n]) {
		t.Errorf("Read: expected %q got %q", msg[4:8], msg[0:n])
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Kubernetes 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 main

import (
	"fmt"
	"io/ioutil"
	"k8s.io/klog"
	"net/http"
	"strings"

	"gopkg.in/yaml.v2"
)

type githubDirContent struct {
	Name        string `yaml:"name"`
	Path        string `yaml:"path"`
	DownloadURL string `yaml:"download_url"`
	Type        string `yaml:"type"`
	URL         string `yaml:"url"`
}

// GetConfigsFromGithub gets config paths from github directory. It uses github API,
// which is documented here: https://developer.github.com/v3/repos/contents/
//
// Example url: https://api.github.com/repos/kubernetes/test-infra/contents/config/jobs/kubernetes/sig-release/release-branch-jobs
//
// Different branch can be specified by appending "?ref=branch-name" parameter at the end
// of the url.
func GetConfigsFromGithub(url string) ([]string, error) {
	var result []string
	contents, err := getGithubDirContents(url)
	if err != nil {
		return nil, err
	}
	for _, c := range contents {
		// Dirs and non-yaml files are ignored; this means that there is no
		// recursive search, it should be good enough for now.
		if c.Type == "file" && strings.HasSuffix(c.Name, ".yaml") {
			result = append(result, c.DownloadURL)
		}
	}
	return result, nil
}

func getGithubDirContents(url string) ([]githubDirContent, error) {
	klog.Infof("Downloading github spec from %v", url)
	resp, err := http.Get(url)
	if err != nil {
		return nil, fmt.Errorf("error calling github API %s: %v", url, err)
	}
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("error reading github response %s: %v", url, err)
	}
	var decoded []githubDirContent
	err = yaml.Unmarshal(b, &decoded)
	if err != nil {
		return nil, err
	}
	return decoded, nil
}
<commit_msg>* Added support for GitHub bearer token<commit_after>/*
Copyright 2019 The Kubernetes 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 main

import (
	"fmt"
	"io/ioutil"
	"k8s.io/klog"
	"net/http"
	"os"
	"strings"

	"gopkg.in/yaml.v2"
)

type githubDirContent struct {
	Name        string `yaml:"name"`
	Path        string `yaml:"path"`
	DownloadURL string `yaml:"download_url"`
	Type        string `yaml:"type"`
	URL         string `yaml:"url"`
}

// GetConfigsFromGithub gets config paths from github directory. It uses github API,
// which is documented here: https://developer.github.com/v3/repos/contents/
//
// Example url: https://api.github.com/repos/kubernetes/test-infra/contents/config/jobs/kubernetes/sig-release/release-branch-jobs
//
// Different branch can be specified by appending "?ref=branch-name" parameter at the end
// of the url.
func GetConfigsFromGithub(url string) ([]string, error) {
	var result []string
	contents, err := getGithubDirContents(url)
	if err != nil {
		return nil, err
	}
	for _, c := range contents {
		// Dirs and non-yaml files are ignored; this means that there is no
		// recursive search, it should be good enough for now.
		if c.Type == "file" && strings.HasSuffix(c.Name, ".yaml") {
			result = append(result, c.DownloadURL)
		}
	}
	return result, nil
}

func getGithubDirContents(url string) ([]githubDirContent, error) {
	klog.Infof("Downloading github spec from %v", url)
	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		return nil, err
	}
	if token := os.Getenv("GITHUB_TOKEN"); len(token) != 0 {
		req.Header.Add("Authorization", fmt.Sprintf("Bearer: %s", token))
	}
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("error calling github API %s: %v", url, err)
	}
	b, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("error reading github response %s: %v", url, err)
	}
	var decoded []githubDirContent
	err = yaml.Unmarshal(b, &decoded)
	if err != nil {
		return nil, err
	}
	return decoded, nil
}
<|endoftext|>


<commit_before>package dynmap

import (
	"strings"
	// "log"
	"encoding/json"
	"errors"
	"fmt"
	"net/url"
	"time"
)

//Dont make this a map type, since we want the option of
//extending this and adding members.
type DynMap struct {
	Map map[string]interface{}
}

type DynMaper interface {
	ToDynMap() *DynMap
}

func NewDynMap() *DynMap {
	return &DynMap{make(map[string]interface{})}
}

// Returns self. Here so that we satisfy the DynMaper interface
func (this *DynMap) ToDynMap() *DynMap {
	return this
}

//encodes this map into a url encoded string.
//maps are encoded in the rails style (key[key2][key2]=value)
// TODO: we should sort the keynames so ordering is consistent and then this
// can be used a cache key
func (this *DynMap) MarshalURL() (string, error) {
	vals := &url.Values{}
	for key, value := range this.Map {
		err := this.urlEncode(vals, key, value)
		if err != nil {
			return "", err
		}
	}
	return vals.Encode(), nil
}

// Unmarshals a url encoded string.
// will also parse rails style maps in the form key[key1][key2]=val\
func (this *DynMap) UnmarshalURL(urlstring string) error {
	//TODO: split on ?
	values, err := url.ParseQuery(urlstring)
	if err != nil {
		return err
	}
	for k := range values {
		var v = values[k]
		key := strings.Replace(k, "[", ".", -1)
		key = strings.Replace(key, "]", "", -1)

		if len(v) == 1 {
			this.PutWithDot(key, v[0])
		} else {
			this.PutWithDot(key, v)
		}
	}
	return nil
}

//adds the requested value to the Values
func (this *DynMap) urlEncode(vals *url.Values, key string, value interface{}) error {

	if DynMapConvertable(value) {
		mp, ok := ToDynMap(value)
		if !ok {
			return fmt.Errorf("Unable to convert %s", mp)
		}
		for k, v := range mp.Map {
			//encode in rails style key[key2]=value
			this.urlEncode(vals, fmt.Sprintf("%s[%s]", key, k), v)
		}
		return nil
	}
	switch v := value.(type) {
	case []interface{}:
		for _, tmp := range v {
			this.urlEncode(vals, key, tmp)
		}
		return nil
	}
	vals.Add(key, ToString(value))
	return nil
}

func (this *DynMap) MarshalJSON() ([]byte, error) {
	bytes, err := json.Marshal(this.Map)
	return bytes, err
}

func (this *DynMap) UnmarshalJSON(bytes []byte) error {
	return json.Unmarshal(bytes, &this.Map)
}

// Gets the value at the specified key as an int64.  returns -1,false if value not available or is not convertable
func (this *DynMap) GetInt64(key string) (int64, bool) {
	tmp, ok := this.Get(key)
	if !ok {
		return -1, ok
	}
	val, err := ToInt64(tmp)
	if err == nil {
		return val, true
	}
	return -1, false
}

func (this *DynMap) MustInt64(key string, def int64) int64 {
	v, ok := this.GetInt64(key)
	if ok {
		return v
	}
	return def
}

func (this *DynMap) MustInt(key string, def int) int {
	v, ok := this.GetInt(key)
	if ok {
		return v
	}
	return def
}

func (this *DynMap) GetInt(key string) (int, bool) {
	v, ok := this.GetInt64(key)
	if !ok {
		return -1, ok
	}
	return int(v), true
}

//
// Gets a string representation of the value at key
//
func (this *DynMap) GetString(key string) (string, bool) {
	tmp, ok := this.Get(key)
	if !ok {
		return ToString(tmp), ok
	}
	return ToString(tmp), true
}

// gets a string. if string is not available in the map, then the default
//is returned
func (this *DynMap) MustString(key string, def string) string {
	tmp, ok := this.GetString(key)
	if !ok {
		return def
	}
	return tmp
}

func (this *DynMap) GetTime(key string) (time.Time, bool) {
	tmp, ok := this.Get(key)
	if !ok {
		return time.Now(), false
	}
	t, err := ToTime(tmp)
	if err != nil {
		return time.Now(), false
	}
	return t, true
}

func (this *DynMap) GetTimeOrDefault(key string, def time.Time) time.Time {
	tmp, ok := this.GetTime(key)
	if !ok {
		return def
	}
	return tmp
}

func (this *DynMap) GetBool(key string) (bool, bool) {
	tmp, ok := this.Get(key)
	if !ok {
		return false, ok
	}
	b, err := ToBool(tmp)
	if err != nil {
		return false, false
	}
	return b, true
}

func (this *DynMap) MustBool(key string, def bool) bool {
	tmp, ok := this.GetBool(key)
	if !ok {
		return def
	}
	return tmp
}

//Gets a dynmap from the requested.
// This will update the value in the map if the
// value was not already a dynmap.
func (this *DynMap) GetDynMap(key string) (*DynMap, bool) {
	tmp, ok := this.Get(key)
	if !ok {
		return nil, ok
	}
	mp, ok := ToDynMap(tmp)
	return mp, ok
}

func (this *DynMap) MustDynMap(key string, def *DynMap) *DynMap {
	tmp, ok := this.GetDynMap(key)
	if !ok {
		return def
	}
	return tmp
}

// gets a slice of dynmaps
func (this *DynMap) GetDynMapSlice(key string) ([]*DynMap, bool) {
	lst, ok := this.Get(key)
	if !ok {
		return nil, false
	}
	switch v := lst.(type) {
	case []*DynMap:
		return v, true
	case []interface{}:
		retlist := make([]*DynMap, 0)
		for _, tmp := range v {
			in, ok := ToDynMap(tmp)
			if !ok {
				return nil, false
			}
			retlist = append(retlist, in)
		}
		return retlist, true
	}
	return nil, false
}

//Returns a slice of ints
func (this *DynMap) GetIntSlice(key string) ([]int, bool) {
	lst, ok := this.Get(key)
	if !ok {
		return nil, false
	}
	switch v := lst.(type) {
	case []int:
		return v, true
	case []interface{}:
		retlist := make([]int, 0)
		for _, tmp := range v {
			in, err := ToInt(tmp)
			if err != nil {
				return nil, false
			}
			retlist = append(retlist, in)
		}
		return retlist, true
	}
	return nil, false
}

//gets a slice of ints.  if the value is a string it will
//split by the requested delimiter
func (this *DynMap) GetIntSliceSplit(key, delim string) ([]int, bool) {
	lst, ok := this.Get(key)
	if !ok {
		return nil, false
	}
	switch v := lst.(type) {
	case string:
		retlist := make([]int, 0)
		for _, tmp := range strings.Split(v, delim) {
			in, err := ToInt(tmp)
			if err != nil {
				return nil, false
			}
			retlist = append(retlist, in)
		}
		return retlist, true
	}
	ret, ok := this.GetIntSlice(key)
	return ret, ok
}

// Adds the item to a slice
func (this *DynMap) AddToSlice(key string, mp interface{}) error {
	this.PutIfAbsent(key, make([]interface{}, 0))
	lst, _ := this.Get(key)
	switch v := lst.(type) {
	case []interface{}:
		v = append(v, mp)
		this.Put(key, v)
	}
	return nil
}

// puts all the values from the passed in map into this dynmap
// the passed in map must be convertable to a DynMap via ToDynMap.
// returns false if the passed value is not convertable to dynmap
func (this *DynMap) PutAll(mp interface{}) bool {
	dynmap, ok := ToDynMap(mp)
	if !ok {
		return false
	}
	for k, v := range dynmap.Map {
		this.Put(k, v)
	}
	return true
}

//
// Puts the value into the map if and only if no value exists at the
// specified key.
// This does not honor the dot operator on insert.
func (this *DynMap) PutIfAbsent(key string, value interface{}) (interface{}, bool) {
	v, ok := this.Get(key)
	if ok {
		return v, false
	}
	this.Put(key, value)
	return value, true
}

//
// Same as PutIfAbsent but honors the dot operator
//
func (this *DynMap) PutIfAbsentWithDot(key string, value interface{}) (interface{}, bool) {
	v, ok := this.Get(key)
	if ok {
		return v, false
	}
	this.PutWithDot(key, value)
	return value, true
}

//
// Put's a value into the map
//
func (this *DynMap) Put(key string, value interface{}) {
	this.Map[key] = value
}

//
// puts the value into the map, honoring the dot operator.
// so PutWithDot("map1.map2.value", 100)
// would result in:
// {
//   map1 : { map2 : { value: 100 }}
//
// }
func (this *DynMap) PutWithDot(key string, value interface{}) error {
	splitStr := strings.Split(key, ".")
	if len(splitStr) == 1 {
		this.Put(key, value)
		return nil
	}
	mapKeys := splitStr[:(len(splitStr) - 1)]
	var mp = this.Map
	for _, k := range mapKeys {
		tmp, o := mp[k]
		if !o {
			//create a new map and insert
			newmap := make(map[string]interface{})
			mp[k] = newmap
			mp = newmap
		} else {
			mp, o = ToMap(tmp)
			if !o {
				//error
				return errors.New("Error, value at key was not a map")
			}
		}
	}
	mp[splitStr[len(splitStr)-1]] = value
	return nil
}

func (this *DynMap) Exists(key string) bool {
	_, ok := this.Get(key)
	return ok
}

//Remove a mapping
//TODO: this will need to honor the dot operator!
func (this *DynMap) Remove(key string) (interface{}, bool) {
	val, ok := this.Map[key]
	if ok {
		delete(this.Map, key)
		return val, true
	}
	//TODO: dot op..
	return val, false

}

//
// Get's the value.  will honor the dot operator if needed.
// key = 'map.map2'
// will first attempt to matche the literal key 'map.map2'
// if no value is present it will look for a sub map at key 'map'
//
func (this *DynMap) Get(key string) (interface{}, bool) {
	val, ok := this.Map[key]
	if ok {
		return val, true
	}
	//look for dot operator.
	splitStr := strings.Split(key, ".")
	if len(splitStr) == 1 {
		return val, false
	}

	var mp = this.Map
	for index, k := range splitStr {
		tmp, o := mp[k]
		if !o {
			return val, ok
		}

		if index == (len(splitStr) - 1) {
			return tmp, o
		} else {
			mp, o = ToMap(tmp)
			if !o {
				return val, ok
			}
		}
	}
	return val, ok
}
<commit_msg>add recursive ToMap method<commit_after>package dynmap

import (
	"strings"
	// "log"
	"encoding/json"
	"errors"
	"fmt"
	"net/url"
	"time"
)

//Dont make this a map type, since we want the option of
//extending this and adding members.
type DynMap struct {
	Map map[string]interface{}
}

type DynMaper interface {
	ToDynMap() *DynMap
}

func NewDynMap() *DynMap {
	return &DynMap{make(map[string]interface{})}
}

// Recursively converts this to a regular go map.
// (will convert any sub maps)
func (this *DynMap) ToMap() map[string]interface{} {
	mp := make(map[string]interface{})
	for k, v := range(this.Map) {
		submp, ok := ToDynMap(this.Map[k])
		if ok {
			v = submp.ToMap()
		}
		mp[k] = v
	}
	return mp
}

// Returns self. Here so that we satisfy the DynMaper interface
func (this *DynMap) ToDynMap() *DynMap {
	return this
}

//encodes this map into a url encoded string.
//maps are encoded in the rails style (key[key2][key2]=value)
// TODO: we should sort the keynames so ordering is consistent and then this
// can be used a cache key
func (this *DynMap) MarshalURL() (string, error) {
	vals := &url.Values{}
	for key, value := range this.Map {
		err := this.urlEncode(vals, key, value)
		if err != nil {
			return "", err
		}
	}
	return vals.Encode(), nil
}

// Unmarshals a url encoded string.
// will also parse rails style maps in the form key[key1][key2]=val\
func (this *DynMap) UnmarshalURL(urlstring string) error {
	//TODO: split on ?
	values, err := url.ParseQuery(urlstring)
	if err != nil {
		return err
	}
	for k := range values {
		var v = values[k]
		key := strings.Replace(k, "[", ".", -1)
		key = strings.Replace(key, "]", "", -1)

		if len(v) == 1 {
			this.PutWithDot(key, v[0])
		} else {
			this.PutWithDot(key, v)
		}
	}
	return nil
}

//adds the requested value to the Values
func (this *DynMap) urlEncode(vals *url.Values, key string, value interface{}) error {

	if DynMapConvertable(value) {
		mp, ok := ToDynMap(value)
		if !ok {
			return fmt.Errorf("Unable to convert %s", mp)
		}
		for k, v := range mp.Map {
			//encode in rails style key[key2]=value
			this.urlEncode(vals, fmt.Sprintf("%s[%s]", key, k), v)
		}
		return nil
	}
	switch v := value.(type) {
	case []interface{}:
		for _, tmp := range v {
			this.urlEncode(vals, key, tmp)
		}
		return nil
	}
	vals.Add(key, ToString(value))
	return nil
}

func (this *DynMap) MarshalJSON() ([]byte, error) {
	bytes, err := json.Marshal(this.Map)
	return bytes, err
}

func (this *DynMap) UnmarshalJSON(bytes []byte) error {
	return json.Unmarshal(bytes, &this.Map)
}

// Gets the value at the specified key as an int64.  returns -1,false if value not available or is not convertable
func (this *DynMap) GetInt64(key string) (int64, bool) {
	tmp, ok := this.Get(key)
	if !ok {
		return -1, ok
	}
	val, err := ToInt64(tmp)
	if err == nil {
		return val, true
	}
	return -1, false
}

func (this *DynMap) MustInt64(key string, def int64) int64 {
	v, ok := this.GetInt64(key)
	if ok {
		return v
	}
	return def
}

func (this *DynMap) MustInt(key string, def int) int {
	v, ok := this.GetInt(key)
	if ok {
		return v
	}
	return def
}

func (this *DynMap) GetInt(key string) (int, bool) {
	v, ok := this.GetInt64(key)
	if !ok {
		return -1, ok
	}
	return int(v), true
}

//
// Gets a string representation of the value at key
//
func (this *DynMap) GetString(key string) (string, bool) {
	tmp, ok := this.Get(key)
	if !ok {
		return ToString(tmp), ok
	}
	return ToString(tmp), true
}

// gets a string. if string is not available in the map, then the default
//is returned
func (this *DynMap) MustString(key string, def string) string {
	tmp, ok := this.GetString(key)
	if !ok {
		return def
	}
	return tmp
}

func (this *DynMap) GetTime(key string) (time.Time, bool) {
	tmp, ok := this.Get(key)
	if !ok {
		return time.Now(), false
	}
	t, err := ToTime(tmp)
	if err != nil {
		return time.Now(), false
	}
	return t, true
}

func (this *DynMap) GetTimeOrDefault(key string, def time.Time) time.Time {
	tmp, ok := this.GetTime(key)
	if !ok {
		return def
	}
	return tmp
}

func (this *DynMap) GetBool(key string) (bool, bool) {
	tmp, ok := this.Get(key)
	if !ok {
		return false, ok
	}
	b, err := ToBool(tmp)
	if err != nil {
		return false, false
	}
	return b, true
}

func (this *DynMap) MustBool(key string, def bool) bool {
	tmp, ok := this.GetBool(key)
	if !ok {
		return def
	}
	return tmp
}

//Gets a dynmap from the requested.
// This will update the value in the map if the
// value was not already a dynmap.
func (this *DynMap) GetDynMap(key string) (*DynMap, bool) {
	tmp, ok := this.Get(key)
	if !ok {
		return nil, ok
	}
	mp, ok := ToDynMap(tmp)
	return mp, ok
}

func (this *DynMap) MustDynMap(key string, def *DynMap) *DynMap {
	tmp, ok := this.GetDynMap(key)
	if !ok {
		return def
	}
	return tmp
}

// gets a slice of dynmaps
func (this *DynMap) GetDynMapSlice(key string) ([]*DynMap, bool) {
	lst, ok := this.Get(key)
	if !ok {
		return nil, false
	}
	switch v := lst.(type) {
	case []*DynMap:
		return v, true
	case []interface{}:
		retlist := make([]*DynMap, 0)
		for _, tmp := range v {
			in, ok := ToDynMap(tmp)
			if !ok {
				return nil, false
			}
			retlist = append(retlist, in)
		}
		return retlist, true
	}
	return nil, false
}

//Returns a slice of ints
func (this *DynMap) GetIntSlice(key string) ([]int, bool) {
	lst, ok := this.Get(key)
	if !ok {
		return nil, false
	}
	switch v := lst.(type) {
	case []int:
		return v, true
	case []interface{}:
		retlist := make([]int, 0)
		for _, tmp := range v {
			in, err := ToInt(tmp)
			if err != nil {
				return nil, false
			}
			retlist = append(retlist, in)
		}
		return retlist, true
	}
	return nil, false
}

//gets a slice of ints.  if the value is a string it will
//split by the requested delimiter
func (this *DynMap) GetIntSliceSplit(key, delim string) ([]int, bool) {
	lst, ok := this.Get(key)
	if !ok {
		return nil, false
	}
	switch v := lst.(type) {
	case string:
		retlist := make([]int, 0)
		for _, tmp := range strings.Split(v, delim) {
			in, err := ToInt(tmp)
			if err != nil {
				return nil, false
			}
			retlist = append(retlist, in)
		}
		return retlist, true
	}
	ret, ok := this.GetIntSlice(key)
	return ret, ok
}

// Adds the item to a slice
func (this *DynMap) AddToSlice(key string, mp interface{}) error {
	this.PutIfAbsent(key, make([]interface{}, 0))
	lst, _ := this.Get(key)
	switch v := lst.(type) {
	case []interface{}:
		v = append(v, mp)
		this.Put(key, v)
	}
	return nil
}

// puts all the values from the passed in map into this dynmap
// the passed in map must be convertable to a DynMap via ToDynMap.
// returns false if the passed value is not convertable to dynmap
func (this *DynMap) PutAll(mp interface{}) bool {
	dynmap, ok := ToDynMap(mp)
	if !ok {
		return false
	}
	for k, v := range dynmap.Map {
		this.Put(k, v)
	}
	return true
}

//
// Puts the value into the map if and only if no value exists at the
// specified key.
// This does not honor the dot operator on insert.
func (this *DynMap) PutIfAbsent(key string, value interface{}) (interface{}, bool) {
	v, ok := this.Get(key)
	if ok {
		return v, false
	}
	this.Put(key, value)
	return value, true
}

//
// Same as PutIfAbsent but honors the dot operator
//
func (this *DynMap) PutIfAbsentWithDot(key string, value interface{}) (interface{}, bool) {
	v, ok := this.Get(key)
	if ok {
		return v, false
	}
	this.PutWithDot(key, value)
	return value, true
}

//
// Put's a value into the map
//
func (this *DynMap) Put(key string, value interface{}) {
	this.Map[key] = value
}

//
// puts the value into the map, honoring the dot operator.
// so PutWithDot("map1.map2.value", 100)
// would result in:
// {
//   map1 : { map2 : { value: 100 }}
//
// }
func (this *DynMap) PutWithDot(key string, value interface{}) error {
	splitStr := strings.Split(key, ".")
	if len(splitStr) == 1 {
		this.Put(key, value)
		return nil
	}
	mapKeys := splitStr[:(len(splitStr) - 1)]
	var mp = this.Map
	for _, k := range mapKeys {
		tmp, o := mp[k]
		if !o {
			//create a new map and insert
			newmap := make(map[string]interface{})
			mp[k] = newmap
			mp = newmap
		} else {
			mp, o = ToMap(tmp)
			if !o {
				//error
				return errors.New("Error, value at key was not a map")
			}
		}
	}
	mp[splitStr[len(splitStr)-1]] = value
	return nil
}

func (this *DynMap) Exists(key string) bool {
	_, ok := this.Get(key)
	return ok
}

//Remove a mapping
//TODO: this will need to honor the dot operator!
func (this *DynMap) Remove(key string) (interface{}, bool) {
	val, ok := this.Map[key]
	if ok {
		delete(this.Map, key)
		return val, true
	}
	//TODO: dot op..
	return val, false

}

//
// Get's the value.  will honor the dot operator if needed.
// key = 'map.map2'
// will first attempt to matche the literal key 'map.map2'
// if no value is present it will look for a sub map at key 'map'
//
func (this *DynMap) Get(key string) (interface{}, bool) {
	val, ok := this.Map[key]
	if ok {
		return val, true
	}
	//look for dot operator.
	splitStr := strings.Split(key, ".")
	if len(splitStr) == 1 {
		return val, false
	}

	var mp = this.Map
	for index, k := range splitStr {
		tmp, o := mp[k]
		if !o {
			return val, ok
		}

		if index == (len(splitStr) - 1) {
			return tmp, o
		} else {
			mp, o = ToMap(tmp)
			if !o {
				return val, ok
			}
		}
	}
	return val, ok
}
<|endoftext|>


<commit_before>package terraform

import (
	"strings"
	"testing"

	"github.com/hashicorp/terraform/addrs"
)

func TestTransitiveReductionTransformer(t *testing.T) {
	mod := testModule(t, "transform-trans-reduce-basic")

	g := Graph{Path: addrs.RootModuleInstance}
	{
		tf := &ConfigTransformer{Config: mod}
		if err := tf.Transform(&g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	{
		transform := &AttachResourceConfigTransformer{Config: mod}
		if err := transform.Transform(&g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	{
		transform := &ReferenceTransformer{}
		if err := transform.Transform(&g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	{
		transform := &TransitiveReductionTransformer{}
		if err := transform.Transform(&g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	actual := strings.TrimSpace(g.String())
	expected := strings.TrimSpace(testTransformTransReduceBasicStr)
	if actual != expected {
		t.Fatalf("bad:\n\n%s", actual)
	}
}

const testTransformTransReduceBasicStr = `
aws_instance.A
aws_instance.B
  aws_instance.A
aws_instance.C
  aws_instance.B
`
<commit_msg>core: TestTransitiveReductionTransformer needs a schema<commit_after>package terraform

import (
	"strings"
	"testing"

	"github.com/hashicorp/terraform/addrs"
	"github.com/hashicorp/terraform/config/configschema"
	"github.com/zclconf/go-cty/cty"
)

func TestTransitiveReductionTransformer(t *testing.T) {
	mod := testModule(t, "transform-trans-reduce-basic")

	g := Graph{Path: addrs.RootModuleInstance}
	{
		tf := &ConfigTransformer{Config: mod}
		if err := tf.Transform(&g); err != nil {
			t.Fatalf("err: %s", err)
		}
		t.Logf("graph after ConfigTransformer:\n%s", g.String())
	}

	{
		transform := &AttachResourceConfigTransformer{Config: mod}
		if err := transform.Transform(&g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	{
		transform := &AttachSchemaTransformer{
			Components: testProviderComponentFactory(
				"aws",
				mockProviderWithResourceTypeSchema("aws_instance", &configschema.Block{
					Attributes: map[string]*configschema.Attribute{
						"A": {
							Type:     cty.String,
							Optional: true,
						},
						"B": {
							Type:     cty.String,
							Optional: true,
						},
					},
				}),
			),
		}
		if err := transform.Transform(&g); err != nil {
			t.Fatalf("err: %s", err)
		}
	}

	{
		transform := &ReferenceTransformer{}
		if err := transform.Transform(&g); err != nil {
			t.Fatalf("err: %s", err)
		}
		t.Logf("graph after ReferenceTransformer:\n%s", g.String())
	}

	{
		transform := &TransitiveReductionTransformer{}
		if err := transform.Transform(&g); err != nil {
			t.Fatalf("err: %s", err)
		}
		t.Logf("graph after TransitiveReductionTransformer:\n%s", g.String())
	}

	actual := strings.TrimSpace(g.String())
	expected := strings.TrimSpace(testTransformTransReduceBasicStr)
	if actual != expected {
		t.Errorf("wrong result\ngot:\n%s\n\nwant:\n%s", actual, expected)
	}
}

const testTransformTransReduceBasicStr = `
aws_instance.A
aws_instance.B
  aws_instance.A
aws_instance.C
  aws_instance.B
`
<|endoftext|>


<commit_before>package errs

import (
	"fmt"
	"runtime/debug"
	"time"
)

type Err interface {
	Stack() []byte
	Time() time.Time
	StandardError() error
	StandardErrorMessage() string
	UserMessage() string
	SetUserMessage(userMessage string)
	InternalInfo() Info
	LogString() string
}

type Info map[string]interface{}
type Opts struct {
	OmitStack bool
}

var (
	DefaultUserMessage = "Oops! Something went wrong. Please try again."
	DefaultOpts        = Opts{
		OmitStack: false,
	}
)

func Wrap(stdErr error, internalInfo Info, userMessage ...interface{}) Err {
	return WrapWithOpts(stdErr, internalInfo, DefaultOpts, userMessage...)
}
func New(internalInfo Info, userMessage ...interface{}) Err {
	return NewWithOpts(internalInfo, DefaultOpts, userMessage...)
}
func WrapWithOpts(stdErr error, internalInfo Info, opts Opts, userMessage ...interface{}) Err {
	return newErr(stdErr, internalInfo, opts, userMessage)
}
func NewWithOpts(internalInfo Info, opts Opts, userMessage ...interface{}) Err {
	return newErr(nil, internalInfo, opts, userMessage)
}

func newErr(stdErr error, internalInfo Info, opts Opts, userMessageParts []interface{}) Err {
	if stdErr == nil {
		return nil
	}
	userMessage := fmt.Sprint(userMessageParts...)
	if userMessage == "" {
		userMessage = DefaultUserMessage
	}
	var stack []byte
	if !opts.OmitStack {
		stack = debug.Stack()
	}
	if internalInfo == nil {
		internalInfo = Info{}
	}
	return &err{stack, time.Now(), stdErr, internalInfo, userMessage}
}

type err struct {
	stack        []byte
	time         time.Time
	stdErr       error
	internalInfo Info
	userMessage  string
}

func (e *err) Stack() []byte             { return e.stack }
func (e *err) Time() time.Time           { return e.time }
func (e *err) StandardError() error      { return e.stdErr }
func (e *err) UserMessage() string       { return e.userMessage }
func (e *err) SetUserMessage(msg string) { e.userMessage = msg }
func (e *err) InternalInfo() Info        { return e.internalInfo }
func (e *err) StandardErrorMessage() string {
	if e == nil {
		return ""
	}
	if e.stdErr == nil {
		return ""
	}
	return e.stdErr.Error()
}
func (e *err) LogString() string {
	return fmt.Sprint("Error | UserMessage: ", e.userMessage, " | StandardError: "+e.StandardErrorMessage()+" | Stack: ", string(e.stack), " | tInternalInfo:[", e.internalInfo, "Time:", e.time)
}

func (e *err) String() string { return e.LogString() }
<commit_msg>Only Wrap* functions should return nil if there is no stderr<commit_after>package errs

import (
	"fmt"
	"runtime/debug"
	"time"
)

type Err interface {
	Stack() []byte
	Time() time.Time
	StandardError() error
	StandardErrorMessage() string
	UserMessage() string
	SetUserMessage(userMessage string)
	InternalInfo() Info
	LogString() string
}

type Info map[string]interface{}
type Opts struct {
	OmitStack bool
}

var (
	DefaultUserMessage = "Oops! Something went wrong. Please try again."
	DefaultOpts        = Opts{
		OmitStack: false,
	}
)

func Wrap(stdErr error, internalInfo Info, userMessage ...interface{}) Err {
	if stdErr == nil {
		return nil
	}
	return WrapWithOpts(stdErr, internalInfo, DefaultOpts, userMessage...)
}
func New(internalInfo Info, userMessage ...interface{}) Err {
	return NewWithOpts(internalInfo, DefaultOpts, userMessage...)
}
func WrapWithOpts(stdErr error, internalInfo Info, opts Opts, userMessage ...interface{}) Err {
	if stdErr == nil {
		return nil
	}
	return newErr(stdErr, internalInfo, opts, userMessage)
}
func NewWithOpts(internalInfo Info, opts Opts, userMessage ...interface{}) Err {
	return newErr(nil, internalInfo, opts, userMessage)
}

func newErr(stdErr error, internalInfo Info, opts Opts, userMessageParts []interface{}) Err {
	userMessage := fmt.Sprint(userMessageParts...)
	if userMessage == "" {
		userMessage = DefaultUserMessage
	}
	var stack []byte
	if !opts.OmitStack {
		stack = debug.Stack()
	}
	if internalInfo == nil {
		internalInfo = Info{}
	}
	return &err{stack, time.Now(), stdErr, internalInfo, userMessage}
}

type err struct {
	stack        []byte
	time         time.Time
	stdErr       error
	internalInfo Info
	userMessage  string
}

func (e *err) Stack() []byte             { return e.stack }
func (e *err) Time() time.Time           { return e.time }
func (e *err) StandardError() error      { return e.stdErr }
func (e *err) UserMessage() string       { return e.userMessage }
func (e *err) SetUserMessage(msg string) { e.userMessage = msg }
func (e *err) InternalInfo() Info        { return e.internalInfo }
func (e *err) StandardErrorMessage() string {
	if e == nil {
		return ""
	}
	if e.stdErr == nil {
		return ""
	}
	return e.stdErr.Error()
}
func (e *err) LogString() string {
	return fmt.Sprint("Error | UserMessage: ", e.userMessage, " | StandardError: "+e.StandardErrorMessage()+" | Stack: ", string(e.stack), " | tInternalInfo:[", e.internalInfo, "Time:", e.time)
}

func (e *err) String() string { return e.LogString() }
<|endoftext|>


<commit_before>//  Copyright 2018 Google LLC
//  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

//        https://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 overlord

import (
	"testing"

	mpb "github.com/google/minions/proto/minions"
	pb "github.com/google/minions/proto/overlord"
	"golang.org/x/net/context"
	"google.golang.org/grpc"

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

func Test_CreateScan_returnsUuid(t *testing.T) {
	s, err := New(context.Background(), nil)
	require.NoError(t, err)

	resp, err := s.CreateScan(context.Background(), nil)
	require.NoError(t, err)
	require.NotEmpty(t, resp.GetScanId())
}

func Test_CreateScanAndListInterests_returnsInitialInterests(t *testing.T) {
	interest := &mpb.Interest{
		DataType:   mpb.Interest_METADATA_AND_DATA,
		PathRegexp: "/some/regexp",
	}
	interests := []*mappedInterest{
		&mappedInterest{interest, "fake_minion"},
	}
	s, err := New(context.Background(), nil)
	require.NoError(t, err)

	// Hard-plugging some initial interests in the overlord.
	s.initialInterests = interests
	resp, err := s.CreateScan(context.Background(), nil)
	require.NoError(t, err)
	require.Contains(t, resp.GetInterests(), interest)

	// Retrieve non existing scan
	req := &pb.ListInterestsRequest{ScanId: "Totally fake"}
	r, err := s.ListInterests(context.TODO(), req)
	require.Error(t, err)

	// Now retrieve interests for this scan.
	req = &pb.ListInterestsRequest{ScanId: resp.GetScanId()}
	r, err = s.ListInterests(context.TODO(), req)
	require.NoError(t, err)
	require.Contains(t, r.GetInterests(), interest)
}

func Test_INTERNAL_queriesMinions(t *testing.T) {
	i := &mpb.Interest{
		DataType:   mpb.Interest_METADATA_AND_DATA,
		PathRegexp: "/irrelevant",
	}
	interests := []*mpb.Interest{i}
	fm := &fakeMinionClient{interests: interests}
	minionClients := make(map[string]mpb.MinionClient)
	minionClients["fakeMinion"] = fm
	retrievedInterests, err := getInterestsFromMinions(context.Background(), minionClients)
	require.NoError(t, err)
	require.Equal(t, retrievedInterests[0].interest, i)
}

type fakeMinionClient struct {
	interests []*mpb.Interest
}

func (m *fakeMinionClient) ListInitialInterests(ctx context.Context, req *mpb.ListInitialInterestsRequest, opts ...grpc.CallOption) (*mpb.ListInitialInterestsResponse, error) {
	return &mpb.ListInitialInterestsResponse{Interests: m.interests}, nil
}
func (m *fakeMinionClient) AnalyzeFiles(ctx context.Context, req *mpb.AnalyzeFilesRequest, opts ...grpc.CallOption) (*mpb.AnalyzeFilesResponse, error) {
	return nil, nil
}

// TOOD(paradoxengine): the overlord still needs plenty of unit tests
// Cases that are untested: rebuilding chunks, routing results to minion,
// state building through additional interests.
<commit_msg>Rename tests, works on #22<commit_after>//  Copyright 2018 Google LLC
//  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

//        https://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 overlord

import (
	"testing"

	mpb "github.com/google/minions/proto/minions"
	pb "github.com/google/minions/proto/overlord"
	"golang.org/x/net/context"
	"google.golang.org/grpc"

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

func TestCreateScanReturnsUuid(t *testing.T) {
	s, err := New(context.Background(), nil)
	require.NoError(t, err)

	resp, err := s.CreateScan(context.Background(), nil)
	require.NoError(t, err)
	require.NotEmpty(t, resp.GetScanId())
}

func TestCreateScanAndListInterestsReturnsInitialInterests(t *testing.T) {
	interest := &mpb.Interest{
		DataType:   mpb.Interest_METADATA_AND_DATA,
		PathRegexp: "/some/regexp",
	}
	interests := []*mappedInterest{
		&mappedInterest{interest, "fake_minion"},
	}
	s, err := New(context.Background(), nil)
	require.NoError(t, err)

	// Hard-plugging some initial interests in the overlord.
	s.initialInterests = interests
	resp, err := s.CreateScan(context.Background(), nil)
	require.NoError(t, err)
	require.Contains(t, resp.GetInterests(), interest)

	// Retrieve non existing scan
	req := &pb.ListInterestsRequest{ScanId: "Totally fake"}
	r, err := s.ListInterests(context.TODO(), req)
	require.Error(t, err)

	// Now retrieve interests for this scan.
	req = &pb.ListInterestsRequest{ScanId: resp.GetScanId()}
	r, err = s.ListInterests(context.TODO(), req)
	require.NoError(t, err)
	require.Contains(t, r.GetInterests(), interest)
}

func TestInternalBehaviorQueriesMinions(t *testing.T) {
	i := &mpb.Interest{
		DataType:   mpb.Interest_METADATA_AND_DATA,
		PathRegexp: "/irrelevant",
	}
	interests := []*mpb.Interest{i}
	fm := &fakeMinionClient{interests: interests}
	minionClients := make(map[string]mpb.MinionClient)
	minionClients["fakeMinion"] = fm
	retrievedInterests, err := getInterestsFromMinions(context.Background(), minionClients)
	require.NoError(t, err)
	require.Equal(t, retrievedInterests[0].interest, i)
}

type fakeMinionClient struct {
	interests []*mpb.Interest
}

func (m *fakeMinionClient) ListInitialInterests(ctx context.Context, req *mpb.ListInitialInterestsRequest, opts ...grpc.CallOption) (*mpb.ListInitialInterestsResponse, error) {
	return &mpb.ListInitialInterestsResponse{Interests: m.interests}, nil
}
func (m *fakeMinionClient) AnalyzeFiles(ctx context.Context, req *mpb.AnalyzeFilesRequest, opts ...grpc.CallOption) (*mpb.AnalyzeFilesResponse, error) {
	return nil, nil
}

// TOOD(paradoxengine): the overlord still needs plenty of unit tests
// Cases that are untested: rebuilding chunks, routing results to minion,
// state building through additional interests.
<|endoftext|>


<commit_before>package defaults

import (
	"io/ioutil"
	"os"
	"testing"

	"github.com/goreleaser/goreleaser/config"
	"github.com/goreleaser/goreleaser/context"
	"github.com/stretchr/testify/assert"
)

func TestDescription(t *testing.T) {
	assert.NotEmpty(t, Pipe{}.Description())
}

func TestFillBasicData(t *testing.T) {
	var assert = assert.New(t)
	var ctx = &context.Context{
		Config: config.Project{},
	}

	assert.NoError(Pipe{}.Run(ctx))
	assert.Equal("goreleaser", ctx.Config.Release.GitHub.Owner)
	assert.Equal("goreleaser", ctx.Config.Release.GitHub.Name)
	assert.NotEmpty(ctx.Config.Builds)
	assert.Equal("goreleaser", ctx.Config.Builds[0].Binary)
	assert.Equal(".", ctx.Config.Builds[0].Main)
	assert.Contains(ctx.Config.Builds[0].Goos, "darwin")
	assert.Contains(ctx.Config.Builds[0].Goos, "linux")
	assert.Contains(ctx.Config.Builds[0].Goarch, "386")
	assert.Contains(ctx.Config.Builds[0].Goarch, "amd64")
	assert.Equal("tar.gz", ctx.Config.Archive.Format)
	assert.Contains(ctx.Config.Brew.Install, "bin.install \"goreleaser\"")
	assert.NotEmpty(
		ctx.Config.Archive.NameTemplate,
		ctx.Config.Builds[0].Ldflags,
		ctx.Config.Archive.Files,
	)
}

func TestFillPartial(t *testing.T) {
	var assert = assert.New(t)

	var ctx = &context.Context{
		Config: config.Project{
			Release: config.Release{
				GitHub: config.Repo{
					Owner: "goreleaser",
					Name:  "test",
				},
			},
			Archive: config.Archive{
				Files: []string{
					"glob/*",
				},
			},
			Builds: []config.Build{
				{Binary: "testreleaser"},
				{Goos: []string{"linux"}},
				{
					Binary: "another",
					Ignore: []config.IgnoredBuild{
						{Goos: "darwin", Goarch: "amd64"},
					},
				},
			},
		},
	}
	assert.NoError(Pipe{}.Run(ctx))
	assert.Len(ctx.Config.Archive.Files, 1)
	assert.Equal(`bin.install "testreleaser"`, ctx.Config.Brew.Install)
}

func TestFillSingleBuild(t *testing.T) {
	var assert = assert.New(t)

	var ctx = &context.Context{
		Config: config.Project{
			SingleBuild: config.Build{
				Main: "testreleaser",
			},
		},
	}
	assert.NoError(Pipe{}.Run(ctx))
	assert.Len(ctx.Config.Builds, 1)
	assert.Equal(ctx.Config.Builds[0].Binary, "goreleaser")
}

func TestNotAGitRepo(t *testing.T) {
	var assert = assert.New(t)
	folder, err := ioutil.TempDir("", "goreleasertest")
	assert.NoError(err)
	previous, err := os.Getwd()
	assert.NoError(err)
	assert.NoError(os.Chdir(folder))
	defer func() {
		assert.NoError(os.Chdir(previous))
	}()
	var ctx = &context.Context{
		Config: config.Project{},
	}
	assert.Error(Pipe{}.Run(ctx))
}
<commit_msg>defaults tests<commit_after>package defaults

import (
	"io/ioutil"
	"os"
	"testing"

	"github.com/goreleaser/goreleaser/config"
	"github.com/goreleaser/goreleaser/context"
	"github.com/stretchr/testify/assert"
)

func TestDescription(t *testing.T) {
	assert.NotEmpty(t, Pipe{}.Description())
}

func TestFillBasicData(t *testing.T) {
	var assert = assert.New(t)
	var ctx = &context.Context{
		Config: config.Project{},
	}

	assert.NoError(Pipe{}.Run(ctx))
	assert.Equal("goreleaser", ctx.Config.Release.GitHub.Owner)
	assert.Equal("goreleaser", ctx.Config.Release.GitHub.Name)
	assert.NotEmpty(ctx.Config.Builds)
	assert.Equal("goreleaser", ctx.Config.Builds[0].Binary)
	assert.Equal(".", ctx.Config.Builds[0].Main)
	assert.Contains(ctx.Config.Builds[0].Goos, "darwin")
	assert.Contains(ctx.Config.Builds[0].Goos, "linux")
	assert.Contains(ctx.Config.Builds[0].Goarch, "386")
	assert.Contains(ctx.Config.Builds[0].Goarch, "amd64")
	assert.Equal("tar.gz", ctx.Config.Archive.Format)
	assert.Contains(ctx.Config.Brew.Install, "bin.install \"goreleaser\"")
	assert.Empty(ctx.Config.Dockers)
	assert.NotEmpty(
		ctx.Config.Archive.NameTemplate,
		ctx.Config.Builds[0].Ldflags,
		ctx.Config.Archive.Files,
	)
}

func TestFillPartial(t *testing.T) {
	var assert = assert.New(t)

	var ctx = &context.Context{
		Config: config.Project{
			Release: config.Release{
				GitHub: config.Repo{
					Owner: "goreleaser",
					Name:  "test",
				},
			},
			Archive: config.Archive{
				Files: []string{
					"glob/*",
				},
			},
			Builds: []config.Build{
				{Binary: "testreleaser"},
				{Goos: []string{"linux"}},
				{
					Binary: "another",
					Ignore: []config.IgnoredBuild{
						{Goos: "darwin", Goarch: "amd64"},
					},
				},
			},
			Dockers: []config.Docker{
				{Image: "a/b"},
			},
		},
	}
	assert.NoError(Pipe{}.Run(ctx))
	assert.Len(ctx.Config.Archive.Files, 1)
	assert.Equal(`bin.install "testreleaser"`, ctx.Config.Brew.Install)
	assert.NotEmpty(ctx.Config.Dockers[0].Binary)
	assert.NotEmpty(ctx.Config.Dockers[0].Goos)
	assert.NotEmpty(ctx.Config.Dockers[0].Goarch)
	assert.NotEmpty(ctx.Config.Dockers[0].Dockerfile)
	assert.Empty(ctx.Config.Dockers[0].Goarm)
}

func TestFillSingleBuild(t *testing.T) {
	var assert = assert.New(t)

	var ctx = &context.Context{
		Config: config.Project{
			SingleBuild: config.Build{
				Main: "testreleaser",
			},
		},
	}
	assert.NoError(Pipe{}.Run(ctx))
	assert.Len(ctx.Config.Builds, 1)
	assert.Equal(ctx.Config.Builds[0].Binary, "goreleaser")
}

func TestNotAGitRepo(t *testing.T) {
	var assert = assert.New(t)
	folder, err := ioutil.TempDir("", "goreleasertest")
	assert.NoError(err)
	previous, err := os.Getwd()
	assert.NoError(err)
	assert.NoError(os.Chdir(folder))
	defer func() {
		assert.NoError(os.Chdir(previous))
	}()
	var ctx = &context.Context{
		Config: config.Project{},
	}
	assert.Error(Pipe{}.Run(ctx))
}
<|endoftext|>


<commit_before>// Package aws generates Machine objects for aws.
package aws

import (
	"fmt"

	"github.com/pkg/errors"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/util/sets"
	"k8s.io/utils/pointer"
	awsprovider "sigs.k8s.io/cluster-api-provider-aws/pkg/apis/awsproviderconfig/v1alpha1"
	clusterapi "sigs.k8s.io/cluster-api/pkg/apis/cluster/v1alpha1"

	"github.com/openshift/installer/pkg/types"
)

// Machines returns a list of machines for a machinepool.
func Machines(config *types.InstallConfig, pool *types.MachinePool, role, userDataSecret string) ([]clusterapi.Machine, error) {
	if configPlatform := config.Platform.Name(); configPlatform != types.PlatformNameAWS {
		return nil, fmt.Errorf("non-AWS configuration: %q", configPlatform)
	}
	if poolPlatform := pool.Platform.Name(); poolPlatform != types.PlatformNameAWS {
		return nil, fmt.Errorf("non-AWS machine-pool: %q", poolPlatform)
	}
	clustername := config.ObjectMeta.Name
	platform := config.Platform.AWS
	mpool := pool.Platform.AWS
	azs := mpool.Zones

	total := int64(1)
	if pool.Replicas != nil {
		total = *pool.Replicas
	}
	numOfAZs := int64(len(azs))
	var machines []clusterapi.Machine
	for idx := range azs {
		replicas := int32(total / numOfAZs)
		if int64(idx) < total%numOfAZs {
			replicas++
		}

		provider, err := provider(config.ClusterID, clustername, platform, mpool, idx, role, userDataSecret)
		if err != nil {
			return nil, errors.Wrap(err, "failed to create provider")
		}
		machine := clusterapi.Machine{
			TypeMeta: metav1.TypeMeta{
				APIVersion: "cluster.k8s.io/v1alpha1",
				Kind:       "Machine",
			},
			ObjectMeta: metav1.ObjectMeta{
				Namespace: "openshift-cluster-api",
				Name:      fmt.Sprintf("%s-%s-%d", clustername, pool.Name, idx),
				Labels: map[string]string{
					"sigs.k8s.io/cluster-api-cluster":      clustername,
					"sigs.k8s.io/cluster-api-machine-role": role,
					"sigs.k8s.io/cluster-api-machine-type": role,
				},
			},
			Spec: clusterapi.MachineSpec{
				ProviderConfig: clusterapi.ProviderConfig{
					Value: &runtime.RawExtension{Object: provider},
				},
				// we don't need to set Versions, because we control those via operators.
			},
		}

		machines = append(machines, machine)
	}

	return machines, nil
}

func provider(clusterID, clusterName string, platform *types.AWSPlatform, mpool *types.AWSMachinePoolPlatform, azIdx int, role, userDataSecret string) (*awsprovider.AWSMachineProviderConfig, error) {
	az := mpool.Zones[azIdx]
	tags, err := tagsFromUserTags(clusterID, clusterName, platform.UserTags)
	if err != nil {
		return nil, errors.Wrap(err, "failed to create awsprovider.TagSpecifications from UserTags")
	}
	return &awsprovider.AWSMachineProviderConfig{
		TypeMeta: metav1.TypeMeta{
			APIVersion: "aws.cluster.k8s.io/v1alpha1",
			Kind:       "AWSMachineProviderConfig",
		},
		InstanceType:       mpool.InstanceType,
		AMI:                awsprovider.AWSResourceReference{ID: &mpool.AMIID},
		Tags:               tags,
		IAMInstanceProfile: &awsprovider.AWSResourceReference{ID: pointer.StringPtr(fmt.Sprintf("%s-%s-profile", clusterName, role))},
		UserDataSecret:     &corev1.LocalObjectReference{Name: userDataSecret},
		Subnet: awsprovider.AWSResourceReference{
			Filters: []awsprovider.Filter{{
				Name:   "tag:Name",
				Values: []string{fmt.Sprintf("%s-%s-%s", clusterName, role, az)},
			}},
		},
		Placement: awsprovider.Placement{Region: platform.Region, AvailabilityZone: az},
		SecurityGroups: []awsprovider.AWSResourceReference{{
			Filters: []awsprovider.Filter{{
				Name:   "tag:Name",
				Values: []string{fmt.Sprintf("%s_%s_sg", clusterName, role)},
			}},
		}},
	}, nil
}

func tagsFromUserTags(clusterID, clusterName string, usertags map[string]string) ([]awsprovider.TagSpecification, error) {
	tags := []awsprovider.TagSpecification{
		{Name: "tectonicClusterID", Value: clusterID},
		{Name: fmt.Sprintf("kubernetes.io/cluster/%s", clusterName), Value: "owned"},
	}
	forbiddenTags := sets.NewString()
	for idx := range tags {
		forbiddenTags.Insert(tags[idx].Name)
	}
	for k, v := range usertags {
		if forbiddenTags.Has(k) {
			return nil, fmt.Errorf("user tags may not clobber %s", k)
		}
		tags = append(tags, awsprovider.TagSpecification{Name: k, Value: v})
	}
	return tags, nil
}
<commit_msg>asset/machines/aws: fix num of machine objects created.<commit_after>// Package aws generates Machine objects for aws.
package aws

import (
	"fmt"

	"github.com/pkg/errors"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/util/sets"
	"k8s.io/utils/pointer"
	awsprovider "sigs.k8s.io/cluster-api-provider-aws/pkg/apis/awsproviderconfig/v1alpha1"
	clusterapi "sigs.k8s.io/cluster-api/pkg/apis/cluster/v1alpha1"

	"github.com/openshift/installer/pkg/types"
)

// Machines returns a list of machines for a machinepool.
func Machines(config *types.InstallConfig, pool *types.MachinePool, role, userDataSecret string) ([]clusterapi.Machine, error) {
	if configPlatform := config.Platform.Name(); configPlatform != types.PlatformNameAWS {
		return nil, fmt.Errorf("non-AWS configuration: %q", configPlatform)
	}
	if poolPlatform := pool.Platform.Name(); poolPlatform != types.PlatformNameAWS {
		return nil, fmt.Errorf("non-AWS machine-pool: %q", poolPlatform)
	}
	clustername := config.ObjectMeta.Name
	platform := config.Platform.AWS
	mpool := pool.Platform.AWS
	azs := mpool.Zones

	total := int64(1)
	if pool.Replicas != nil {
		total = *pool.Replicas
	}
	var machines []clusterapi.Machine
	for idx := int64(0); idx < total; idx++ {
		azIndex := int(idx) % len(azs)
		provider, err := provider(config.ClusterID, clustername, platform, mpool, azIndex, role, userDataSecret)
		if err != nil {
			return nil, errors.Wrap(err, "failed to create provider")
		}
		machine := clusterapi.Machine{
			TypeMeta: metav1.TypeMeta{
				APIVersion: "cluster.k8s.io/v1alpha1",
				Kind:       "Machine",
			},
			ObjectMeta: metav1.ObjectMeta{
				Namespace: "openshift-cluster-api",
				Name:      fmt.Sprintf("%s-%s-%d", clustername, pool.Name, idx),
				Labels: map[string]string{
					"sigs.k8s.io/cluster-api-cluster":      clustername,
					"sigs.k8s.io/cluster-api-machine-role": role,
					"sigs.k8s.io/cluster-api-machine-type": role,
				},
			},
			Spec: clusterapi.MachineSpec{
				ProviderConfig: clusterapi.ProviderConfig{
					Value: &runtime.RawExtension{Object: provider},
				},
				// we don't need to set Versions, because we control those via operators.
			},
		}

		machines = append(machines, machine)
	}

	return machines, nil
}

func provider(clusterID, clusterName string, platform *types.AWSPlatform, mpool *types.AWSMachinePoolPlatform, azIdx int, role, userDataSecret string) (*awsprovider.AWSMachineProviderConfig, error) {
	az := mpool.Zones[azIdx]
	tags, err := tagsFromUserTags(clusterID, clusterName, platform.UserTags)
	if err != nil {
		return nil, errors.Wrap(err, "failed to create awsprovider.TagSpecifications from UserTags")
	}
	return &awsprovider.AWSMachineProviderConfig{
		TypeMeta: metav1.TypeMeta{
			APIVersion: "aws.cluster.k8s.io/v1alpha1",
			Kind:       "AWSMachineProviderConfig",
		},
		InstanceType:       mpool.InstanceType,
		AMI:                awsprovider.AWSResourceReference{ID: &mpool.AMIID},
		Tags:               tags,
		IAMInstanceProfile: &awsprovider.AWSResourceReference{ID: pointer.StringPtr(fmt.Sprintf("%s-%s-profile", clusterName, role))},
		UserDataSecret:     &corev1.LocalObjectReference{Name: userDataSecret},
		Subnet: awsprovider.AWSResourceReference{
			Filters: []awsprovider.Filter{{
				Name:   "tag:Name",
				Values: []string{fmt.Sprintf("%s-%s-%s", clusterName, role, az)},
			}},
		},
		Placement: awsprovider.Placement{Region: platform.Region, AvailabilityZone: az},
		SecurityGroups: []awsprovider.AWSResourceReference{{
			Filters: []awsprovider.Filter{{
				Name:   "tag:Name",
				Values: []string{fmt.Sprintf("%s_%s_sg", clusterName, role)},
			}},
		}},
	}, nil
}

func tagsFromUserTags(clusterID, clusterName string, usertags map[string]string) ([]awsprovider.TagSpecification, error) {
	tags := []awsprovider.TagSpecification{
		{Name: "tectonicClusterID", Value: clusterID},
		{Name: fmt.Sprintf("kubernetes.io/cluster/%s", clusterName), Value: "owned"},
	}
	forbiddenTags := sets.NewString()
	for idx := range tags {
		forbiddenTags.Insert(tags[idx].Name)
	}
	for k, v := range usertags {
		if forbiddenTags.Has(k) {
			return nil, fmt.Errorf("user tags may not clobber %s", k)
		}
		tags = append(tags, awsprovider.TagSpecification{Name: k, Value: v})
	}
	return tags, nil
}
<|endoftext|>


<commit_before>package github

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"mime"
	"net/http"

	kapi "k8s.io/kubernetes/pkg/api"

	"github.com/golang/glog"
	"github.com/openshift/origin/pkg/build/api"
	"github.com/openshift/origin/pkg/build/webhook"
)

var (
	ErrNoGitHubEvent = errors.New("missing X-GitHub-Event or X-Gogs-Event")
)

// WebHook used for processing github webhook requests.
type WebHook struct{}

// New returns github webhook plugin.
func New() *WebHook {
	return &WebHook{}
}

type commit struct {
	ID        string                `json:"id,omitempty"`
	Author    api.SourceControlUser `json:"author,omitempty"`
	Committer api.SourceControlUser `json:"committer,omitempty"`
	Message   string                `json:"message,omitempty"`
}

type pushEvent struct {
	Ref        string `json:"ref,omitempty"`
	After      string `json:"after,omitempty"`
	HeadCommit commit `json:"head_commit,omitempty"`
}

// Extract services webhooks from github.com
func (p *WebHook) Extract(buildCfg *api.BuildConfig, secret, path string, req *http.Request) (revision *api.SourceRevision, envvars []kapi.EnvVar, proceed bool, err error) {
	triggers, err := webhook.FindTriggerPolicy(api.GitHubWebHookBuildTriggerType, buildCfg)
	if err != nil {
		return revision, envvars, proceed, err
	}
	glog.V(4).Infof("Checking if the provided secret for BuildConfig %s/%s matches", buildCfg.Namespace, buildCfg.Name)

	if _, err = webhook.ValidateWebHookSecret(triggers, secret); err != nil {
		return revision, envvars, proceed, err
	}

	glog.V(4).Infof("Verifying build request for BuildConfig %s/%s", buildCfg.Namespace, buildCfg.Name)
	if err = verifyRequest(req); err != nil {
		return revision, envvars, proceed, err
	}
	method := getEvent(req.Header)
	if method != "ping" && method != "push" {
		return revision, envvars, proceed, fmt.Errorf("Unknown X-GitHub-Event or X-Gogs-Event %s", method)
	}
	if method == "ping" {
		return revision, envvars, proceed, err
	}
	body, err := ioutil.ReadAll(req.Body)
	if err != nil {
		return revision, envvars, proceed, err
	}
	var event pushEvent
	if err = json.Unmarshal(body, &event); err != nil {
		return revision, envvars, proceed, err
	}
	if !webhook.GitRefMatches(event.Ref, webhook.DefaultConfigRef, &buildCfg.Spec.Source) {
		glog.V(2).Infof("Skipping build for BuildConfig %s/%s.  Branch reference from '%s' does not match configuration", buildCfg.Namespace, buildCfg, event)
		return revision, envvars, proceed, err
	}

	revision = &api.SourceRevision{
		Git: &api.GitSourceRevision{
			Commit:    event.HeadCommit.ID,
			Author:    event.HeadCommit.Author,
			Committer: event.HeadCommit.Committer,
			Message:   event.HeadCommit.Message,
		},
	}
	return revision, envvars, true, err
}

func verifyRequest(req *http.Request) error {
	if method := req.Method; method != "POST" {
		return fmt.Errorf("unsupported HTTP method %s", method)
	}
	contentType := req.Header.Get("Content-Type")
	mediaType, _, err := mime.ParseMediaType(contentType)
	if err != nil {
		return fmt.Errorf("non-parseable Content-Type %s (%s)", contentType, err)
	}
	if mediaType != "application/json" {
		return fmt.Errorf("unsupported Content-Type %s", contentType)
	}
	if len(getEvent(req.Header)) == 0 {
		return ErrNoGitHubEvent
	}
	return nil
}

func getEvent(header http.Header) string {
	event := header.Get("X-GitHub-Event")
	if len(event) == 0 {
		event = header.Get("X-Gogs-Event")
	}
	return event
}
<commit_msg>Add support for GitLab Push Event<commit_after>package github

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"mime"
	"net/http"

	kapi "k8s.io/kubernetes/pkg/api"

	"github.com/golang/glog"
	"github.com/openshift/origin/pkg/build/api"
	"github.com/openshift/origin/pkg/build/webhook"
)

var (
	ErrNoGitHubEvent = errors.New("missing X-GitHub-Event, X-Gogs-Event or X-Gitlab-Event")
)

// WebHook used for processing github webhook requests.
type WebHook struct{}

// New returns github webhook plugin.
func New() *WebHook {
	return &WebHook{}
}

type commit struct {
	ID        string                `json:"id,omitempty"`
	Author    api.SourceControlUser `json:"author,omitempty"`
	Committer api.SourceControlUser `json:"committer,omitempty"`
	Message   string                `json:"message,omitempty"`
}

type pushEvent struct {
	Ref        string `json:"ref,omitempty"`
	After      string `json:"after,omitempty"`
	HeadCommit commit `json:"head_commit,omitempty"`
}

// Extract services webhooks from github.com
func (p *WebHook) Extract(buildCfg *api.BuildConfig, secret, path string, req *http.Request) (revision *api.SourceRevision, envvars []kapi.EnvVar, proceed bool, err error) {
	triggers, err := webhook.FindTriggerPolicy(api.GitHubWebHookBuildTriggerType, buildCfg)
	if err != nil {
		return revision, envvars, proceed, err
	}
	glog.V(4).Infof("Checking if the provided secret for BuildConfig %s/%s matches", buildCfg.Namespace, buildCfg.Name)

	if _, err = webhook.ValidateWebHookSecret(triggers, secret); err != nil {
		return revision, envvars, proceed, err
	}

	glog.V(4).Infof("Verifying build request for BuildConfig %s/%s", buildCfg.Namespace, buildCfg.Name)
	if err = verifyRequest(req); err != nil {
		return revision, envvars, proceed, err
	}
	method := getEvent(req.Header)
	if method != "ping" && method != "push" && method != "Push Hook" {
		return revision, envvars, proceed, fmt.Errorf("Unknown X-GitHub-Event, X-Gogs-Event or X-Gitlab-Event %s", method)
	}
	if method == "ping" {
		return revision, envvars, proceed, err
	}
	body, err := ioutil.ReadAll(req.Body)
	if err != nil {
		return revision, envvars, proceed, err
	}
	var event pushEvent
	if err = json.Unmarshal(body, &event); err != nil {
		return revision, envvars, proceed, err
	}
	if !webhook.GitRefMatches(event.Ref, webhook.DefaultConfigRef, &buildCfg.Spec.Source) {
		glog.V(2).Infof("Skipping build for BuildConfig %s/%s.  Branch reference from '%s' does not match configuration", buildCfg.Namespace, buildCfg, event)
		return revision, envvars, proceed, err
	}

	revision = &api.SourceRevision{
		Git: &api.GitSourceRevision{
			Commit:    event.HeadCommit.ID,
			Author:    event.HeadCommit.Author,
			Committer: event.HeadCommit.Committer,
			Message:   event.HeadCommit.Message,
		},
	}
	return revision, envvars, true, err
}

func verifyRequest(req *http.Request) error {
	if method := req.Method; method != "POST" {
		return fmt.Errorf("unsupported HTTP method %s", method)
	}
	contentType := req.Header.Get("Content-Type")
	mediaType, _, err := mime.ParseMediaType(contentType)
	if err != nil {
		return fmt.Errorf("non-parseable Content-Type %s (%s)", contentType, err)
	}
	if mediaType != "application/json" {
		return fmt.Errorf("unsupported Content-Type %s", contentType)
	}
	if len(getEvent(req.Header)) == 0 {
		return ErrNoGitHubEvent
	}
	return nil
}

func getEvent(header http.Header) string {
	event := header.Get("X-GitHub-Event")
	if len(event) == 0 {
		event = header.Get("X-Gogs-Event")
	}
	if len(event) == 0 {
		event = header.Get("X-Gitlab-Event")
	}
	return event
}
<|endoftext|>


<commit_before>package crmanager

import (
	"fmt"
	"reflect"
	"strings"
	"time"

	"github.com/F5Networks/k8s-bigip-ctlr/pkg/pollers"
	"github.com/F5Networks/k8s-bigip-ctlr/pkg/vxlan"

	log "github.com/F5Networks/k8s-bigip-ctlr/pkg/vlogger"
	v1 "k8s.io/api/core/v1"
)

func (crMgr *CRManager) SetupNodePolling(
	nodePollInterval int,
	nodeLabelSelector string,
	vxlanMode string,
	vxlanName string,
) error {
	intervalFactor := time.Duration(nodePollInterval)
	crMgr.nodePoller = pollers.NewNodePoller(crMgr.kubeClient, intervalFactor*time.Second, nodeLabelSelector)

	// Register appMgr to watch for node updates to keep track of watched nodes
	err := crMgr.nodePoller.RegisterListener(crMgr.ProcessNodeUpdate)
	if nil != err {
		return fmt.Errorf("error registering node update listener: %v",
			err)
	}

	if 0 != len(vxlanMode) {
		// If partition is part of vxlanName, extract just the tunnel name
		tunnelName := vxlanName
		cleanPath := strings.TrimLeft(vxlanName, "/")
		slashPos := strings.Index(cleanPath, "/")
		if slashPos != -1 {
			tunnelName = cleanPath[slashPos+1:]
		}
		vxMgr, err := vxlan.NewVxlanMgr(
			vxlanMode,
			tunnelName,
			crMgr.UseNodeInternal,
			crMgr.Agent.ConfigWriter,
			crMgr.Agent.EventChan,
		)
		if nil != err {
			return fmt.Errorf("error creating vxlan manager: %v", err)
		}

		// Register vxMgr to watch for node updates to process fdb records
		err = crMgr.nodePoller.RegisterListener(vxMgr.ProcessNodeUpdate)
		if nil != err {
			return fmt.Errorf("error registering node update listener for vxlan mode: %v",
				err)
		}
		if crMgr.Agent.EventChan != nil {
			// It handles arp entries related to PoolMembers
			vxMgr.ProcessAppmanagerEvents(crMgr.kubeClient)
		}
	}

	return nil
}

type Node struct {
	Name   string
	Addr   string
	Labels map[string]string
}

// Check for a change in Node state
func (crMgr *CRManager) ProcessNodeUpdate(
	obj interface{}, err error,
) {
	if nil != err {
		log.Warningf("Unable to get list of nodes, err=%+v", err)
		return
	}

	newNodes, err := crMgr.getNodes(obj)
	if nil != err {
		log.Warningf("Unable to get list of nodes, err=%+v", err)
		return
	}

	// Only check for updates once we are out of initial state
	if !crMgr.initState {
		// Compare last set of nodes with new one
		if !reflect.DeepEqual(newNodes, crMgr.oldNodes) {
			log.Infof("ProcessNodeUpdate: Change in Node state detected")

			for _, ns := range crMgr.namespaces {
				virtuals := crMgr.getAllVirtualServers(ns)
				for _, virtual := range virtuals {
					qKey := &rqKey{
						ns,
						VirtualServer,
						virtual.ObjectMeta.Name,
						virtual,
						false,
					}
					crMgr.rscQueue.Add(qKey)
				}
			}

			// Update node cache
			crMgr.oldNodes = newNodes
		}
	} else {
		// Initialize crMgr nodes on our first pass through
		crMgr.oldNodes = newNodes
	}
}

// Return a copy of the node cache
func (crMgr *CRManager) getNodesFromCache() []Node {
	nodes := make([]Node, len(crMgr.oldNodes))
	copy(nodes, crMgr.oldNodes)

	return nodes
}

// Get a list of Node addresses
func (crMgr *CRManager) getNodes(
	obj interface{},
) ([]Node, error) {

	nodes, ok := obj.([]v1.Node)
	if false == ok {
		return nil,
			fmt.Errorf("poll update unexpected type, interface is not []v1.Node")
	}

	watchedNodes := []Node{}

	var addrType v1.NodeAddressType
	if crMgr.UseNodeInternal {
		addrType = v1.NodeInternalIP
	} else {
		addrType = v1.NodeExternalIP
	}

	// Append list of nodes to watchedNodes
	for _, node := range nodes {
		nodeAddrs := node.Status.Addresses
		for _, addr := range nodeAddrs {
			if addr.Type == addrType {
				n := Node{
					Name:   node.ObjectMeta.Name,
					Addr:   addr.Address,
					Labels: make(map[string]string),
				}
				for k, v := range node.ObjectMeta.Labels {
					n.Labels[k] = v
				}
				watchedNodes = append(watchedNodes, n)
			}
		}
	}

	return watchedNodes, nil
}

func (crMgr *CRManager) getNodesWithLabel(
	nodeMemberLabel string,
) []Node {
	allNodes := crMgr.getNodesFromCache()

	label := strings.Split(nodeMemberLabel, "=")
	if len(label) != 2 {
		log.Warningf("Invalid NodeMemberLabel: %v", nodeMemberLabel)
		return nil
	}
	labelKey := label[0]
	labelValue := label[1]
	var nodes []Node
	for _, node := range allNodes {
		if node.Labels[labelKey] == labelValue {
			nodes = append(nodes, node)
		}
	}
	return nodes
}
<commit_msg>[CRD] Handle NodeLabel Changes<commit_after>package crmanager

import (
	"fmt"
	cisapiv1 "github.com/F5Networks/k8s-bigip-ctlr/config/apis/cis/v1"
	"reflect"
	"strings"
	"time"

	"github.com/F5Networks/k8s-bigip-ctlr/pkg/pollers"
	"github.com/F5Networks/k8s-bigip-ctlr/pkg/vxlan"

	log "github.com/F5Networks/k8s-bigip-ctlr/pkg/vlogger"
	v1 "k8s.io/api/core/v1"
)

func (crMgr *CRManager) SetupNodePolling(
	nodePollInterval int,
	nodeLabelSelector string,
	vxlanMode string,
	vxlanName string,
) error {
	intervalFactor := time.Duration(nodePollInterval)
	crMgr.nodePoller = pollers.NewNodePoller(crMgr.kubeClient, intervalFactor*time.Second, nodeLabelSelector)

	// Register appMgr to watch for node updates to keep track of watched nodes
	err := crMgr.nodePoller.RegisterListener(crMgr.ProcessNodeUpdate)
	if nil != err {
		return fmt.Errorf("error registering node update listener: %v",
			err)
	}

	if 0 != len(vxlanMode) {
		// If partition is part of vxlanName, extract just the tunnel name
		tunnelName := vxlanName
		cleanPath := strings.TrimLeft(vxlanName, "/")
		slashPos := strings.Index(cleanPath, "/")
		if slashPos != -1 {
			tunnelName = cleanPath[slashPos+1:]
		}
		vxMgr, err := vxlan.NewVxlanMgr(
			vxlanMode,
			tunnelName,
			crMgr.UseNodeInternal,
			crMgr.Agent.ConfigWriter,
			crMgr.Agent.EventChan,
		)
		if nil != err {
			return fmt.Errorf("error creating vxlan manager: %v", err)
		}

		// Register vxMgr to watch for node updates to process fdb records
		err = crMgr.nodePoller.RegisterListener(vxMgr.ProcessNodeUpdate)
		if nil != err {
			return fmt.Errorf("error registering node update listener for vxlan mode: %v",
				err)
		}
		if crMgr.Agent.EventChan != nil {
			// It handles arp entries related to PoolMembers
			vxMgr.ProcessAppmanagerEvents(crMgr.kubeClient)
		}
	}

	return nil
}

type Node struct {
	Name   string
	Addr   string
	Labels map[string]string
}

// Check for a change in Node state
func (crMgr *CRManager) ProcessNodeUpdate(
	obj interface{}, err error,
) {
	if nil != err {
		log.Warningf("Unable to get list of nodes, err=%+v", err)
		return
	}

	newNodes, err := crMgr.getNodes(obj)
	if nil != err {
		log.Warningf("Unable to get list of nodes, err=%+v", err)
		return
	}

	// Only check for updates once we are out of initial state
	if !crMgr.initState {
		// Compare last set of nodes with new one
		if !reflect.DeepEqual(newNodes, crMgr.oldNodes) {
			log.Debugf("Processing Node Updates")
			// Handle NodeLabelUpdates
			if crMgr.ControllerMode == NodePortMode {
				if crMgr.watchingAllNamespaces() {
					crInf, _ := crMgr.getNamespaceInformer("")
					virtuals := crInf.vsInformer.GetIndexer().List()
					if len(virtuals) != 0 {
						for _, virtual := range virtuals {
							vs := virtual.(*cisapiv1.VirtualServer)
							qKey := &rqKey{
								vs.ObjectMeta.Namespace,
								VirtualServer,
								vs.ObjectMeta.Name,
								vs,
								false,
							}
							crMgr.rscQueue.Add(qKey)
						}
					}
				} else {
					for _, ns := range crMgr.namespaces {
						virtuals := crMgr.getAllVirtualServers(ns)
						for _, virtual := range virtuals {
							qKey := &rqKey{
								ns,
								VirtualServer,
								virtual.ObjectMeta.Name,
								virtual,
								false,
							}
							crMgr.rscQueue.Add(qKey)
						}
					}
				}
			}
			// Update node cache
			crMgr.oldNodes = newNodes
		}
	} else {
		// Initialize crMgr nodes on our first pass through
		crMgr.oldNodes = newNodes
	}
}

// Return a copy of the node cache
func (crMgr *CRManager) getNodesFromCache() []Node {
	nodes := make([]Node, len(crMgr.oldNodes))
	copy(nodes, crMgr.oldNodes)

	return nodes
}

// Get a list of Node addresses
func (crMgr *CRManager) getNodes(
	obj interface{},
) ([]Node, error) {

	nodes, ok := obj.([]v1.Node)
	if false == ok {
		return nil,
			fmt.Errorf("poll update unexpected type, interface is not []v1.Node")
	}

	watchedNodes := []Node{}

	var addrType v1.NodeAddressType
	if crMgr.UseNodeInternal {
		addrType = v1.NodeInternalIP
	} else {
		addrType = v1.NodeExternalIP
	}

	// Append list of nodes to watchedNodes
	for _, node := range nodes {
		nodeAddrs := node.Status.Addresses
		for _, addr := range nodeAddrs {
			if addr.Type == addrType {
				n := Node{
					Name:   node.ObjectMeta.Name,
					Addr:   addr.Address,
					Labels: make(map[string]string),
				}
				for k, v := range node.ObjectMeta.Labels {
					n.Labels[k] = v
				}
				watchedNodes = append(watchedNodes, n)
			}
		}
	}

	return watchedNodes, nil
}

func (crMgr *CRManager) getNodesWithLabel(
	nodeMemberLabel string,
) []Node {
	allNodes := crMgr.getNodesFromCache()

	label := strings.Split(nodeMemberLabel, "=")
	if len(label) != 2 {
		log.Warningf("Invalid NodeMemberLabel: %v", nodeMemberLabel)
		return nil
	}
	labelKey := label[0]
	labelValue := label[1]
	var nodes []Node
	for _, node := range allNodes {
		if node.Labels[labelKey] == labelValue {
			nodes = append(nodes, node)
		}
	}
	return nodes
}
<|endoftext|>