<commit_before>package ginmon

import (
	"net/http"
	"net/http/httptest"
	"net/url"
	"testing"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/assert"
)

const TestMode string = "test"

const checkMark = "\u2713"
const ballotX = "\u2717"

const testpath = "/foo/bar"

func internalGinCtx() *gin.Context {
	return &gin.Context{
		Request: &http.Request{
			URL: &url.URL{
				Path: testpath,
			},
		},
	}
}

func Test_Inc(t *testing.T) {
	ca := NewCounterAspect()
	ca.StartTimer(1 * time.Second)
	expect := 1
	ca.inc <- tuple{
		path: testpath,
		code: 404,
	}
	ca.reset()
	if assert.Equal(t, ca.RequestsSum, expect, "Incrementation of counter does not work, expect %d but got %d %s",
		expect, ca.RequestsSum, ballotX) {
		t.Logf("Incrementation of counter works, expect %d and git %d %s",
			expect, ca.RequestsSum, checkMark)
	}
}

func Test_GetStats(t *testing.T) {
	ca := NewCounterAspect()
	ca.StartTimer(1 * time.Second)
	if assert.NotNil(t, ca.GetStats(), "Return of Getstats() should not be nil") {
		t.Logf("Should be an interface %s", checkMark)
	}

	newCa := ca.GetStats().(CounterAspect)
	expect := 0
	if assert.Equal(t, newCa.RequestsSum, expect, "Return of Getstats() does not work, expect %d but got %d %s",
		expect, newCa.RequestsSum, ballotX) {
		t.Logf("Return of Getstats() works, expect %d and got %d %s",
			expect, newCa.RequestsSum, checkMark)
	}

	ca.inc <- tuple{
		path: testpath,
		code: 404,
	}
	if assert.Equal(t, newCa.RequestsSum, expect, "Return of Getstats() does not work, expect %d but got %d %s",
		expect, newCa.RequestsSum, ballotX) {
		t.Logf("Return of Getstats() works, expect %d and got %d %s",
			expect, newCa.RequestsSum, checkMark)
	}
	if assert.Equal(t, newCa.Requests[testpath], expect, "Return of Getstats() does not work, expect %d but got %d %s",
		expect, newCa.Requests[testpath], ballotX) {
		t.Logf("Return of Getstats() works, expect %d and got %d %s",
			expect, newCa.Requests[testpath], checkMark)
	}

	ca.reset()
	newCa = ca.GetStats().(CounterAspect)
	expect = 1
	if assert.Equal(t, newCa.RequestsSum, expect, "Return of Getstats() does not work, expect %d but got %d %s",
		expect, newCa.RequestsSum, ballotX) {
		t.Logf("Return of Getstats() works, expect %d and got %d %s",
			expect, newCa.RequestsSum, checkMark)
	}
	if assert.Equal(t, newCa.Requests[testpath], expect, "Return of Getstats() does not work, expect %d but got %d %s",
		expect, newCa.Requests[testpath], ballotX) {
		t.Logf("Return of Getstats() works, expect %d and got %d %s",
			expect, newCa.Requests[testpath], checkMark)
	}
}

func Test_Name(t *testing.T) {
	ca := NewCounterAspect()
	expect := "Counter"
	if assert.Equal(t, ca.Name(), expect, "Return of counter name does not work, expect %s but got %s %s",
		expect, ca.Name(), ballotX) {
		t.Logf("Return of counter name works, expect %s and got %s %s",
			expect, ca.Name(), checkMark)
	}
}

func Test_InRoot(t *testing.T) {
	ca := NewCounterAspect()
	expect := false
	if assert.Equal(t, ca.InRoot(), expect, "Expect %v but got %v %s",
		expect, ca.InRoot(), ballotX) {
		t.Logf("Expect %v and got %v %s",
			expect, ca.InRoot(), checkMark)
	}
}

func Test_CounterHandler(t *testing.T) {
	gin.SetMode(TestMode)
	router := gin.New()
	ca := NewCounterAspect()
	ca.StartTimer(1 * time.Second)
	expect := 1
	ca.inc <- tuple{
		path: testpath,
		code: 404,
	}
	ca.reset()

	router.Use(CounterHandler(ca))
	tryRequest(router, "GET", "/")
	if assert.Equal(t, ca.RequestsSum, expect, "Incrementation of counter does not work, expect %d but got %d %s", expect, ca.RequestsSum, ballotX) {
		t.Logf("CounterHandler works, expect %d and got %d %s", expect, ca.RequestsSum, checkMark)
	}
}

func tryRequest(r http.Handler, method, path string) *httptest.ResponseRecorder {
	req, _ := http.NewRequest(method, path, nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)
	return w
}
<commit_msg>make sure we match the assertEqual signature<commit_after>package ginmon

import (
	"net/http"
	"net/http/httptest"
	"net/url"
	"testing"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/stretchr/testify/assert"
)

const TestMode string = "test"

const checkMark = "\u2713"
const ballotX = "\u2717"

const testpath = "/foo/bar"

func internalGinCtx() *gin.Context {
	return &gin.Context{
		Request: &http.Request{
			URL: &url.URL{
				Path: testpath,
			},
		},
	}
}

func Test_Inc(t *testing.T) {
	ca := NewCounterAspect()
	ca.StartTimer(1 * time.Second)
	expect := 1
	ca.inc <- tuple{
		path: testpath,
		code: 404,
	}
	ca.reset()
	if assert.Equal(t, expect, ca.RequestsSum, "Incrementation of counter does not work, expect %d but got %d %s",
		expect, ca.RequestsSum, ballotX) {
		t.Logf("Incrementation of counter works, expect %d and git %d %s",
			expect, ca.RequestsSum, checkMark)
	}
}

func Test_GetStats(t *testing.T) {
	ca := NewCounterAspect()
	ca.StartTimer(1 * time.Second)
	if assert.NotNil(t, ca.GetStats(), "Return of Getstats() should not be nil") {
		t.Logf("Should be an interface %s", checkMark)
	}

	newCa := ca.GetStats().(CounterAspect)
	expect := 0
	if assert.Equal(t, expect, newCa.RequestsSum, "Return of Getstats() does not work, expect %d but got %d %s",
		expect, newCa.RequestsSum, ballotX) {
		t.Logf("Return of Getstats() works, expect %d and got %d %s",
			expect, newCa.RequestsSum, checkMark)
	}

	ca.inc <- tuple{
		path: testpath,
		code: 404,
	}
	if assert.Equal(t, expect, newCa.RequestsSum, "Return of Getstats() does not work, expect %d but got %d %s",
		expect, newCa.RequestsSum, ballotX) {
		t.Logf("Return of Getstats() works, expect %d and got %d %s",
			expect, newCa.RequestsSum, checkMark)
	}
	if assert.Equal(t, expect, newCa.Requests[testpath], "Return of Getstats() does not work, expect %d but got %d %s",
		expect, newCa.Requests[testpath], ballotX) {
		t.Logf("Return of Getstats() works, expect %d and got %d %s",
			expect, newCa.Requests[testpath], checkMark)
	}

	ca.reset()
	newCa = ca.GetStats().(CounterAspect)
	expect = 1
	if assert.Equal(t, expect, newCa.RequestsSum, "Return of Getstats() does not work, expect %d but got %d %s",
		expect, newCa.RequestsSum, ballotX) {
		t.Logf("Return of Getstats() works, expect %d and got %d %s",
			expect, newCa.RequestsSum, checkMark)
	}
	if assert.Equal(t, expect, newCa.Requests[testpath], "Return of Getstats() does not work, expect %d but got %d %s",
		expect, newCa.Requests[testpath], ballotX) {
		t.Logf("Return of Getstats() works, expect %d and got %d %s",
			expect, newCa.Requests[testpath], checkMark)
	}
}

func Test_Name(t *testing.T) {
	ca := NewCounterAspect()
	expect := "Counter"
	if assert.Equal(t, expect, ca.Name(), "Return of counter name does not work, expect %s but got %s %s",
		expect, ca.Name(), ballotX) {
		t.Logf("Return of counter name works, expect %s and got %s %s",
			expect, ca.Name(), checkMark)
	}
}

func Test_InRoot(t *testing.T) {
	ca := NewCounterAspect()
	expect := false
	if assert.Equal(t, expect, ca.InRoot(), "Expect %v but got %v %s",
		expect, ca.InRoot(), ballotX) {
		t.Logf("Expect %v and got %v %s",
			expect, ca.InRoot(), checkMark)
	}
}

func Test_CounterHandler(t *testing.T) {
	gin.SetMode(TestMode)
	router := gin.New()
	ca := NewCounterAspect()
	ca.StartTimer(1 * time.Second)
	expect := 1
	ca.inc <- tuple{
		path: testpath,
		code: 404,
	}
	ca.reset()

	router.Use(CounterHandler(ca))
	tryRequest(router, "GET", "/")
	if assert.Equal(t, expect, ca.RequestsSum, "Incrementation of counter does not work, expect %d but got %d %s", expect, ca.RequestsSum, ballotX) {
		t.Logf("CounterHandler works, expect %d and got %d %s", expect, ca.RequestsSum, checkMark)
	}
}

func tryRequest(r http.Handler, method, path string) *httptest.ResponseRecorder {
	req, _ := http.NewRequest(method, path, nil)
	w := httptest.NewRecorder()
	r.ServeHTTP(w, req)
	return w
}
<|endoftext|>


<commit_before>// Make balanced rosters according to weighted criteria

package main

import (
	"fmt"
	"math/rand"
	"time"

	"gopkg.in/alecthomas/kingpin.v2"

	"github.com/GaryBoone/GoStats/stats"
)

const numTeams = 6

type Solution struct {
	players []Player
}

type Team struct {
	players []Player
}

func splitIntoTeams(players []Player) []Team {
	teams := make([]Team, numTeams)
	for _, player := range players {
		teams[player.team].players = append(teams[player.team].players, player)
	}
	return teams
}

// Score a solution based on weighted critera.
func score(solution Solution) float64 {
	// Balanced by number
	teams := splitIntoTeams(solution.players)

	teamLengths := make([]float64, numTeams)
	for i, team := range teams {
		teamLengths[i] = float64(len(team.players))
	}
	fmt.Println("teamLengths", teamLengths)
	teamsStdDev := stats.StatsSampleStandardDeviation(teamLengths)
	fmt.Println("teamsStdDev", teamsStdDev)

	// TODO Balanced by gender

	return teamsStdDev
}

func main() {
	// Read command line input
	filenamePointer := kingpin.Arg("input-file",
		"filename from which to get list of players").
		Required().String()
	deterministicPointer := kingpin.Flag("deterministic",
		"makes our output deterministic by allowing the default rand.Seed").
		Short('d').Bool()
	kingpin.Parse()

	if !*deterministicPointer {
		rand.Seed(time.Now().UTC().UnixNano())
	}

	players := ParsePlayers(*filenamePointer)
	solution := Solution{players}

	fmt.Println("score:", score(solution))
}
<commit_msg>calculate gender imbalance<commit_after>// Make balanced rosters according to weighted criteria

package main

import (
	"fmt"
	"math/rand"
	"time"

	"gopkg.in/alecthomas/kingpin.v2"

	"github.com/GaryBoone/GoStats/stats"
	"github.com/topher200/baseutil"
)

const numTeams = 6

type Solution struct {
	players []Player
}

type Team struct {
	players []Player
}

func splitIntoTeams(players []Player) []Team {
	teams := make([]Team, numTeams)
	for _, player := range players {
		teams[player.team].players = append(teams[player.team].players, player)
	}
	return teams
}

// Score a solution based on weighted critera.
func score(solution Solution) float64 {
	teams := splitIntoTeams(solution.players)

	// Balanced by number
	teamLengths := make([]float64, numTeams)
	for i, team := range teams {
		teamLengths[i] = float64(len(team.players))
	}
	fmt.Println("teamLengths", teamLengths)
	teamsStdDev := stats.StatsSampleStandardDeviation(teamLengths)
	fmt.Println("teamsStdDev", teamsStdDev)

	// Score on balance in gender.
	//
	// For each Gender we make a list of the number of players of that gender on
	// each team. Then we take the standard deviation of those two lists to
	// determine the gender imbalance.
	teamGenders := make(map[Gender][]int)
	for _, gender := range []Gender{Male, Female} {
		teamGenders[gender] = make([]int, 6)
	}
	for teamNum, team := range teams {
		for _, player := range team.players {
			teamGenders[player.gender][teamNum] += 1
		}
	}
	fmt.Println("teamGenders", teamGenders)
	for gender, teamList := range teamGenders {
		teamsStdDev = baseutil.StandardDeviationInt(teamList)
		fmt.Println("gender", gender, "std dev:", teamsStdDev)
	}

	return teamsStdDev
}

func main() {
	// Read command line input
	filenamePointer := kingpin.Arg("input-file",
		"filename from which to get list of players").
		Required().String()
	deterministicPointer := kingpin.Flag("deterministic",
		"makes our output deterministic by allowing the default rand.Seed").
		Short('d').Bool()
	kingpin.Parse()

	if !*deterministicPointer {
		rand.Seed(time.Now().UTC().UnixNano())
	}

	players := ParsePlayers(*filenamePointer)
	solution := Solution{players}

	fmt.Println("score:", score(solution))
}
<|endoftext|>


<commit_before>package leds

import (
	"fmt"
	"math"

	"github.com/siggy/bbox/bbox"
	"github.com/siggy/rpi_ws281x/golang/ws2811"
)

const (
	LED_COUNT  = 150
	TICK_DELAY = 0 // match sound to LEDs
)

type Row struct {
	start   int
	end     int
	buttons [bbox.BEATS]int
}

func (r *Row) TickToLed(tick int) int {
	// determine where we are in the buttons array
	// 0 <= tick < 160
	// 0 <= beat < 16
	floatBeat := float64(tick) / float64(bbox.TICKS_PER_BEAT) // 12.7 => 0.7
	f := math.Floor(floatBeat)                                // 12
	c := math.Ceil(floatBeat)                                 // 13

	var floor int
	var ceil int

	if f == 0 {
		// between start and first beat
		floor = r.start
		ceil = r.buttons[int(c)]
	} else if c == bbox.BEATS {
		// between last beat and end
		floor = r.buttons[int(f)]
		ceil = r.end
	} else {
		// between first and last beat
		floor = r.buttons[int(f)]
		ceil = r.buttons[int(c)]
	}

	percentAhead := floatBeat - f
	diff := percentAhead * (float64(ceil) - float64(floor))
	return floor + int(diff)
}

type LedBeats struct {
	beats   bbox.Beats
	closing chan struct{}
	msgs    <-chan bbox.Beats
	ticks   <-chan int
}

var (
	rows = [bbox.SOUNDS]Row{
		// rows 0 and 1 are LED strip 0
		Row{
			start: 33,
			end:   0,
			buttons: [bbox.BEATS]int{
				31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1,
			},
		},
		Row{
			start: 35,
			end:   69,
			buttons: [bbox.BEATS]int{
				36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66,
			},
		},

		// rows 1 and 2 are LED strip 1
		Row{
			start: 43,
			end:   0,
			buttons: [bbox.BEATS]int{
				42, 39, 36, 34, 31, 28, 26, 23, 20, 18, 15, 12, 10, 7, 4, 1,
			},
		},
		Row{
			start: 45,
			end:   87,
			buttons: [bbox.BEATS]int{
				46, 49, 52, 54, 57, 60, 63, 66, 68, 70, 73, 76, 78, 81, 84, 87,
			},
		},
	}
)

func InitLedBeats(msgs <-chan bbox.Beats, ticks <-chan int) *LedBeats {
	InitLeds(LED_COUNT, LED_COUNT)

	return &LedBeats{
		closing: make(chan struct{}),
		msgs:    msgs,
		ticks:   ticks,
	}
}

func (l *LedBeats) Run() {
	defer func() {
		ws2811.Clear()
		ws2811.Render()
		ws2811.Wait()
		ws2811.Fini()
	}()

	ws2811.Clear()
	err := ws2811.Render()
	if err != nil {
		fmt.Printf("ws2811.Render failed: %+v\n", err)
		panic(err)
	}
	err = ws2811.Wait()
	if err != nil {
		fmt.Printf("ws2811.Wait failed: %+v\n", err)
		panic(err)
	}

	for {
		select {
		case _, more := <-l.closing:
			if !more {
				fmt.Printf("LEDs closing\n")
				return
			}
		case tick := <-l.ticks:
			// TODO: leds for all 4 beats
			tick = (tick + bbox.TICKS - TICK_DELAY) % bbox.TICKS
			ws2811.Clear()
			// cur := tick / bbox.TICKS_PER_BEAT

			// light all leds at current position
			for _, r := range rows[0:2] {
				ws2811.SetLed(0, r.TickToLed(tick), trueWhite)
			}
			for _, r := range rows[2:4] {
				ws2811.SetLed(1, r.TickToLed(tick), trueWhite)
			}

			// light active beats
			// for _, beat := range l.beats {
			// 	for j, t := range beat {
			// 		if t {
			// 			for _, r := range rows {
			// 				if j == cur {
			// 					ws2811.SetLed(0, r.buttons[j], redWhite)
			// 				} else {
			// 					ws2811.SetLed(0, r.buttons[j], trueRed)
			// 				}
			// 			}
			// 		}
			// 	}
			// }

			err = ws2811.Render()
			if err != nil {
				fmt.Printf("ws2811.Render failed: %+v\n", err)
				panic(err)
			}
			err = ws2811.Wait()
			if err != nil {
				fmt.Printf("ws2811.Wait failed: %+v\n", err)
				panic(err)
			}
		case beats, more := <-l.msgs:
			if more {
				// incoming beat update from keyboard
				l.beats = beats
			} else {
				// closing
				fmt.Printf("LEDs closing\n")
				return
			}
		}
	}
}

func (l *LedBeats) Close() {
	// TODO: this doesn't block?
	close(l.closing)
}
<commit_msg>bbox beats calibrated<commit_after>package leds

import (
	"fmt"
	"math"

	"github.com/siggy/bbox/bbox"
	"github.com/siggy/rpi_ws281x/golang/ws2811"
)

const (
	LED_COUNT  = 150
	TICK_DELAY = 17 // match sound to LEDs
)

type Row struct {
	start   int
	end     int
	buttons [bbox.BEATS]int
}

func (r *Row) TickToLed(tick int) (led int, buttonIdx int) {
	// determine where we are in the buttons array
	// 0 <= tick < 160
	// 0 <= beat < 16
	floatBeat := float64(tick) / float64(bbox.TICKS_PER_BEAT) // 127 => 12.7
	f := math.Floor(floatBeat)                                // 12
	c := math.Ceil(floatBeat)                                 // 13

	var floor int
	var ceil int

	if f == 0 {
		// between start and first beat
		floor = r.start
		ceil = r.buttons[int(c)]
	} else if c == bbox.BEATS {
		// between last beat and end
		floor = r.buttons[int(f)]
		ceil = r.end
	} else {
		// between first and last beat
		floor = r.buttons[int(f)]
		ceil = r.buttons[int(c)]
	}

	percentAhead := floatBeat - f // 12.7 - 12 => 0.7
	diff := percentAhead * (float64(ceil) - float64(floor))

	led = floor + int(diff)
	buttonIdx = -1
	if led == floor {
		buttonIdx = int(f)
	}

	return
}

type LedBeats struct {
	beats   bbox.Beats
	closing chan struct{}
	msgs    <-chan bbox.Beats
	ticks   <-chan int
}

var (
	rows = [bbox.SOUNDS]Row{
		// rows 0 and 1 are LED strip 0
		Row{
			start: 33,
			end:   0,
			buttons: [bbox.BEATS]int{
				31, 29, 27, 25, 23, 21, 19, 17, 15, 13, 11, 9, 7, 5, 3, 1,
			},
		},
		Row{
			start: 35,
			end:   69,
			buttons: [bbox.BEATS]int{
				36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66,
			},
		},

		// rows 2 and 3 are LED strip 1
		Row{
			start: 43,
			end:   0,
			buttons: [bbox.BEATS]int{
				42, 39, 36, 34, 31, 28, 26, 23, 20, 18, 15, 12, 10, 7, 4, 1,
			},
		},
		Row{
			start: 45,
			end:   87,
			buttons: [bbox.BEATS]int{
				46, 49, 52, 54, 57, 60, 63, 66, 68, 70, 73, 76, 78, 81, 84, 87,
			},
		},
	}
)

func InitLedBeats(msgs <-chan bbox.Beats, ticks <-chan int) *LedBeats {
	InitLeds(LED_COUNT, LED_COUNT)

	return &LedBeats{
		closing: make(chan struct{}),
		msgs:    msgs,
		ticks:   ticks,
	}
}

func (l *LedBeats) Run() {
	defer func() {
		ws2811.Clear()
		ws2811.Render()
		ws2811.Wait()
		ws2811.Fini()
	}()

	ws2811.Clear()
	err := ws2811.Render()
	if err != nil {
		fmt.Printf("ws2811.Render failed: %+v\n", err)
		panic(err)
	}
	err = ws2811.Wait()
	if err != nil {
		fmt.Printf("ws2811.Wait failed: %+v\n", err)
		panic(err)
	}

	for {
		select {
		case _, more := <-l.closing:
			if !more {
				fmt.Printf("LEDs closing\n")
				return
			}
		case tick := <-l.ticks:
			tick = (tick + bbox.TICKS - TICK_DELAY) % bbox.TICKS
			ws2811.Clear()

			ledIdxs := [len(rows)]int{}
			buttonIdxs := [len(rows)]int{}
			for i, r := range rows {
				ledIdxs[i], buttonIdxs[i] = r.TickToLed(tick)
			}

			// light all leds at current position
			for i, _ := range rows[0:2] {
				ws2811.SetLed(0, ledIdxs[i], trueWhite)
			}
			for i, _ := range rows[2:4] {
				ws2811.SetLed(1, ledIdxs[i+2], trueWhite)
			}

			// light active beats
			for i, beat := range l.beats[0:2] {
				for j, t := range beat {
					if t {
						if j == buttonIdxs[i] {
							ws2811.SetLed(0, rows[i].buttons[j], purple)
						} else {
							ws2811.SetLed(0, rows[i].buttons[j], trueRed)
						}
					}
				}
			}
			for i, beat := range l.beats[2:4] {
				for j, t := range beat {
					if t {
						if j == buttonIdxs[i+2] {
							ws2811.SetLed(1, rows[i+2].buttons[j], purple)
						} else {
							ws2811.SetLed(1, rows[i+2].buttons[j], trueRed)
						}
					}
				}
			}

			err = ws2811.Render()
			if err != nil {
				fmt.Printf("ws2811.Render failed: %+v\n", err)
				panic(err)
			}
			err = ws2811.Wait()
			if err != nil {
				fmt.Printf("ws2811.Wait failed: %+v\n", err)
				panic(err)
			}
		case beats, more := <-l.msgs:
			if more {
				// incoming beat update from keyboard
				l.beats = beats
			} else {
				// closing
				fmt.Printf("LEDs closing\n")
				return
			}
		}
	}
}

func (l *LedBeats) Close() {
	// TODO: this doesn't block?
	close(l.closing)
}
<|endoftext|>


<commit_before>// Copyright 2015 CoreOS, Inc.
//
// 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 misc

import (
	"bytes"
	"fmt"
	"path"
	"time"

	"github.com/coreos/mantle/platform"
	"github.com/coreos/mantle/util"

	"github.com/coreos/mantle/Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/config"
	"github.com/coreos/mantle/Godeps/_workspace/src/github.com/coreos/pkg/capnslog"
)

var plog = capnslog.NewPackageLogger("github.com/coreos/mantle", "kola/tests/misc")

// Test that the kernel NFS server and client work within CoreOS.
func NFS(c platform.TestCluster) error {
	/* server machine */
	c1 := config.CloudConfig{
		CoreOS: config.CoreOS{
			Units: []config.Unit{
				config.Unit{
					Name:    "rpcbind.service",
					Command: "start",
				},
				config.Unit{
					Name:    "rpc-statd.service",
					Command: "start",
				},
				config.Unit{
					Name:    "rpc-mountd.service",
					Command: "start",
				},
				config.Unit{
					Name:    "nfsd.service",
					Command: "start",
				},
			},
		},
		WriteFiles: []config.File{
			config.File{
				Content: "/tmp	*(ro,insecure,all_squash,no_subtree_check,fsid=0)",
				Path: "/etc/exports",
			},
		},
		Hostname: "nfs1",
	}

	m1, err := c.NewMachine(c1.String())
	if err != nil {
		return fmt.Errorf("Cluster.NewMachine: %s", err)
	}

	defer m1.Destroy()

	plog.Info("NFS server booted.")

	/* poke a file in /tmp */
	tmp, err := m1.SSH("mktemp")
	if err != nil {
		return fmt.Errorf("Machine.SSH: %s", err)
	}

	plog.Infof("Test file %q created on server.", tmp)

	/* client machine */

	nfstmpl := `[Unit]
Description=NFS Client
After=network-online.target
Requires=network-online.target
After=rpc-statd.service
Requires=rpc-statd.service

[Mount]
What=%s:/tmp
Where=/mnt
Type=nfs
Options=defaults,noexec
`

	c2 := config.CloudConfig{
		CoreOS: config.CoreOS{
			Units: []config.Unit{
				config.Unit{
					Name:    "rpc-statd.service",
					Command: "start",
				},
				config.Unit{
					Name:    "mnt.mount",
					Command: "start",
					Content: fmt.Sprintf(nfstmpl, m1.PrivateIP()),
				},
			},
		},
		Hostname: "nfs2",
	}

	m2, err := c.NewMachine(c2.String())
	if err != nil {
		return fmt.Errorf("Cluster.NewMachine: %s", err)
	}

	defer m2.Destroy()

	plog.Info("NFS client booted.")

	var lsmnt []byte

	plog.Info("Waiting for NFS mount on client...")

	/* there's probably a better wait to check the mount */
	checker := func() error {
		lsmnt, _ = m2.SSH("ls /mnt")
		if len(lsmnt) == 0 {
			return fmt.Errorf("client /mnt is empty")
		}

		plog.Info("Got NFS mount.")
		return nil
	}

	if err = util.Retry(5, 1*time.Second, checker); err != nil {
		return err
	}

	if len(lsmnt) == 0 {
		return fmt.Errorf("Client /mnt is empty.")
	}

	if bytes.Contains(lsmnt, []byte(path.Base(string(tmp)))) != true {
		return fmt.Errorf("Client /mnt did not contain file %q from server /tmp -- /mnt: %s", tmp, lsmnt)
	}

	return nil
}
<commit_msg>kola/tests/misc: use systemd to check nfs mount; increase timeout<commit_after>// Copyright 2015 CoreOS, Inc.
//
// 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 misc

import (
	"fmt"
	"path"
	"time"

	"github.com/coreos/mantle/platform"
	"github.com/coreos/mantle/util"

	"github.com/coreos/mantle/Godeps/_workspace/src/github.com/coreos/coreos-cloudinit/config"
	"github.com/coreos/mantle/Godeps/_workspace/src/github.com/coreos/pkg/capnslog"
)

var plog = capnslog.NewPackageLogger("github.com/coreos/mantle", "kola/tests/misc")

// Test that the kernel NFS server and client work within CoreOS.
func NFS(c platform.TestCluster) error {
	/* server machine */
	c1 := config.CloudConfig{
		CoreOS: config.CoreOS{
			Units: []config.Unit{
				config.Unit{
					Name:    "rpcbind.service",
					Command: "start",
				},
				config.Unit{
					Name:    "rpc-statd.service",
					Command: "start",
				},
				config.Unit{
					Name:    "rpc-mountd.service",
					Command: "start",
				},
				config.Unit{
					Name:    "nfsd.service",
					Command: "start",
				},
			},
		},
		WriteFiles: []config.File{
			config.File{
				Content: "/tmp	*(ro,insecure,all_squash,no_subtree_check,fsid=0)",
				Path: "/etc/exports",
			},
		},
		Hostname: "nfs1",
	}

	m1, err := c.NewMachine(c1.String())
	if err != nil {
		return fmt.Errorf("Cluster.NewMachine: %s", err)
	}

	defer m1.Destroy()

	plog.Info("NFS server booted.")

	/* poke a file in /tmp */
	tmp, err := m1.SSH("mktemp")
	if err != nil {
		return fmt.Errorf("Machine.SSH: %s", err)
	}

	plog.Infof("Test file %q created on server.", tmp)

	/* client machine */

	nfstmpl := `[Unit]
Description=NFS Client
After=network-online.target
Requires=network-online.target
After=rpc-statd.service
Requires=rpc-statd.service

[Mount]
What=%s:/tmp
Where=/mnt
Type=nfs
Options=defaults,noexec
`

	c2 := config.CloudConfig{
		CoreOS: config.CoreOS{
			Units: []config.Unit{
				config.Unit{
					Name:    "rpc-statd.service",
					Command: "start",
				},
				config.Unit{
					Name:    "mnt.mount",
					Command: "start",
					Content: fmt.Sprintf(nfstmpl, m1.PrivateIP()),
				},
			},
		},
		Hostname: "nfs2",
	}

	m2, err := c.NewMachine(c2.String())
	if err != nil {
		return fmt.Errorf("Cluster.NewMachine: %s", err)
	}

	defer m2.Destroy()

	plog.Info("NFS client booted.")

	plog.Info("Waiting for NFS mount on client...")

	checkmount := func() error {
		status, err := m2.SSH("systemctl is-active mnt.mount")
		if err != nil || string(status) != "active" {
			return fmt.Errorf("mnt.mount status is %q: %v", status, err)
		}

		plog.Info("Got NFS mount.")
		return nil
	}

	if err = util.Retry(10, 3*time.Second, checkmount); err != nil {
		return err
	}

	_, err = m2.SSH(fmt.Sprintf("stat /mnt/%s", path.Base(string(tmp))))
	if err != nil {
		return fmt.Errorf("file %q does not exist", tmp)
	}

	return nil
}
<|endoftext|>


<commit_before>package action

import "net/http"

//Action action struct
type Action struct {
	handler func(w http.ResponseWriter, r *http.Request)
}

//ServeHTTP serve as http server
func (a *Action) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	a.handler(w, r)
}

//SetHandler set action handler
func (a *Action) SetHandler(f func(w http.ResponseWriter, r *http.Request)) *Action {
	a.handler = f
	return a
}

//Handler return action handler
func (a *Action) Handler() func(w http.ResponseWriter, r *http.Request) {
	return a.handler
}

//New create new cation
func New() *Action {
	return &Action{}
}
<commit_msg>update<commit_after>package action

import "net/http"

//Action action struct
type Action struct {
	middleware func(w http.ResponseWriter, r *http.Request, next http.HandlerFunc)
	handler    func(w http.ResponseWriter, r *http.Request)
}

//ServeHTTP serve as http server
func (a *Action) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if a.middleware == nil {
		a.handler(w, r)
		return
	}
	a.middleware(w, r, a.handler)
}

//SetHandler set action handler
func (a *Action) SetHandler(f func(w http.ResponseWriter, r *http.Request)) *Action {
	a.handler = f
	return a
}

//Handler return action handler
func (a *Action) Handler() func(w http.ResponseWriter, r *http.Request) {
	return a.handler
}

//New create new cation
func New() *Action {
	return &Action{}
}
<|endoftext|>


<commit_before>/*

   Copyright 2016 Wenhui Shen <www.webx.top>

   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 language

import (
	"fmt"
	"path/filepath"
	"strings"

	"github.com/admpub/i18n"
	"github.com/admpub/log"
	"github.com/webx-top/com"
)

var defaultInstance *I18n

type I18n struct {
	*i18n.TranslatorFactory
	Translators map[string]*i18n.Translator
	config      *Config
}

func NewI18n(c *Config) *I18n {
	f, errs := i18n.NewTranslatorFactory(c.RulesPath, c.MessagesPath, c.Fallback, c.FSFunc())
	if errs != nil && len(errs) > 0 {
		var errMsg string
		for idx, err := range errs {
			if idx > 0 {
				errMsg += "\n"
			}
			errMsg += err.Error()
		}
		if len(errMsg) > 0 {
			panic("== i18n error: " + errMsg + "\n")
		}
	}
	defaultInstance = &I18n{
		TranslatorFactory: f,
		Translators:       make(map[string]*i18n.Translator),
		config:            c,
	}
	defaultInstance.Get(c.Default)

	return defaultInstance
}

func (a *I18n) Monitor() *I18n {
	onchange := func(file string) {
		log.Info("reload language: ", file)
		defaultInstance.Reload(file)
	}
	for _, mp := range a.config.MessagesPath {
		if len(mp) == 0 {
			continue
		}
		callback := &com.MonitorEvent{
			Modify: onchange,
			Delete: onchange,
			Rename: onchange,
		}
		callback.Watch(mp, func(f string) bool {
			log.Info("changed language: ", f)
			return strings.HasSuffix(f, `.yaml`)
		})
	}
	return a
}

func (a *I18n) Get(langCode string) *i18n.Translator {
	var (
		t    *i18n.Translator
		errs []error
	)
	t, errs = a.TranslatorFactory.GetTranslator(langCode)
	if errs != nil && len(errs) > 0 {
		if a.config.Default != langCode {
			t, errs = a.TranslatorFactory.GetTranslator(a.config.Default)
		}
	}
	if errs != nil && len(errs) > 0 {
		var errMsg string
		for idx, err := range errs {
			if idx > 0 {
				errMsg += "\n"
			}
			errMsg += err.Error()
		}
		if len(errMsg) > 0 {
			panic("== i18n error: " + errMsg + "\n")
		}
	}
	a.Translators[langCode] = t
	return t
}

func (a *I18n) Reload(langCode string) {
	if strings.HasSuffix(langCode, `.yaml`) {
		langCode = strings.TrimSuffix(langCode, `.yaml`)
		langCode = filepath.Base(langCode)
	}
	a.TranslatorFactory.Reload(langCode)
	if _, ok := a.Translators[langCode]; ok {
		delete(a.Translators, langCode)
	}
}

func (a *I18n) Translate(langCode, key string, args map[string]string) string {
	t, ok := a.Translators[langCode]
	if !ok {
		t = a.Get(langCode)
	}
	translation, err := t.Translate(key, args)
	if err != nil {
		return key
	}
	return translation
}

func (a *I18n) T(langCode, key string, args ...interface{}) (t string) {
	if len(args) > 0 {
		if v, ok := args[0].(map[string]string); ok {
			t = a.Translate(langCode, key, v)
			return
		}
		t = a.Translate(langCode, key, map[string]string{})
		t = fmt.Sprintf(t, args...)
		return
	}
	t = a.Translate(langCode, key, map[string]string{})
	return
}

//T 多语言翻译
func T(langCode, key string, args ...interface{}) (t string) {
	if defaultInstance == nil {
		t = key
		if len(args) > 0 {
			t = fmt.Sprintf(t, args...)
		}
		return
	}
	t = defaultInstance.T(langCode, key, args...)
	return
}
<commit_msg>update<commit_after>/*

   Copyright 2016 Wenhui Shen <www.webx.top>

   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 language

import (
	"fmt"
	"path/filepath"
	"strings"

	"github.com/admpub/i18n"
	"github.com/admpub/log"
	"github.com/webx-top/com"
)

var defaultInstance *I18n

type I18n struct {
	*i18n.TranslatorFactory
	Translators map[string]*i18n.Translator
	config      *Config
}

func NewI18n(c *Config) *I18n {
	f, errs := i18n.NewTranslatorFactory(c.RulesPath, c.MessagesPath, c.Fallback, c.FSFunc())
	if errs != nil && len(errs) > 0 {
		var errMsg string
		for idx, err := range errs {
			if idx > 0 {
				errMsg += "\n"
			}
			errMsg += err.Error()
		}
		if len(errMsg) > 0 {
			panic("== i18n error: " + errMsg + "\n")
		}
	}
	defaultInstance = &I18n{
		TranslatorFactory: f,
		Translators:       make(map[string]*i18n.Translator),
		config:            c,
	}
	defaultInstance.Get(c.Default)

	return defaultInstance
}

func (a *I18n) Monitor() *I18n {
	onchange := func(file string) {
		log.Info("reload language: ", file)
		defaultInstance.Reload(file)
	}
	callback := &com.MonitorEvent{
		Modify: onchange,
		Delete: onchange,
		Rename: onchange,
	}
	callback.Watch(func(f string) bool {
		log.Info("changed language: ", f)
		return strings.HasSuffix(f, `.yaml`)
	})
	for _, mp := range a.config.MessagesPath {
		if len(mp) == 0 {
			continue
		}
		if err := callback.AddDir(mp); err != nil {
			log.Error(err)
		}
	}
	return a
}

func (a *I18n) Get(langCode string) *i18n.Translator {
	var (
		t    *i18n.Translator
		errs []error
	)
	t, errs = a.TranslatorFactory.GetTranslator(langCode)
	if errs != nil && len(errs) > 0 {
		if a.config.Default != langCode {
			t, errs = a.TranslatorFactory.GetTranslator(a.config.Default)
		}
	}
	if errs != nil && len(errs) > 0 {
		var errMsg string
		for idx, err := range errs {
			if idx > 0 {
				errMsg += "\n"
			}
			errMsg += err.Error()
		}
		if len(errMsg) > 0 {
			panic("== i18n error: " + errMsg + "\n")
		}
	}
	a.Translators[langCode] = t
	return t
}

func (a *I18n) Reload(langCode string) {
	if strings.HasSuffix(langCode, `.yaml`) {
		langCode = strings.TrimSuffix(langCode, `.yaml`)
		langCode = filepath.Base(langCode)
	}
	a.TranslatorFactory.Reload(langCode)
	if _, ok := a.Translators[langCode]; ok {
		delete(a.Translators, langCode)
	}
}

func (a *I18n) Translate(langCode, key string, args map[string]string) string {
	t, ok := a.Translators[langCode]
	if !ok {
		t = a.Get(langCode)
	}
	translation, err := t.Translate(key, args)
	if err != nil {
		return key
	}
	return translation
}

func (a *I18n) T(langCode, key string, args ...interface{}) (t string) {
	if len(args) > 0 {
		if v, ok := args[0].(map[string]string); ok {
			t = a.Translate(langCode, key, v)
			return
		}
		t = a.Translate(langCode, key, map[string]string{})
		t = fmt.Sprintf(t, args...)
		return
	}
	t = a.Translate(langCode, key, map[string]string{})
	return
}

//T 多语言翻译
func T(langCode, key string, args ...interface{}) (t string) {
	if defaultInstance == nil {
		t = key
		if len(args) > 0 {
			t = fmt.Sprintf(t, args...)
		}
		return
	}
	t = defaultInstance.T(langCode, key, args...)
	return
}
<|endoftext|>


<commit_before>package kv

import (
	"encoding/json"
	"fmt"
	"strings"

	"github.com/movio/kasper/util"
	"golang.org/x/net/context"
	elastic "gopkg.in/olivere/elastic.v5"
)

// ElasticsearchKeyValueStore is a key-value storage that uses ElasticSearch.
// In this key-value store, all keys must have the format "<index>/<type>/<_id>".
// See: https://www.elastic.co/products/elasticsearch
type ElasticsearchKeyValueStore struct {
	witness            *util.StructPtrWitness
	client             *elastic.Client
	context            context.Context
	existingIndexNames []string
}

// NewElasticsearchKeyValueStore creates new ElasticsearchKeyValueStore instance.
// Host must of the format hostname:port.
// StructPtr should be a pointer to struct type that is used
// for serialization and deserialization of store values.
func NewElasticsearchKeyValueStore(host string, structPtr interface{}) *ElasticsearchKeyValueStore {
	url := fmt.Sprintf("http://%s", host)
	client, err := elastic.NewClient(
		elastic.SetURL(url),
		elastic.SetSniff(false), // FIXME: workaround for issues with ES in docker
	)
	if err != nil {
		panic(fmt.Sprintf("Cannot create ElasticSearch Client to '%s': %s", url, err))
	}
	return &ElasticsearchKeyValueStore{
		witness: util.NewStructPtrWitness(structPtr),
		client:  client,
		context: context.Background(),
	}
}

func (s *ElasticsearchKeyValueStore) checkOrCreateIndex(indexName string) {
	for _, existingIndexName := range s.existingIndexNames {
		if existingIndexName == indexName {
			return
		}
	}
	exists, err := s.client.IndexExists(indexName).Do(s.context)
	if err != nil {
		panic(fmt.Sprintf("Failed to check if index exists: %s", err))
	}
	if !exists {
		_, err := s.client.CreateIndex(indexName).Do(s.context)
		if err != nil {
			panic(fmt.Sprintf("Failed to create index: %s", err))
		}
	}
	s.existingIndexNames = append(s.existingIndexNames, indexName)
}

// Get gets value by key from store
func (s *ElasticsearchKeyValueStore) Get(key string) (interface{}, error) {
	keyParts := strings.Split(key, "/")
	if len(keyParts) != 3 {
		return nil, fmt.Errorf("invalid key: '%s'", key)
	}
	indexName := keyParts[0]
	indexType := keyParts[1]
	valueID := keyParts[2]

	s.checkOrCreateIndex(indexName)

	rawValue, err := s.client.Get().
		Index(indexName).
		Type(indexType).
		Id(valueID).
		Do(s.context)

	if fmt.Sprintf("%s", err) == "elastic: Error 404 (Not Found)" {
		return s.witness.Nil(), nil
	}

	if err != nil {
		return s.witness.Nil(), err
	}

	if !rawValue.Found {
		return s.witness.Nil(), nil
	}

	structPtr := s.witness.Allocate()
	err = json.Unmarshal(*rawValue.Source, structPtr)
	if err != nil {
		return s.witness.Nil(), err
	}
	return structPtr, nil
}

// Put updates key in store with serialized value
func (s *ElasticsearchKeyValueStore) Put(key string, structPtr interface{}) error {
	s.witness.Assert(structPtr)
	keyParts := strings.Split(key, "/")
	if len(keyParts) != 3 {
		return fmt.Errorf("invalid key: '%s'", key)
	}
	indexName := keyParts[0]
	indexType := keyParts[1]
	valueID := keyParts[2]

	s.checkOrCreateIndex(indexName)

	_, err := s.client.Index().
		Index(indexName).
		Type(indexType).
		Id(valueID).
		BodyJson(structPtr).
		Do(s.context)

	return err
}

// Delete removes key from store
func (s *ElasticsearchKeyValueStore) Delete(key string) error {
	keyParts := strings.Split(key, "/")
	if len(keyParts) != 3 {
		return fmt.Errorf("invalid key: '%s'", key)
	}
	indexName := keyParts[0]
	indexType := keyParts[1]
	valueID := keyParts[2]

	s.checkOrCreateIndex(indexName)

	_, err := s.client.Delete().
		Index(indexName).
		Type(indexType).
		Id(valueID).
		Do(s.context)

	return err
}
<commit_msg>add non-indexed mapping for created indexes<commit_after>package kv

import (
	"encoding/json"
	"fmt"
	"strings"

	"github.com/movio/kasper/util"
	"golang.org/x/net/context"
	elastic "gopkg.in/olivere/elastic.v5"
)

// ElasticsearchKeyValueStore is a key-value storage that uses ElasticSearch.
// In this key-value store, all keys must have the format "<index>/<type>/<_id>".
// See: https://www.elastic.co/products/elasticsearch
type ElasticsearchKeyValueStore struct {
	witness         *util.StructPtrWitness
	client          *elastic.Client
	context         context.Context
	existingIndexes []string
}

// NewElasticsearchKeyValueStore creates new ElasticsearchKeyValueStore instance.
// Host must of the format hostname:port.
// StructPtr should be a pointer to struct type that is used
// for serialization and deserialization of store values.
func NewElasticsearchKeyValueStore(host string, structPtr interface{}) *ElasticsearchKeyValueStore {
	url := fmt.Sprintf("http://%s", host)
	client, err := elastic.NewClient(
		elastic.SetURL(url),
		elastic.SetSniff(false), // FIXME: workaround for issues with ES in docker
	)
	if err != nil {
		panic(fmt.Sprintf("Cannot create ElasticSearch Client to '%s': %s", url, err))
	}
	return &ElasticsearchKeyValueStore{
		witness: util.NewStructPtrWitness(structPtr),
		client:  client,
		context: context.Background(),
	}
}

func (s *ElasticsearchKeyValueStore) checkOrCreateIndex(indexName string, indexType string) {
	index := strings.Join([]string{indexName, indexType}, "/")
	for _, existingIndex := range s.existingIndexes {
		if existingIndex == index {
			return
		}
	}
	exists, err := s.client.IndexExists(indexName).Do(s.context)
	if err != nil {
		panic(fmt.Sprintf("Failed to check if index exists: %s", err))
	}
	if !exists {
		_, err = s.client.CreateIndex(indexName).Do(s.context)
		if err != nil {
			panic(fmt.Sprintf("Failed to create index: %s", err))
		}
		s.putMapping(indexName, indexType)
	}

	s.existingIndexes = append(s.existingIndexes, index)
}

func (s *ElasticsearchKeyValueStore) putMapping(indexName string, indexType string) {
	mapping := fmt.Sprintf(`{
		"settings": {
			"index": {
				"number_of_shards": 3,
				"number_of_replicas": 1
			}
		},
		"mappings": { "%s": {
				"dynamic_templates": [{
					"data_template": {
						"mapping": {
							"index": "no"
						},
						"path_match": "data.*"
					}
				}],
				"properties": {
					"data": {
						"type": "nested"
					},
					"metadata": {
						"properties": {
							"campaignId": {
								"type": "string"
							}
						}
					}
				}
			}
		}
	}`, indexType)

	resp, err := s.client.PutMapping().Index(indexName).Type(indexType).BodyString(mapping).Do(s.context)
	if err != nil {
		panic(fmt.Sprintf("Failed to put mapping for index: %s/%s", indexName, indexType))
	}
	if resp == nil {
		panic(fmt.Sprintf("Expected put mapping response; got: %v", resp))
	}
	if !resp.Acknowledged {
		panic(fmt.Sprintf("Expected put mapping ack; got: %v", resp.Acknowledged))
	}
}

// Get gets value by key from store
func (s *ElasticsearchKeyValueStore) Get(key string) (interface{}, error) {
	keyParts := strings.Split(key, "/")
	if len(keyParts) != 3 {
		return nil, fmt.Errorf("invalid key: '%s'", key)
	}
	indexName := keyParts[0]
	indexType := keyParts[1]
	valueID := keyParts[2]

	s.checkOrCreateIndex(indexName, indexType)

	rawValue, err := s.client.Get().
		Index(indexName).
		Type(indexType).
		Id(valueID).
		Do(s.context)

	if fmt.Sprintf("%s", err) == "elastic: Error 404 (Not Found)" {
		return s.witness.Nil(), nil
	}

	if err != nil {
		return s.witness.Nil(), err
	}

	if !rawValue.Found {
		return s.witness.Nil(), nil
	}

	structPtr := s.witness.Allocate()
	err = json.Unmarshal(*rawValue.Source, structPtr)
	if err != nil {
		return s.witness.Nil(), err
	}
	return structPtr, nil
}

// Put updates key in store with serialized value
func (s *ElasticsearchKeyValueStore) Put(key string, structPtr interface{}) error {
	s.witness.Assert(structPtr)
	keyParts := strings.Split(key, "/")
	if len(keyParts) != 3 {
		return fmt.Errorf("invalid key: '%s'", key)
	}
	indexName := keyParts[0]
	indexType := keyParts[1]
	valueID := keyParts[2]

	s.checkOrCreateIndex(indexName, indexType)

	_, err := s.client.Index().
		Index(indexName).
		Type(indexType).
		Id(valueID).
		BodyJson(structPtr).
		Do(s.context)

	return err
}

// Delete removes key from store
func (s *ElasticsearchKeyValueStore) Delete(key string) error {
	keyParts := strings.Split(key, "/")
	if len(keyParts) != 3 {
		return fmt.Errorf("invalid key: '%s'", key)
	}
	indexName := keyParts[0]
	indexType := keyParts[1]
	valueID := keyParts[2]

	s.checkOrCreateIndex(indexName, indexType)

	_, err := s.client.Delete().
		Index(indexName).
		Type(indexType).
		Id(valueID).
		Do(s.context)

	return err
}
<|endoftext|>


<commit_before>/* Copyright 2018 The Bazel Authors. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package golang

import (
	"errors"
	"fmt"
	"go/build"
	"log"
	"path"
	"strings"

	"github.com/bazelbuild/bazel-gazelle/config"
	"github.com/bazelbuild/bazel-gazelle/label"
	"github.com/bazelbuild/bazel-gazelle/pathtools"
	"github.com/bazelbuild/bazel-gazelle/repo"
	"github.com/bazelbuild/bazel-gazelle/resolve"
	"github.com/bazelbuild/bazel-gazelle/rule"
)

func (_ *goLang) Imports(_ *config.Config, r *rule.Rule, f *rule.File) []resolve.ImportSpec {
	if !isGoLibrary(r.Kind()) {
		return nil
	}
	if importPath := r.AttrString("importpath"); importPath == "" {
		return []resolve.ImportSpec{}
	} else {
		return []resolve.ImportSpec{{goName, importPath}}
	}
}

func (_ *goLang) Embeds(r *rule.Rule, from label.Label) []label.Label {
	embedStrings := r.AttrStrings("embed")
	if isGoProtoLibrary(r.Kind()) {
		embedStrings = append(embedStrings, r.AttrString("proto"))
	}
	embedLabels := make([]label.Label, 0, len(embedStrings))
	for _, s := range embedStrings {
		l, err := label.Parse(s)
		if err != nil {
			continue
		}
		l = l.Abs(from.Repo, from.Pkg)
		embedLabels = append(embedLabels, l)
	}
	return embedLabels
}

func (gl *goLang) Resolve(c *config.Config, ix *resolve.RuleIndex, rc *repo.RemoteCache, r *rule.Rule, importsRaw interface{}, from label.Label) {
	if importsRaw == nil {
		// may not be set in tests.
		return
	}
	imports := importsRaw.(rule.PlatformStrings)
	r.DelAttr("deps")
	resolve := resolveGo
	if r.Kind() == "go_proto_library" {
		resolve = resolveProto
	}
	deps, errs := imports.Map(func(imp string) (string, error) {
		l, err := resolve(c, ix, rc, r, imp, from)
		if err == skipImportError {
			return "", nil
		} else if err != nil {
			return "", err
		}
		for _, embed := range gl.Embeds(r, from) {
			if embed.Equal(l) {
				return "", nil
			}
		}
		l = l.Rel(from.Repo, from.Pkg)
		return l.String(), nil
	})
	for _, err := range errs {
		log.Print(err)
	}
	if !deps.IsEmpty() {
		if r.Kind() == "go_proto_library" {
			// protos may import the same library multiple times by different names,
			// so we need to de-duplicate them. Protos are not platform-specific,
			// so it's safe to just flatten them.
			r.SetAttr("deps", deps.Flat())
		} else {
			r.SetAttr("deps", deps)
		}
	}
}

var (
	skipImportError = errors.New("std or self import")
	notFoundError   = errors.New("rule not found")
)

func resolveGo(c *config.Config, ix *resolve.RuleIndex, rc *repo.RemoteCache, r *rule.Rule, imp string, from label.Label) (label.Label, error) {
	gc := getGoConfig(c)
	pcMode := getProtoMode(c)
	if build.IsLocalImport(imp) {
		cleanRel := path.Clean(path.Join(from.Pkg, imp))
		if build.IsLocalImport(cleanRel) {
			return label.NoLabel, fmt.Errorf("relative import path %q from %q points outside of repository", imp, from.Pkg)
		}
		imp = path.Join(gc.prefix, cleanRel)
	}

	if isStandard(imp) {
		return label.NoLabel, skipImportError
	}

	if l, ok := resolve.FindRuleWithOverride(c, resolve.ImportSpec{Lang: "go", Imp: imp}, "go"); ok {
		return l, nil
	}

	if pcMode.ShouldUseKnownImports() {
		// These are commonly used libraries that depend on Well Known Types.
		// They depend on the generated versions of these protos to avoid conflicts.
		// However, since protoc-gen-go depends on these libraries, we generate
		// its rules in disable_global mode (to avoid cyclic dependency), so the
		// "go_default_library" versions of these libraries depend on the
		// pre-generated versions of the proto libraries.
		switch imp {
		case "github.com/golang/protobuf/proto":
			return label.New("com_github_golang_protobuf", "proto", "go_default_library"), nil
		case "github.com/golang/protobuf/jsonpb":
			return label.New("com_github_golang_protobuf", "jsonpb", "go_default_library_gen"), nil
		case "github.com/golang/protobuf/descriptor":
			return label.New("com_github_golang_protobuf", "descriptor", "go_default_library_gen"), nil
		case "github.com/golang/protobuf/ptypes":
			return label.New("com_github_golang_protobuf", "ptypes", "go_default_library_gen"), nil
		case "github.com/golang/protobuf/protoc-gen-go/generator":
			return label.New("com_github_golang_protobuf", "protoc-gen-go/generator", "go_default_library_gen"), nil
		case "google.golang.org/grpc":
			return label.New("org_golang_google_grpc", "", "go_default_library"), nil
		}
		if l, ok := knownGoProtoImports[imp]; ok {
			return l, nil
		}
	}

	if l, err := resolveWithIndexGo(ix, imp, from); err == nil || err == skipImportError {
		return l, err
	} else if err != notFoundError {
		return label.NoLabel, err
	}

	// Special cases for rules_go and bazel_gazelle.
	// These have names that don't following conventions and they're
	// typeically declared with http_archive, not go_repository, so Gazelle
	// won't recognize them.
	if pathtools.HasPrefix(imp, "github.com/bazelbuild/rules_go") {
		pkg := pathtools.TrimPrefix(imp, "github.com/bazelbuild/rules_go")
		return label.New("io_bazel_rules_go", pkg, "go_default_library"), nil
	} else if pathtools.HasPrefix(imp, "github.com/bazelbuild/bazel-gazelle") {
		pkg := pathtools.TrimPrefix(imp, "github.com/bazelbuild/bazel-gazelle")
		return label.New("bazel_gazelle", pkg, "go_default_library"), nil
	}

	if !c.IndexLibraries {
		// packages in current repo were not indexed, relying on prefix to decide what may have been in
		// current repo
		if pathtools.HasPrefix(imp, gc.prefix) {
			pkg := path.Join(gc.prefixRel, pathtools.TrimPrefix(imp, gc.prefix))
			return label.New("", pkg, defaultLibName), nil
		}
	}

	if gc.depMode == externalMode {
		return resolveExternal(rc, imp)
	} else {
		return resolveVendored(rc, imp)
	}
}

// isStandard returns whether a package is in the standard library.
func isStandard(imp string) bool {
	return stdPackages[imp]
}

func resolveWithIndexGo(ix *resolve.RuleIndex, imp string, from label.Label) (label.Label, error) {
	matches := ix.FindRulesByImport(resolve.ImportSpec{Lang: "go", Imp: imp}, "go")
	var bestMatch resolve.FindResult
	var bestMatchIsVendored bool
	var bestMatchVendorRoot string
	var matchError error

	for _, m := range matches {
		// Apply vendoring logic for Go libraries. A library in a vendor directory
		// is only visible in the parent tree. Vendored libraries supercede
		// non-vendored libraries, and libraries closer to from.Pkg supercede
		// those further up the tree.
		isVendored := false
		vendorRoot := ""
		parts := strings.Split(m.Label.Pkg, "/")
		for i := len(parts) - 1; i >= 0; i-- {
			if parts[i] == "vendor" {
				isVendored = true
				vendorRoot = strings.Join(parts[:i], "/")
				break
			}
		}
		if isVendored {
		}
		if isVendored && !label.New(m.Label.Repo, vendorRoot, "").Contains(from) {
			// vendor directory not visible
			continue
		}
		if bestMatch.Label.Equal(label.NoLabel) || isVendored && (!bestMatchIsVendored || len(vendorRoot) > len(bestMatchVendorRoot)) {
			// Current match is better
			bestMatch = m
			bestMatchIsVendored = isVendored
			bestMatchVendorRoot = vendorRoot
			matchError = nil
		} else if (!isVendored && bestMatchIsVendored) || (isVendored && len(vendorRoot) < len(bestMatchVendorRoot)) {
			// Current match is worse
		} else {
			// Match is ambiguous
			matchError = fmt.Errorf("multiple rules (%s and %s) may be imported with %q from %s", bestMatch.Label, m.Label, imp, from)
		}
	}
	if matchError != nil {
		return label.NoLabel, matchError
	}
	if bestMatch.Label.Equal(label.NoLabel) {
		return label.NoLabel, notFoundError
	}
	if bestMatch.IsSelfImport(from) {
		return label.NoLabel, skipImportError
	}
	return bestMatch.Label, nil
}

func resolveExternal(rc *repo.RemoteCache, imp string) (label.Label, error) {
	prefix, repo, err := rc.Root(imp)
	if err != nil {
		return label.NoLabel, err
	}

	var pkg string
	if imp != prefix {
		pkg = pathtools.TrimPrefix(imp, prefix)
	}

	return label.New(repo, pkg, defaultLibName), nil
}

func resolveVendored(rc *repo.RemoteCache, imp string) (label.Label, error) {
	return label.New("", path.Join("vendor", imp), defaultLibName), nil
}

func resolveProto(c *config.Config, ix *resolve.RuleIndex, rc *repo.RemoteCache, r *rule.Rule, imp string, from label.Label) (label.Label, error) {
	pcMode := getProtoMode(c)

	if wellKnownProtos[imp] {
		return label.NoLabel, skipImportError
	}

	if l, ok := resolve.FindRuleWithOverride(c, resolve.ImportSpec{Lang: "proto", Imp: imp}, "go"); ok {
		return l, nil
	}

	if l, ok := knownProtoImports[imp]; ok && pcMode.ShouldUseKnownImports() {
		if l.Equal(from) {
			return label.NoLabel, skipImportError
		} else {
			return l, nil
		}
	}

	if l, err := resolveWithIndexProto(ix, imp, from); err == nil || err == skipImportError {
		return l, err
	} else if err != notFoundError {
		return label.NoLabel, err
	}

	// As a fallback, guess the label based on the proto file name. We assume
	// all proto files in a directory belong to the same package, and the
	// package name matches the directory base name. We also assume that protos
	// in the vendor directory must refer to something else in vendor.
	rel := path.Dir(imp)
	if rel == "." {
		rel = ""
	}
	if from.Pkg == "vendor" || strings.HasPrefix(from.Pkg, "vendor/") {
		rel = path.Join("vendor", rel)
	}
	return label.New("", rel, defaultLibName), nil
}

// wellKnownProtos is the set of proto sets for which we don't need to add
// an explicit dependency in go_proto_library.
// TODO(jayconrod): generate from
// @io_bazel_rules_go//proto/wkt:WELL_KNOWN_TYPE_PACKAGES
var wellKnownProtos = map[string]bool{
	"google/protobuf/any.proto":             true,
	"google/protobuf/api.proto":             true,
	"google/protobuf/compiler_plugin.proto": true,
	"google/protobuf/descriptor.proto":      true,
	"google/protobuf/duration.proto":        true,
	"google/protobuf/empty.proto":           true,
	"google/protobuf/field_mask.proto":      true,
	"google/protobuf/source_context.proto":  true,
	"google/protobuf/struct.proto":          true,
	"google/protobuf/timestamp.proto":       true,
	"google/protobuf/type.proto":            true,
	"google/protobuf/wrappers.proto":        true,
}

func resolveWithIndexProto(ix *resolve.RuleIndex, imp string, from label.Label) (label.Label, error) {
	matches := ix.FindRulesByImport(resolve.ImportSpec{Lang: "proto", Imp: imp}, "go")
	if len(matches) == 0 {
		return label.NoLabel, notFoundError
	}
	if len(matches) > 1 {
		return label.NoLabel, fmt.Errorf("multiple rules (%s and %s) may be imported with %q from %s", matches[0].Label, matches[1].Label, imp, from)
	}
	if matches[0].IsSelfImport(from) {
		return label.NoLabel, skipImportError
	}
	return matches[0].Label, nil
}

func isGoLibrary(kind string) bool {
	return kind == "go_library" || isGoProtoLibrary(kind)
}

func isGoProtoLibrary(kind string) bool {
	return kind == "go_proto_library" || kind == "go_grpc_library"
}
<commit_msg>Clarifies "ambiguous import" message (#479)<commit_after>/* Copyright 2018 The Bazel Authors. All rights reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package golang

import (
	"errors"
	"fmt"
	"go/build"
	"log"
	"path"
	"strings"

	"github.com/bazelbuild/bazel-gazelle/config"
	"github.com/bazelbuild/bazel-gazelle/label"
	"github.com/bazelbuild/bazel-gazelle/pathtools"
	"github.com/bazelbuild/bazel-gazelle/repo"
	"github.com/bazelbuild/bazel-gazelle/resolve"
	"github.com/bazelbuild/bazel-gazelle/rule"
)

func (_ *goLang) Imports(_ *config.Config, r *rule.Rule, f *rule.File) []resolve.ImportSpec {
	if !isGoLibrary(r.Kind()) {
		return nil
	}
	if importPath := r.AttrString("importpath"); importPath == "" {
		return []resolve.ImportSpec{}
	} else {
		return []resolve.ImportSpec{{goName, importPath}}
	}
}

func (_ *goLang) Embeds(r *rule.Rule, from label.Label) []label.Label {
	embedStrings := r.AttrStrings("embed")
	if isGoProtoLibrary(r.Kind()) {
		embedStrings = append(embedStrings, r.AttrString("proto"))
	}
	embedLabels := make([]label.Label, 0, len(embedStrings))
	for _, s := range embedStrings {
		l, err := label.Parse(s)
		if err != nil {
			continue
		}
		l = l.Abs(from.Repo, from.Pkg)
		embedLabels = append(embedLabels, l)
	}
	return embedLabels
}

func (gl *goLang) Resolve(c *config.Config, ix *resolve.RuleIndex, rc *repo.RemoteCache, r *rule.Rule, importsRaw interface{}, from label.Label) {
	if importsRaw == nil {
		// may not be set in tests.
		return
	}
	imports := importsRaw.(rule.PlatformStrings)
	r.DelAttr("deps")
	resolve := resolveGo
	if r.Kind() == "go_proto_library" {
		resolve = resolveProto
	}
	deps, errs := imports.Map(func(imp string) (string, error) {
		l, err := resolve(c, ix, rc, r, imp, from)
		if err == skipImportError {
			return "", nil
		} else if err != nil {
			return "", err
		}
		for _, embed := range gl.Embeds(r, from) {
			if embed.Equal(l) {
				return "", nil
			}
		}
		l = l.Rel(from.Repo, from.Pkg)
		return l.String(), nil
	})
	for _, err := range errs {
		log.Print(err)
	}
	if !deps.IsEmpty() {
		if r.Kind() == "go_proto_library" {
			// protos may import the same library multiple times by different names,
			// so we need to de-duplicate them. Protos are not platform-specific,
			// so it's safe to just flatten them.
			r.SetAttr("deps", deps.Flat())
		} else {
			r.SetAttr("deps", deps)
		}
	}
}

var (
	skipImportError = errors.New("std or self import")
	notFoundError   = errors.New("rule not found")
)

func resolveGo(c *config.Config, ix *resolve.RuleIndex, rc *repo.RemoteCache, r *rule.Rule, imp string, from label.Label) (label.Label, error) {
	gc := getGoConfig(c)
	pcMode := getProtoMode(c)
	if build.IsLocalImport(imp) {
		cleanRel := path.Clean(path.Join(from.Pkg, imp))
		if build.IsLocalImport(cleanRel) {
			return label.NoLabel, fmt.Errorf("relative import path %q from %q points outside of repository", imp, from.Pkg)
		}
		imp = path.Join(gc.prefix, cleanRel)
	}

	if isStandard(imp) {
		return label.NoLabel, skipImportError
	}

	if l, ok := resolve.FindRuleWithOverride(c, resolve.ImportSpec{Lang: "go", Imp: imp}, "go"); ok {
		return l, nil
	}

	if pcMode.ShouldUseKnownImports() {
		// These are commonly used libraries that depend on Well Known Types.
		// They depend on the generated versions of these protos to avoid conflicts.
		// However, since protoc-gen-go depends on these libraries, we generate
		// its rules in disable_global mode (to avoid cyclic dependency), so the
		// "go_default_library" versions of these libraries depend on the
		// pre-generated versions of the proto libraries.
		switch imp {
		case "github.com/golang/protobuf/proto":
			return label.New("com_github_golang_protobuf", "proto", "go_default_library"), nil
		case "github.com/golang/protobuf/jsonpb":
			return label.New("com_github_golang_protobuf", "jsonpb", "go_default_library_gen"), nil
		case "github.com/golang/protobuf/descriptor":
			return label.New("com_github_golang_protobuf", "descriptor", "go_default_library_gen"), nil
		case "github.com/golang/protobuf/ptypes":
			return label.New("com_github_golang_protobuf", "ptypes", "go_default_library_gen"), nil
		case "github.com/golang/protobuf/protoc-gen-go/generator":
			return label.New("com_github_golang_protobuf", "protoc-gen-go/generator", "go_default_library_gen"), nil
		case "google.golang.org/grpc":
			return label.New("org_golang_google_grpc", "", "go_default_library"), nil
		}
		if l, ok := knownGoProtoImports[imp]; ok {
			return l, nil
		}
	}

	if l, err := resolveWithIndexGo(ix, imp, from); err == nil || err == skipImportError {
		return l, err
	} else if err != notFoundError {
		return label.NoLabel, err
	}

	// Special cases for rules_go and bazel_gazelle.
	// These have names that don't following conventions and they're
	// typeically declared with http_archive, not go_repository, so Gazelle
	// won't recognize them.
	if pathtools.HasPrefix(imp, "github.com/bazelbuild/rules_go") {
		pkg := pathtools.TrimPrefix(imp, "github.com/bazelbuild/rules_go")
		return label.New("io_bazel_rules_go", pkg, "go_default_library"), nil
	} else if pathtools.HasPrefix(imp, "github.com/bazelbuild/bazel-gazelle") {
		pkg := pathtools.TrimPrefix(imp, "github.com/bazelbuild/bazel-gazelle")
		return label.New("bazel_gazelle", pkg, "go_default_library"), nil
	}

	if !c.IndexLibraries {
		// packages in current repo were not indexed, relying on prefix to decide what may have been in
		// current repo
		if pathtools.HasPrefix(imp, gc.prefix) {
			pkg := path.Join(gc.prefixRel, pathtools.TrimPrefix(imp, gc.prefix))
			return label.New("", pkg, defaultLibName), nil
		}
	}

	if gc.depMode == externalMode {
		return resolveExternal(rc, imp)
	} else {
		return resolveVendored(rc, imp)
	}
}

// isStandard returns whether a package is in the standard library.
func isStandard(imp string) bool {
	return stdPackages[imp]
}

func resolveWithIndexGo(ix *resolve.RuleIndex, imp string, from label.Label) (label.Label, error) {
	matches := ix.FindRulesByImport(resolve.ImportSpec{Lang: "go", Imp: imp}, "go")
	var bestMatch resolve.FindResult
	var bestMatchIsVendored bool
	var bestMatchVendorRoot string
	var matchError error

	for _, m := range matches {
		// Apply vendoring logic for Go libraries. A library in a vendor directory
		// is only visible in the parent tree. Vendored libraries supercede
		// non-vendored libraries, and libraries closer to from.Pkg supercede
		// those further up the tree.
		isVendored := false
		vendorRoot := ""
		parts := strings.Split(m.Label.Pkg, "/")
		for i := len(parts) - 1; i >= 0; i-- {
			if parts[i] == "vendor" {
				isVendored = true
				vendorRoot = strings.Join(parts[:i], "/")
				break
			}
		}
		if isVendored {
		}
		if isVendored && !label.New(m.Label.Repo, vendorRoot, "").Contains(from) {
			// vendor directory not visible
			continue
		}
		if bestMatch.Label.Equal(label.NoLabel) || isVendored && (!bestMatchIsVendored || len(vendorRoot) > len(bestMatchVendorRoot)) {
			// Current match is better
			bestMatch = m
			bestMatchIsVendored = isVendored
			bestMatchVendorRoot = vendorRoot
			matchError = nil
		} else if (!isVendored && bestMatchIsVendored) || (isVendored && len(vendorRoot) < len(bestMatchVendorRoot)) {
			// Current match is worse
		} else {
			// Match is ambiguous
			// TODO: consider listing all the ambiguous rules here.
			matchError = fmt.Errorf("rule %s imports %q which matches multiple rules: %s and %s. # gazelle:resolve may be used to disambiguate", from, imp, bestMatch.Label, m.Label)
		}
	}
	if matchError != nil {
		return label.NoLabel, matchError
	}
	if bestMatch.Label.Equal(label.NoLabel) {
		return label.NoLabel, notFoundError
	}
	if bestMatch.IsSelfImport(from) {
		return label.NoLabel, skipImportError
	}
	return bestMatch.Label, nil
}

func resolveExternal(rc *repo.RemoteCache, imp string) (label.Label, error) {
	prefix, repo, err := rc.Root(imp)
	if err != nil {
		return label.NoLabel, err
	}

	var pkg string
	if imp != prefix {
		pkg = pathtools.TrimPrefix(imp, prefix)
	}

	return label.New(repo, pkg, defaultLibName), nil
}

func resolveVendored(rc *repo.RemoteCache, imp string) (label.Label, error) {
	return label.New("", path.Join("vendor", imp), defaultLibName), nil
}

func resolveProto(c *config.Config, ix *resolve.RuleIndex, rc *repo.RemoteCache, r *rule.Rule, imp string, from label.Label) (label.Label, error) {
	pcMode := getProtoMode(c)

	if wellKnownProtos[imp] {
		return label.NoLabel, skipImportError
	}

	if l, ok := resolve.FindRuleWithOverride(c, resolve.ImportSpec{Lang: "proto", Imp: imp}, "go"); ok {
		return l, nil
	}

	if l, ok := knownProtoImports[imp]; ok && pcMode.ShouldUseKnownImports() {
		if l.Equal(from) {
			return label.NoLabel, skipImportError
		} else {
			return l, nil
		}
	}

	if l, err := resolveWithIndexProto(ix, imp, from); err == nil || err == skipImportError {
		return l, err
	} else if err != notFoundError {
		return label.NoLabel, err
	}

	// As a fallback, guess the label based on the proto file name. We assume
	// all proto files in a directory belong to the same package, and the
	// package name matches the directory base name. We also assume that protos
	// in the vendor directory must refer to something else in vendor.
	rel := path.Dir(imp)
	if rel == "." {
		rel = ""
	}
	if from.Pkg == "vendor" || strings.HasPrefix(from.Pkg, "vendor/") {
		rel = path.Join("vendor", rel)
	}
	return label.New("", rel, defaultLibName), nil
}

// wellKnownProtos is the set of proto sets for which we don't need to add
// an explicit dependency in go_proto_library.
// TODO(jayconrod): generate from
// @io_bazel_rules_go//proto/wkt:WELL_KNOWN_TYPE_PACKAGES
var wellKnownProtos = map[string]bool{
	"google/protobuf/any.proto":             true,
	"google/protobuf/api.proto":             true,
	"google/protobuf/compiler_plugin.proto": true,
	"google/protobuf/descriptor.proto":      true,
	"google/protobuf/duration.proto":        true,
	"google/protobuf/empty.proto":           true,
	"google/protobuf/field_mask.proto":      true,
	"google/protobuf/source_context.proto":  true,
	"google/protobuf/struct.proto":          true,
	"google/protobuf/timestamp.proto":       true,
	"google/protobuf/type.proto":            true,
	"google/protobuf/wrappers.proto":        true,
}

func resolveWithIndexProto(ix *resolve.RuleIndex, imp string, from label.Label) (label.Label, error) {
	matches := ix.FindRulesByImport(resolve.ImportSpec{Lang: "proto", Imp: imp}, "go")
	if len(matches) == 0 {
		return label.NoLabel, notFoundError
	}
	if len(matches) > 1 {
		return label.NoLabel, fmt.Errorf("multiple rules (%s and %s) may be imported with %q from %s", matches[0].Label, matches[1].Label, imp, from)
	}
	if matches[0].IsSelfImport(from) {
		return label.NoLabel, skipImportError
	}
	return matches[0].Label, nil
}

func isGoLibrary(kind string) bool {
	return kind == "go_library" || isGoProtoLibrary(kind)
}

func isGoProtoLibrary(kind string) bool {
	return kind == "go_proto_library" || kind == "go_grpc_library"
}
<|endoftext|>


<commit_before>package brightbox

import (
	"crypto/sha1"
	"encoding/base64"
	"encoding/hex"

	"github.com/brightbox/gobrightbox"
	"github.com/hashicorp/terraform/helper/schema"
)

func hash_string(
	v interface{},
) string {
	switch v.(type) {
	case string:
		return userDataHashSum(v.(string))
	default:
		return ""
	}
}

func userDataHashSum(user_data string) string {
	// Check whether the user_data is not Base64 encoded.
	// Always calculate hash of base64 decoded value since we
	// check against double-encoding when setting it
	v, base64DecodeError := base64Decode(user_data)
	if base64DecodeError != nil {
		v = user_data
	}
	hash := sha1.Sum([]byte(v))
	return hex.EncodeToString(hash[:])
}

func assign_string(d *schema.ResourceData, target **string, index string) {
	if d.HasChange(index) {
		if *target == nil {
			var temp string
			*target = &temp
		}
		if attr, ok := d.GetOk(index); ok {
			**target = attr.(string)
		}
	}
}

func assign_string_set(d *schema.ResourceData, target **[]string, index string) {
	if d.HasChange(index) {
		assign_string_set_always(d, target, index)
	}
}

func assign_string_set_always(d *schema.ResourceData, target **[]string, index string) {
	var temp []string
	if attr := d.Get(index).(*schema.Set); attr.Len() > 0 {
		for _, v := range attr.List() {
			temp = append(temp, v.(string))
		}
	}
	*target = &temp
}

func assign_int(d *schema.ResourceData, target **int, index string) {
	if d.HasChange(index) {
		var temp int
		if attr, ok := d.GetOk(index); ok {
			temp = attr.(int)
		}
		*target = &temp
	}
}

func assign_bool(d *schema.ResourceData, target **bool, index string) {
	if d.HasChange(index) {
		var temp bool
		if attr, ok := d.GetOk(index); ok {
			temp = attr.(bool)
		}
		*target = &temp
	}
}

func setPrimaryCloudIp(d *schema.ResourceData, cloud_ip *brightbox.CloudIP) {
	d.Set("ipv4_address", cloud_ip.PublicIP)
	d.SetPartial("ipv4_address")
	d.Set("public_hostname", cloud_ip.Fqdn)
	d.SetPartial("public_hostname")
}

// Base64Encode encodes data if the input isn't already encoded
// using base64.StdEncoding.EncodeToString. If the input is already base64
// encoded, return the original input unchanged.
func base64Encode(data string) string {
	// Check whether the data is already Base64 encoded; don't double-encode
	if isBase64Encoded(data) {
		return data
	}
	// data has not been encoded encode and return
	return base64.StdEncoding.EncodeToString([]byte(data))
}

func isBase64Encoded(data string) bool {
	_, err := base64Decode(data)
	return err == nil
}

func base64Decode(data string) (string, error) {
	result, err := base64.StdEncoding.DecodeString(data)
	return string(result), err
}
<commit_msg>Use make rather than append to create string slice<commit_after>package brightbox

import (
	"crypto/sha1"
	"encoding/base64"
	"encoding/hex"

	"github.com/brightbox/gobrightbox"
	"github.com/hashicorp/terraform/helper/schema"
)

func hash_string(
	v interface{},
) string {
	switch v.(type) {
	case string:
		return userDataHashSum(v.(string))
	default:
		return ""
	}
}

func userDataHashSum(user_data string) string {
	// Check whether the user_data is not Base64 encoded.
	// Always calculate hash of base64 decoded value since we
	// check against double-encoding when setting it
	v, base64DecodeError := base64Decode(user_data)
	if base64DecodeError != nil {
		v = user_data
	}
	hash := sha1.Sum([]byte(v))
	return hex.EncodeToString(hash[:])
}

func assign_string(d *schema.ResourceData, target **string, index string) {
	if d.HasChange(index) {
		if *target == nil {
			var temp string
			*target = &temp
		}
		if attr, ok := d.GetOk(index); ok {
			**target = attr.(string)
		}
	}
}

func assign_string_set(d *schema.ResourceData, target **[]string, index string) {
	if d.HasChange(index) {
		assign_string_set_always(d, target, index)
	}
}

func assign_string_set_always(d *schema.ResourceData, target **[]string, index string) {
	var temp []string
	if attr := d.Get(index).(*schema.Set); attr.Len() > 0 {
		temp = make([]string, attr.Len())
		for i, v := range attr.List() {
			temp[i] = v.(string)
		}
	}
	*target = &temp
}

func assign_int(d *schema.ResourceData, target **int, index string) {
	if d.HasChange(index) {
		var temp int
		if attr, ok := d.GetOk(index); ok {
			temp = attr.(int)
		}
		*target = &temp
	}
}

func assign_bool(d *schema.ResourceData, target **bool, index string) {
	if d.HasChange(index) {
		var temp bool
		if attr, ok := d.GetOk(index); ok {
			temp = attr.(bool)
		}
		*target = &temp
	}
}

func setPrimaryCloudIp(d *schema.ResourceData, cloud_ip *brightbox.CloudIP) {
	d.Set("ipv4_address", cloud_ip.PublicIP)
	d.SetPartial("ipv4_address")
	d.Set("public_hostname", cloud_ip.Fqdn)
	d.SetPartial("public_hostname")
}

// Base64Encode encodes data if the input isn't already encoded
// using base64.StdEncoding.EncodeToString. If the input is already base64
// encoded, return the original input unchanged.
func base64Encode(data string) string {
	// Check whether the data is already Base64 encoded; don't double-encode
	if isBase64Encoded(data) {
		return data
	}
	// data has not been encoded encode and return
	return base64.StdEncoding.EncodeToString([]byte(data))
}

func isBase64Encoded(data string) bool {
	_, err := base64Decode(data)
	return err == nil
}

func base64Decode(data string) (string, error) {
	result, err := base64.StdEncoding.DecodeString(data)
	return string(result), err
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"strings"
)

const (
	ADD_SERVICE    = "http://localhost:3000/api/v1/service/add"
	RUN_CONTAINER  = "http://localhost:3000/api/v1/container/run"
	LIST_CONTAINER = "http://localhost:3000/api/v1/container/list"
	EXEC_CONTAINER = "http://localhost:3000/api/v1/container/exec"
)

func call(url string) {
	if len(os.Args) != 4 {
		help()
		return
	}

	filename := os.Args[3]

	raw, err := ioutil.ReadFile(filename)
	if err != nil {
		fmt.Println(err)
		return
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(raw))
	req.Header.Set("Content-Type", "application/json")
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != 201 {
		body, _ := ioutil.ReadAll(resp.Body)
		fmt.Println(string(body))
	}
}

func list_containers() {
	resp, err := http.Get(LIST_CONTAINER)
	if err != nil {
		fmt.Println(err)
		return
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(body))
}

func exec_container() {
	if len(os.Args) <= 4 {
		help()
		return
	}

	raw := []byte(fmt.Sprintf("{\"name\":\"%s\"}", os.Args[3]))
	fmt.Println(string(raw))
	req, err := http.NewRequest("POST", EXEC_CONTAINER, bytes.NewBuffer(raw))
	req.Header.Set("Content-Type", "application/json")
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}

	pid := string(body)
	cmd := strings.Join(os.Args[4:], " ")
	path, err := exec.LookPath("nsenter")
	if err != nil {
		fmt.Println("Cannot find nsenter")
		return
	}

	command := strings.Split(fmt.Sprintf("%s --target %s --pid --net %s", path, pid, cmd), " ")
	run := &exec.Cmd{
		Path: command[0],
		Args: command,
	}

	run.Stdin = os.Stdin
	run.Stdout = os.Stdout
	run.Stderr = os.Stderr
	run.Start()
	run.Wait()
}

func help() {
}

func main() {
	switch os.Args[1] {
	case "service":
		switch os.Args[2] {
		case "add":
			call(ADD_SERVICE)
		}
	case "container":
		switch os.Args[2] {
		case "run":
			call(RUN_CONTAINER)
		case "list":
			list_containers()
		case "exec":
			exec_container()
		}
	}
}
<commit_msg>Now handles mount namespaces on client<commit_after>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"strings"
)

const (
	ADD_SERVICE    = "http://localhost:3000/api/v1/service/add"
	RUN_CONTAINER  = "http://localhost:3000/api/v1/container/run"
	LIST_CONTAINER = "http://localhost:3000/api/v1/container/list"
	EXEC_CONTAINER = "http://localhost:3000/api/v1/container/exec"
)

func call(url string) {
	if len(os.Args) != 4 {
		help()
		return
	}

	filename := os.Args[3]

	raw, err := ioutil.ReadFile(filename)
	if err != nil {
		fmt.Println(err)
		return
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(raw))
	req.Header.Set("Content-Type", "application/json")
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != 201 {
		body, _ := ioutil.ReadAll(resp.Body)
		fmt.Println(string(body))
	}
}

func list_containers() {
	resp, err := http.Get(LIST_CONTAINER)
	if err != nil {
		fmt.Println(err)
		return
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(string(body))
}

func exec_container() {
	if len(os.Args) <= 4 {
		help()
		return
	}

	raw := []byte(fmt.Sprintf("{\"name\":\"%s\"}", os.Args[3]))
	fmt.Println(string(raw))
	req, err := http.NewRequest("POST", EXEC_CONTAINER, bytes.NewBuffer(raw))
	req.Header.Set("Content-Type", "application/json")
	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(err)
		return
	}

	pid := string(body)
	cmd := strings.Join(os.Args[4:], " ")
	path, err := exec.LookPath("nsenter")
	if err != nil {
		fmt.Println("Cannot find nsenter")
		return
	}

	command := strings.Split(fmt.Sprintf("%s --target %s --pid --net --mount %s", path, pid, cmd), " ")
	run := &exec.Cmd{
		Path: command[0],
		Args: command,
	}

	run.Stdin = os.Stdin
	run.Stdout = os.Stdout
	run.Stderr = os.Stderr
	run.Start()
	run.Wait()
}

func help() {
}

func main() {
	switch os.Args[1] {
	case "service":
		switch os.Args[2] {
		case "add":
			call(ADD_SERVICE)
		}
	case "container":
		switch os.Args[2] {
		case "run":
			call(RUN_CONTAINER)
		case "list":
			list_containers()
		case "exec":
			exec_container()
		}
	}
}
<|endoftext|>


<commit_before>package ndbm

import (
	"bytes"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"testing"
)

func TestNDBM(t *testing.T) {
	// create a temp dir for test files
	tempdir, err := ioutil.TempDir("", "TestNDBM")
	if err != nil {
		t.Fatalf("Couldn't create tempdir for test DB: %v", err)
	}
	defer os.RemoveAll(tempdir)

	// create a new DB in that temp dir
	ndbm, err := OpenWithDefaults(filepath.Join(tempdir, "test"))
	if err != nil {
		t.Fatalf("Couldn't open DB: %v", err)
	}
	defer ndbm.Close()

	// check the empty database
	if ndbm.Len() != 0 {
		t.Error("Empty DB should have no keys")
	}

	// insert some data
	{
		items := Items{
			Item{[]byte("a"), []byte("alphabet")},
			Item{[]byte("b"), []byte("battlement")},
			Item{[]byte("c"), []byte("carnival")},
			Item{[]byte("d"), []byte("dinosaur")},
		}
		err := ndbm.Update(items)
		if err != nil {
			t.Errorf("Error on update: %v", err)
		}
		if ndbm.Len() != 4 {
			t.Errorf("DB should have 4 keys, but actually has %d", ndbm.Len())
		}
	}

	// try to fetch a key that doesn't exist, which should fail
	{
		value, err := ndbm.Fetch([]byte("x"))
		if value != nil || err == nil {
			t.Errorf("Expected error on fetch")
		} else {
			_, expected := err.(KeyNotFound)
			if !expected {
				t.Errorf("Error on fetch: %v", err)
			}
		}
	}

	// try to insert a key that already exists, which should fail
	{
		err := ndbm.Insert([]byte("c"), []byte("contentment"))
		if err == nil {
			t.Errorf("Expected error on insert")
		} else {
			_, expected := err.(KeyAlreadyExists)
			if !expected {
				t.Errorf("Error on insert: %v", err)
			}
		}
		if ndbm.Len() != 4 {
			t.Errorf("DB should still have 4 keys, but actually has %d", ndbm.Len())
		}
	}

	// replace a key that already exists
	{
		err := ndbm.Replace([]byte("c"), []byte("contentment"))
		if err != nil {
			t.Errorf("Error on replace: %v", err)
		}
		if ndbm.Len() != 4 {
			t.Errorf("DB should still have 4 keys, but actually has %d", ndbm.Len())
		}
	}

	// delete a key
	{
		err := ndbm.Delete([]byte("b"))
		if err != nil {
			t.Errorf("Error on delete: %v", err)
		}
		if ndbm.Len() != 3 {
			t.Errorf("DB should have 3 keys, but actually has %d", ndbm.Len())
		}
	}

	// delete a key that has already been deleted, which should fail
	{
		err := ndbm.Delete([]byte("b"))
		if err == nil {
			t.Errorf("Expected error on delete")
		} else {
			_, expected := err.(KeyNotFound)
			if !expected {
				t.Errorf("Error on delete: %v", err)
			}
		}
		if ndbm.Len() != 3 {
			t.Errorf("DB should have 3 keys, but actually has %d", ndbm.Len())
		}
	}

	// delete a key that has never existed, which should fail
	{
		err := ndbm.Delete([]byte("x"))
		if err == nil {
			t.Errorf("Expected error on delete")
		} else {
			_, expected := err.(KeyNotFound)
			if !expected {
				t.Errorf("Error on delete: %v", err)
			}
		}
	}

	// get all contents, see if it's what we expected
	{
		expected := Items{
			Item{[]byte("a"), []byte("alphabet")},
			Item{[]byte("c"), []byte("contentment")},
			Item{[]byte("d"), []byte("dinosaur")},
		}
		actual := ndbm.Items()
		if len(expected) != len(actual) {
			t.Fatalf(
				"Expected and actual DB contents have different lengths: %d vs. %d",
				len(expected), len(actual))
		}
		sort.Sort(actual)
		for i, expectedItem := range expected {
			actualItem := actual[i]
			if bytes.Compare(expectedItem.Key, actualItem.Key) != 0 {
				t.Errorf("Expected and actual items %d have different keys: %s vs. %s",
					expectedItem.Key, actualItem.Key)
			}
			if bytes.Compare(expectedItem.Value, actualItem.Value) != 0 {
				t.Errorf("Expected and actual items %d have different values: %s vs. %s",
					expectedItem.Value, actualItem.Value)
			}
		}
	}
}
<commit_msg>Fix formatting calls in tests<commit_after>package ndbm

import (
	"bytes"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"testing"
)

func TestNDBM(t *testing.T) {
	// create a temp dir for test files
	tempdir, err := ioutil.TempDir("", "TestNDBM")
	if err != nil {
		t.Fatalf("Couldn't create tempdir for test DB: %v", err)
	}
	defer os.RemoveAll(tempdir)

	// create a new DB in that temp dir
	ndbm, err := OpenWithDefaults(filepath.Join(tempdir, "test"))
	if err != nil {
		t.Fatalf("Couldn't open DB: %v", err)
	}
	defer ndbm.Close()

	// check the empty database
	if ndbm.Len() != 0 {
		t.Error("Empty DB should have no keys")
	}

	// insert some data
	{
		items := Items{
			Item{[]byte("a"), []byte("alphabet")},
			Item{[]byte("b"), []byte("battlement")},
			Item{[]byte("c"), []byte("carnival")},
			Item{[]byte("d"), []byte("dinosaur")},
		}
		err := ndbm.Update(items)
		if err != nil {
			t.Errorf("Error on update: %v", err)
		}
		if ndbm.Len() != 4 {
			t.Errorf("DB should have 4 keys, but actually has %d", ndbm.Len())
		}
	}

	// try to fetch a key that doesn't exist, which should fail
	{
		value, err := ndbm.Fetch([]byte("x"))
		if value != nil || err == nil {
			t.Errorf("Expected error on fetch")
		} else {
			_, expected := err.(KeyNotFound)
			if !expected {
				t.Errorf("Error on fetch: %v", err)
			}
		}
	}

	// try to insert a key that already exists, which should fail
	{
		err := ndbm.Insert([]byte("c"), []byte("contentment"))
		if err == nil {
			t.Errorf("Expected error on insert")
		} else {
			_, expected := err.(KeyAlreadyExists)
			if !expected {
				t.Errorf("Error on insert: %v", err)
			}
		}
		if ndbm.Len() != 4 {
			t.Errorf("DB should still have 4 keys, but actually has %d", ndbm.Len())
		}
	}

	// replace a key that already exists
	{
		err := ndbm.Replace([]byte("c"), []byte("contentment"))
		if err != nil {
			t.Errorf("Error on replace: %v", err)
		}
		if ndbm.Len() != 4 {
			t.Errorf("DB should still have 4 keys, but actually has %d", ndbm.Len())
		}
	}

	// delete a key
	{
		err := ndbm.Delete([]byte("b"))
		if err != nil {
			t.Errorf("Error on delete: %v", err)
		}
		if ndbm.Len() != 3 {
			t.Errorf("DB should have 3 keys, but actually has %d", ndbm.Len())
		}
	}

	// delete a key that has already been deleted, which should fail
	{
		err := ndbm.Delete([]byte("b"))
		if err == nil {
			t.Errorf("Expected error on delete")
		} else {
			_, expected := err.(KeyNotFound)
			if !expected {
				t.Errorf("Error on delete: %v", err)
			}
		}
		if ndbm.Len() != 3 {
			t.Errorf("DB should have 3 keys, but actually has %d", ndbm.Len())
		}
	}

	// delete a key that has never existed, which should fail
	{
		err := ndbm.Delete([]byte("x"))
		if err == nil {
			t.Errorf("Expected error on delete")
		} else {
			_, expected := err.(KeyNotFound)
			if !expected {
				t.Errorf("Error on delete: %v", err)
			}
		}
	}

	// get all contents, see if it's what we expected
	{
		expected := Items{
			Item{[]byte("a"), []byte("alphabet")},
			Item{[]byte("c"), []byte("contentment")},
			Item{[]byte("d"), []byte("dinosaur")},
		}
		actual := ndbm.Items()
		if len(expected) != len(actual) {
			t.Fatalf(
				"Expected and actual DB contents have different lengths: %d vs. %d",
				len(expected), len(actual))
		}
		sort.Sort(actual)
		for i, expectedItem := range expected {
			actualItem := actual[i]
			if bytes.Compare(expectedItem.Key, actualItem.Key) != 0 {
				t.Errorf("Expected and actual items %d have different keys: %s vs. %s",
					i, expectedItem.Key, actualItem.Key)
			}
			if bytes.Compare(expectedItem.Value, actualItem.Value) != 0 {
				t.Errorf("Expected and actual items %d have different values: %s vs. %s",
					i, expectedItem.Value, actualItem.Value)
			}
		}
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
//
// Based on Cassis by Tantek Çelik, released under CC0 license.

// Package newbase60 implements NewBase60 encoding and decoding as specified by
// http://ttk.me/w/NewBase60.
package newbase60

const table = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ_abcdefghijkmnopqrstuvwxyz"

// DecodeToInt decodes the sexagesimal number s to an int.
func DecodeToInt(s string) int {
	var n int
	for i := 0; i < len(s); i++ {
		c := s[i]
		switch {
		case 48 <= c && c <= 57:
			c -= 48
		case 65 <= c && c <= 72:
			c -= 55
		case c == 73 || c == 108:
			c = 1 // capital I, lowercase l => 1
		case 74 <= c && c <= 78:
			c -= 56
		case c == 79:
			c = 0 // capital O => 0
		case 80 <= c && c <= 90:
			c -= 57
		case c == 95:
			c = 34 // underscore
		case 97 <= c && c <= 107:
			c -= 62
		case 109 <= c && c <= 122:
			c -= 63
		default:
			c = 0 // treat all other noise as 0
		}
		n = (60 * n) + int(c)
	}
	return n
}

// EncodeInt encodes the positive integer n to a sexagesimal
// string.
func EncodeInt(n int) string {
	var s string
	for n > 0 {
		d := n % 60
		s = string(table[d]) + s
		n = (n - d) / 60
	}

	return s
}
<commit_msg>add new go14-style import comments<commit_after>// Copyright 2014 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
//
// Based on Cassis by Tantek Çelik, released under CC0 license.

// Package newbase60 implements NewBase60 encoding and decoding as specified by
// http://ttk.me/w/NewBase60.
package newbase60 // import "willnorris.com/go/newbase60"

const table = "0123456789ABCDEFGHJKLMNPQRSTUVWXYZ_abcdefghijkmnopqrstuvwxyz"

// DecodeToInt decodes the sexagesimal number s to an int.
func DecodeToInt(s string) int {
	var n int
	for i := 0; i < len(s); i++ {
		c := s[i]
		switch {
		case 48 <= c && c <= 57:
			c -= 48
		case 65 <= c && c <= 72:
			c -= 55
		case c == 73 || c == 108:
			c = 1 // capital I, lowercase l => 1
		case 74 <= c && c <= 78:
			c -= 56
		case c == 79:
			c = 0 // capital O => 0
		case 80 <= c && c <= 90:
			c -= 57
		case c == 95:
			c = 34 // underscore
		case 97 <= c && c <= 107:
			c -= 62
		case 109 <= c && c <= 122:
			c -= 63
		default:
			c = 0 // treat all other noise as 0
		}
		n = (60 * n) + int(c)
	}
	return n
}

// EncodeInt encodes the positive integer n to a sexagesimal
// string.
func EncodeInt(n int) string {
	var s string
	for n > 0 {
		d := n % 60
		s = string(table[d]) + s
		n = (n - d) / 60
	}

	return s
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"path"
	"path/filepath"
	"strings"

	swarming_api "go.chromium.org/luci/common/api/swarming/swarming/v1"
	"go.skia.org/infra/go/auth"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/swarming"
)

var (
	pool    = flag.String("pool", "Skia", "Which Swarming pool to use.")
	server  = flag.String("server", "https://chromium-swarm.appspot.com", "Swarming server to use.")
	workdir = flag.String("workdir", ".", "Working directory used to find the google_storage_token.data Optional, but recommended not to use CWD.")
)

func log(f string, args ...interface{}) {
	fmt.Println(fmt.Sprintf(f, args...))
}

func logResult(botList []*swarming_api.SwarmingRpcsBotInfo, auth string) {
	msg := fmt.Sprintf("%d\t%s", len(botList), auth)
	if len(botList) > 0 {
		msg += fmt.Sprintf("\teg. %s: %s", botList[0].BotId, botList[0].AuthenticatedAs)
	}
	log(msg)
}

func main() {
	common.Init()

	var err error
	*workdir, err = filepath.Abs(*workdir)
	if err != nil {
		sklog.Fatal(err)
	}

	// Authenticated HTTP client.
	oauthCacheFile := path.Join(*workdir, "google_storage_token.data")
	httpClient, err := auth.NewClientWithTransport(true, oauthCacheFile, "client_secret_skia-buildbots.json", nil, swarming.AUTH_SCOPE)
	if err != nil {
		sklog.Fatalf("Could not authenticate. Did you get the swarming client_secret and put it in %s? : %s", *workdir, err)
	}

	// Swarming API client.
	swarmApi, err := swarming.NewApiClient(httpClient, swarming.SWARMING_SERVER)
	if err != nil {
		sklog.Fatal(err)
	}

	// Obtain the list of bots in this pool.
	bots, err := swarmApi.ListBots(map[string]string{
		"pool": *pool,
	})
	if err != nil {
		sklog.Fatal(err)
	}
	log("%d bots in pool %s on %s.", len(bots), *pool, *server)

	// For each bot, determine whether it's using the new auth.
	var ip, bot, user, other []*swarming_api.SwarmingRpcsBotInfo
	for _, b := range bots {
		if b.AuthenticatedAs == "bot:whitelisted-ip" {
			ip = append(ip, b)
		} else if strings.HasPrefix(b.AuthenticatedAs, "bot:") {
			bot = append(bot, b)
		} else if strings.HasPrefix(b.AuthenticatedAs, "user:") {
			user = append(user, b)
		} else {
			other = append(other, b)
		}
	}
	logResult(ip, "IP whitelist")
	logResult(bot, "as bot\t")
	logResult(user, "as user\t")
	logResult(other, "other\t")
}
<commit_msg>Tweaks for check_swarming_bot_auth<commit_after>package main

import (
	"flag"
	"fmt"
	"path"
	"path/filepath"
	"strings"

	swarming_api "go.chromium.org/luci/common/api/swarming/swarming/v1"
	"go.skia.org/infra/go/auth"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/swarming"
)

var (
	pool    = flag.String("pool", "Skia", "Which Swarming pool to use.")
	server  = flag.String("server", "chromium-swarm.appspot.com", "Swarming server to use.")
	workdir = flag.String("workdir", ".", "Working directory used to find the google_storage_token.data Optional, but recommended not to use CWD.")
)

func log(f string, args ...interface{}) {
	fmt.Println(fmt.Sprintf(f, args...))
}

func logResult(botList []*swarming_api.SwarmingRpcsBotInfo, auth string) {
	msg := fmt.Sprintf("%d\t%s", len(botList), auth)
	if len(botList) > 0 {
		msg += fmt.Sprintf("\teg. %s: %s", botList[0].BotId, botList[0].AuthenticatedAs)
	}
	log(msg)
}

func main() {
	common.Init()

	var err error
	*workdir, err = filepath.Abs(*workdir)
	if err != nil {
		sklog.Fatal(err)
	}

	// Authenticated HTTP client.
	oauthCacheFile := path.Join(*workdir, "google_storage_token.data")
	httpClient, err := auth.NewClientWithTransport(true, oauthCacheFile, "client_secret_skia-buildbots.json", nil, swarming.AUTH_SCOPE)
	if err != nil {
		sklog.Fatalf("Could not authenticate. Did you get the swarming client_secret and put it in %s? : %s", *workdir, err)
	}

	// Swarming API client.
	swarmApi, err := swarming.NewApiClient(httpClient, *server)
	if err != nil {
		sklog.Fatal(err)
	}

	// Obtain the list of bots in this pool.
	bots, err := swarmApi.ListBots(map[string]string{
		"pool": *pool,
	})
	if err != nil {
		sklog.Fatal(err)
	}
	log("%d bots in pool %s on %s.", len(bots), *pool, *server)

	// For each bot, determine whether it's using the new auth.
	var ip, bot, user, other []*swarming_api.SwarmingRpcsBotInfo
	for _, b := range bots {
		if b.AuthenticatedAs == "bot:whitelisted-ip" {
			if len(ip) == 0 {
				log("The following bots are IP-whitelisted:")
			}
			log("  %s", b.BotId)
			ip = append(ip, b)
		} else if strings.HasPrefix(b.AuthenticatedAs, "bot:") {
			bot = append(bot, b)
		} else if strings.HasPrefix(b.AuthenticatedAs, "user:") {
			user = append(user, b)
		} else {
			other = append(other, b)
		}
	}
	log("")
	logResult(ip, "IP whitelist")
	logResult(bot, "as bot\t")
	logResult(user, "as user\t")
	logResult(other, "other\t")
}
<|endoftext|>


<commit_before>// (c) 2020, Alex Willmer. All rights reserved.
// See the file LICENSE for licensing terms.

package utils

import (
	"fmt"
	"net"
	"testing"
)

func TestIPDescEqual(t *testing.T) {
	tests := []struct {
		ipDesc1 IPDesc
		ipDesc2 IPDesc
		result  bool
	}{
		// Expected equal
		{
			IPDesc{net.ParseIP("127.0.0.1"), 0},
			IPDesc{net.ParseIP("127.0.0.1"), 0},
			true,
		}, {
			IPDesc{net.ParseIP("::1"), 0},
			IPDesc{net.ParseIP("::1"), 0},
			true,
		}, {
			IPDesc{net.ParseIP("127.0.0.1"), 0},
			IPDesc{net.ParseIP("::ffff:127.0.0.1"), 0},
			true,
		},

		// Expected unequal
		{
			IPDesc{net.ParseIP("127.0.0.1"), 0},
			IPDesc{net.ParseIP("1.2.3.4"), 0},
			false,
		}, {
			IPDesc{net.ParseIP("::1"), 0},
			IPDesc{net.ParseIP("2001::1"), 0},
			false,
		}, {
			IPDesc{net.ParseIP("127.0.0.1"), 0},
			IPDesc{net.ParseIP("127.0.0.1"), 1},
			false,
		},
	}
	for i, tt := range tests {
		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
			if tt.ipDesc1.IP == nil {
				t.Error("ipDesc1 nil")
			} else if tt.ipDesc2.IP == nil {
				t.Error("ipDesc2 nil")
			}
			result := tt.ipDesc1.Equal(tt.ipDesc2)
			if result && result != tt.result {
				t.Error("Expected IPDesc to be equal, but they were not")
			}
			if !result && result != tt.result {
				t.Error("Expected IPDesc to be unequal, but they were equal")
			}
		})
	}
}
<commit_msg>utils: Add test for IPDesc.PortString<commit_after>// (c) 2020, Alex Willmer. All rights reserved.
// See the file LICENSE for licensing terms.

package utils

import (
	"fmt"
	"net"
	"testing"
)

func TestIPDescEqual(t *testing.T) {
	tests := []struct {
		ipDesc1 IPDesc
		ipDesc2 IPDesc
		result  bool
	}{
		// Expected equal
		{
			IPDesc{net.ParseIP("127.0.0.1"), 0},
			IPDesc{net.ParseIP("127.0.0.1"), 0},
			true,
		}, {
			IPDesc{net.ParseIP("::1"), 0},
			IPDesc{net.ParseIP("::1"), 0},
			true,
		}, {
			IPDesc{net.ParseIP("127.0.0.1"), 0},
			IPDesc{net.ParseIP("::ffff:127.0.0.1"), 0},
			true,
		},

		// Expected unequal
		{
			IPDesc{net.ParseIP("127.0.0.1"), 0},
			IPDesc{net.ParseIP("1.2.3.4"), 0},
			false,
		}, {
			IPDesc{net.ParseIP("::1"), 0},
			IPDesc{net.ParseIP("2001::1"), 0},
			false,
		}, {
			IPDesc{net.ParseIP("127.0.0.1"), 0},
			IPDesc{net.ParseIP("127.0.0.1"), 1},
			false,
		},
	}
	for i, tt := range tests {
		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
			if tt.ipDesc1.IP == nil {
				t.Error("ipDesc1 nil")
			} else if tt.ipDesc2.IP == nil {
				t.Error("ipDesc2 nil")
			}
			result := tt.ipDesc1.Equal(tt.ipDesc2)
			if result && result != tt.result {
				t.Error("Expected IPDesc to be equal, but they were not")
			}
			if !result && result != tt.result {
				t.Error("Expected IPDesc to be unequal, but they were equal")
			}
		})
	}
}

func TestIPDescPortString(t *testing.T) {
	tests := []struct {
		ipDesc IPDesc
		result string
	}{
		{IPDesc{net.ParseIP("127.0.0.1"), 0}, ":0"},
		{IPDesc{net.ParseIP("::1"), 42}, ":42"},
		{IPDesc{net.ParseIP("::ffff:127.0.0.1"), 65535}, ":65535"},
		{IPDesc{net.IP{}, 1234}, ":1234"},
	}
	for _, tt := range tests {
		t.Run(tt.result, func(t *testing.T) {
			if result := tt.ipDesc.PortString(); result != tt.result {
				t.Errorf("Expected %q, got %q", tt.result, result)
			}
		})
	}
}
<|endoftext|>