<commit_before>/*
 * Copyright 2017 Ludovic Fauvet <etix@l0cal.com>
 *
 * 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 xdgraph provides a simple helper for manipulating Dgraph
// gRPC responses.
package xdgraph

import (
	"encoding/json"
	"time"

	"github.com/dgraph-io/dgraph/protos"
	"github.com/twpayne/go-geom"
	"github.com/twpayne/go-geom/encoding/wkb"
)

// ReadResponse is the entry point of this package
// It takes in parameter the response from a gRPC call:
//  resp, _ := c.Run(...)
//  xd := xdgraph.ReadResponse(resp)
//  [...]
func ReadResponse(resp *protos.Response) *Response {
	return &Response{
		nodes: []*protos.Node{resp.GetN()[0]},
	}
}

// Response is a struct that carries the current graph.Node.
type Response struct {
	nodes []*protos.Node
}

// First can be used to access the first attribute without explicitely
// giving its name.
func (r Response) First() Response {
	if len(r.nodes) == 0 {
		return Response{}
	}
	if len(r.nodes[0].GetChildren()) == 0 {
		return Response{}
	}
	return Response{nodes: []*protos.Node{r.nodes[0].GetChildren()[0]}}
}

// Attribute moves to the given attribute name. It must be a children of
// the current attribute. This can be asserted using the IsNil() function.
func (r Response) Attribute(name string) Response {
	if len(r.nodes) == 0 {
		return Response{}
	}
	var nodes []*protos.Node
	for _, n := range r.nodes {
		for _, c := range n.GetChildren() {
			if c.GetAttribute() == name {
				nodes = append(nodes, c)
			}
		}
	}

	return Response{nodes: nodes}
}

// Property returns the given property by name.
func (r Response) Property(name string) Property {
	if len(r.nodes) == 0 {
		return Property{}
	}
	for _, p := range r.nodes[0].GetProperties() {
		if p.GetProp() == name {
			return Property{value: p.GetValue()}
		}
	}
	return Property{}
}

// Properties returns a slice of properties by name.
func (r Response) Properties(name string) []Property {
	var properties []Property
	for _, n := range r.nodes {
		for _, p := range n.GetProperties() {
			if p.GetProp() == name {
				properties = append(properties, Property{value: p.GetValue()})
			}
		}
	}
	return properties
}

// Each will run the provided function for each elements contained in the
// response. Example:
//  xd.First().Attribute("follows").Each(func(r xdgraph.Response) {
//      fmt.Println(r.Property("name").ToString())
//  })
func (r Response) Each(fn func(Response)) {
	for _, n := range r.nodes {
		fn(Response{nodes: []*protos.Node{n}})
	}
}

// String returns the attribute content in RAW format.
func (r Response) String() string {
	return r.Json()
}

// Json returns the attribute content in JSON format.
func (r Response) Json() string {
	if len(r.nodes) == 0 {
		return ""
	}
	j, _ := json.MarshalIndent(r.nodes, "", "    ")
	return string(j)
}

// IsNil returns true if the attribute is not available in the response.
func (r Response) IsNil() bool {
	if len(r.nodes) == 0 {
		return true
	}
	return false
}

// Property is a struct that carries the current graph.Value.
type Property struct {
	value *protos.Value
}

// String returns the RAW value
func (p Property) String() string {
	return p.value.String()
}

// ToString returns the property as a string
func (p Property) ToString() string {
	str := p.value.GetStrVal()
	if len(str) > 0 {
		return str
	}
	return p.value.GetDefaultVal()
}

// ToBytes returns the property as []byte
func (p Property) ToBytes() []byte {
	return p.value.GetBytesVal()
}

// ToInt returns the property as an int64
func (p Property) ToInt() int64 {
	return p.value.GetIntVal()
}

// ToBool returns the property as a bool
func (p Property) ToBool() bool {
	return p.value.GetBoolVal()
}

// ToFloat returns the property as a float64
func (p Property) ToFloat() float64 {
	return p.value.GetDoubleVal()
}

// ToGeo returns the property as a geom.T
func (p Property) ToGeo() geom.T {
	t, _ := wkb.Unmarshal(p.value.GetGeoVal())
	return t
}

// ToDate returns the property as a time.Time
func (p Property) ToDate() time.Time {
	var t time.Time
	t.UnmarshalBinary(p.value.GetDateVal())
	return t
}

// ToDateTime returns the property as a time.Time
func (p Property) ToDateTime() time.Time {
	var t time.Time
	t.UnmarshalBinary(p.value.GetDatetimeVal())
	return t
}

// ToPassword returns the property as a string
func (p Property) ToPassword() string {
	return p.value.GetPasswordVal()
}

// ToUid returns the property as a uint64
func (p Property) ToUid() uint64 {
	return p.value.GetUidVal()
}

// IsNil returns true if the property is not available in the response.
func (p Property) IsNil() bool {
	return p.value == nil
}
<commit_msg>ToDate removed from upstream<commit_after>/*
 * Copyright 2017 Ludovic Fauvet <etix@l0cal.com>
 *
 * 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 xdgraph provides a simple helper for manipulating Dgraph
// gRPC responses.
package xdgraph

import (
	"encoding/json"
	"time"

	"github.com/dgraph-io/dgraph/protos"
	"github.com/twpayne/go-geom"
	"github.com/twpayne/go-geom/encoding/wkb"
)

// ReadResponse is the entry point of this package
// It takes in parameter the response from a gRPC call:
//  resp, _ := c.Run(...)
//  xd := xdgraph.ReadResponse(resp)
//  [...]
func ReadResponse(resp *protos.Response) *Response {
	return &Response{
		nodes: []*protos.Node{resp.GetN()[0]},
	}
}

// Response is a struct that carries the current graph.Node.
type Response struct {
	nodes []*protos.Node
}

// First can be used to access the first attribute without explicitely
// giving its name.
func (r Response) First() Response {
	if len(r.nodes) == 0 {
		return Response{}
	}
	if len(r.nodes[0].GetChildren()) == 0 {
		return Response{}
	}
	return Response{nodes: []*protos.Node{r.nodes[0].GetChildren()[0]}}
}

// Attribute moves to the given attribute name. It must be a children of
// the current attribute. This can be asserted using the IsNil() function.
func (r Response) Attribute(name string) Response {
	if len(r.nodes) == 0 {
		return Response{}
	}
	var nodes []*protos.Node
	for _, n := range r.nodes {
		for _, c := range n.GetChildren() {
			if c.GetAttribute() == name {
				nodes = append(nodes, c)
			}
		}
	}

	return Response{nodes: nodes}
}

// Property returns the given property by name.
func (r Response) Property(name string) Property {
	if len(r.nodes) == 0 {
		return Property{}
	}
	for _, p := range r.nodes[0].GetProperties() {
		if p.GetProp() == name {
			return Property{value: p.GetValue()}
		}
	}
	return Property{}
}

// Properties returns a slice of properties by name.
func (r Response) Properties(name string) []Property {
	var properties []Property
	for _, n := range r.nodes {
		for _, p := range n.GetProperties() {
			if p.GetProp() == name {
				properties = append(properties, Property{value: p.GetValue()})
			}
		}
	}
	return properties
}

// Each will run the provided function for each elements contained in the
// response. Example:
//  xd.First().Attribute("follows").Each(func(r xdgraph.Response) {
//      fmt.Println(r.Property("name").ToString())
//  })
func (r Response) Each(fn func(Response)) {
	for _, n := range r.nodes {
		fn(Response{nodes: []*protos.Node{n}})
	}
}

// String returns the attribute content in RAW format.
func (r Response) String() string {
	return r.Json()
}

// Json returns the attribute content in JSON format.
func (r Response) Json() string {
	if len(r.nodes) == 0 {
		return ""
	}
	j, _ := json.MarshalIndent(r.nodes, "", "    ")
	return string(j)
}

// IsNil returns true if the attribute is not available in the response.
func (r Response) IsNil() bool {
	if len(r.nodes) == 0 {
		return true
	}
	return false
}

// Property is a struct that carries the current graph.Value.
type Property struct {
	value *protos.Value
}

// String returns the RAW value
func (p Property) String() string {
	return p.value.String()
}

// ToString returns the property as a string
func (p Property) ToString() string {
	str := p.value.GetStrVal()
	if len(str) > 0 {
		return str
	}
	return p.value.GetDefaultVal()
}

// ToBytes returns the property as []byte
func (p Property) ToBytes() []byte {
	return p.value.GetBytesVal()
}

// ToInt returns the property as an int64
func (p Property) ToInt() int64 {
	return p.value.GetIntVal()
}

// ToBool returns the property as a bool
func (p Property) ToBool() bool {
	return p.value.GetBoolVal()
}

// ToFloat returns the property as a float64
func (p Property) ToFloat() float64 {
	return p.value.GetDoubleVal()
}

// ToGeo returns the property as a geom.T
func (p Property) ToGeo() geom.T {
	t, _ := wkb.Unmarshal(p.value.GetGeoVal())
	return t
}

// ToDateTime returns the property as a time.Time
func (p Property) ToDateTime() time.Time {
	var t time.Time
	t.UnmarshalBinary(p.value.GetDatetimeVal())
	return t
}

// ToPassword returns the property as a string
func (p Property) ToPassword() string {
	return p.value.GetPasswordVal()
}

// ToUid returns the property as a uint64
func (p Property) ToUid() uint64 {
	return p.value.GetUidVal()
}

// IsNil returns true if the property is not available in the response.
func (p Property) IsNil() bool {
	return p.value == nil
}
<|endoftext|>


<commit_before>package model

import (
	"fmt"
)

func createPlayers() (p1, p2, pn *Player, err error) {
	p1, err = NewPlayer("player1")
	if err != nil {
		err = fmt.Errorf("Error creating p1: %v", err)
		return
	}
	p2, err = NewPlayer("player2")
	if err != nil {
		err = fmt.Errorf("Error creating p2: %v", err)
		return
	}
	pn, err = NewPlayer("neutral")
	if err != nil {
		err = fmt.Errorf("Error creating pn: %v", err)
		return
	}
	return
}

func createIslands(p1, p2, pn *Player) ([]*Island, error) {
	islandData := []struct {
		Pos      Coordinate
		Size     IslandSize
		Strength int
		Player   *Player
	}{
		{Coordinate{0, 0}, IslandSizeMedium, 10, p1},
		{Coordinate{6, 6}, IslandSizeMedium, 10, p2},
		{Coordinate{4, 4}, IslandSizeMedium, 10, pn},
		{Coordinate{6, 2}, IslandSizeMedium, 10, pn},
		{Coordinate{2, 6}, IslandSizeMedium, 10, pn},
		{Coordinate{0, 3}, IslandSizeMedium, 10, pn},
		{Coordinate{3, 0}, IslandSizeMedium, 10, pn},
	}

	islands := make([]*Island, 0)
	for _, data := range islandData {
		island, err := NewIsland(data.Pos, data.Size, data.Strength, data.Player)
		if err != nil {
			return nil, fmt.Errorf("Error creating island (data: %v): %v", data, err)
		}
		islands = append(islands, island)
	}
	return islands, nil
}

// TODO: this function should be moved somewhere and made configurable
func CreateBasicGame() (*Game, error) {
	p1, p2, pn, err := createPlayers()
	if err != nil {
		return nil, fmt.Errorf("Error creating players: %v", err)
	}

	islands, err := createIslands(p1, p2, pn)
	if err != nil {
		return nil, fmt.Errorf("Error creating islands: %v", err)
	}

	gameBuilder := NewGameBuilder(Coordinate{7, 7}, p1, p2, pn)
	for _, island := range islands {
		gameBuilder.AddIsland(island)
	}
	return gameBuilder.Build()
}
<commit_msg>Games are now created with some randomness<commit_after>package model

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

func createPlayers() (p1, p2, pn *Player, err error) {
	p1, err = NewPlayer("player1")
	if err != nil {
		err = fmt.Errorf("Error creating p1: %v", err)
		return
	}
	p2, err = NewPlayer("player2")
	if err != nil {
		err = fmt.Errorf("Error creating p2: %v", err)
		return
	}
	pn, err = NewPlayer("neutral")
	if err != nil {
		err = fmt.Errorf("Error creating pn: %v", err)
		return
	}
	return
}

func createIslands(p1, p2, pn *Player, size Coordinate, gameRand *rand.Rand) ([]*Island, error) {
	type islandData struct {
		Size     IslandSize
		Strength int
		Player   *Player
	}
	islandMap := make(map[Coordinate]islandData)

	islandSizes := []IslandSize{IslandSizeSmall, IslandSizeMedium, IslandSizeLarge}
	// Randomize the neutral islands
	for x := 0; x < size.X; x++ {
		for y := 0; y < size.Y; y ++ {
			if gameRand.Intn(100) >= 20 {
				continue
			}
			pos := Coordinate{x, y}
			size := islandSizes[gameRand.Intn(len(islandSizes))]
			strength := gameRand.Intn(22) + 4 // 4-25
			islandMap[pos] = islandData{size, strength, pn}
		}
	}

	// Set top left to player 1 island, bottom right to player 2 island
	islandMap[Coordinate{0,0}] = islandData{IslandSizeLarge, 20, p1}
	islandMap[Coordinate{size.X-1,size.Y-1}] = islandData{IslandSizeLarge, 20, p2}

	// Transform the map to a slice of islands
	islands := make([]*Island, 0)
	for pos, data := range islandMap {
		island, err := NewIsland(pos, data.Size, data.Strength, data.Player)
		if err != nil {
			return nil, fmt.Errorf("Error creating island (data: %v): %v", data, err)
		}
		islands = append(islands, island)
	}
	return islands, nil
}

func CreateBasicGame() (*Game, error) {
	seed := time.Now().UnixNano()
	gameRand := rand.New(rand.NewSource(seed))

	size := Coordinate{7, 7}

	p1, p2, pn, err := createPlayers()
	if err != nil {
		return nil, fmt.Errorf("Error creating players: %v", err)
	}

	islands, err := createIslands(p1, p2, pn, size, gameRand)
	if err != nil {
		return nil, fmt.Errorf("Error creating islands: %v", err)
	}

	gameBuilder := NewGameBuilder(size, p1, p2, pn)
	for _, island := range islands {
		gameBuilder.AddIsland(island)
	}
	return gameBuilder.Build()
}
<|endoftext|>


<commit_before>// +build !js

package webrtc

import (
	"testing"
	"time"

	"github.com/pion/transport/test"
	"github.com/stretchr/testify/assert"
)

func TestPeerConnection_Close(t *testing.T) {
	// Limit runtime in case of deadlocks
	lim := test.TimeOut(time.Second * 20)
	defer lim.Stop()

	report := test.CheckRoutines(t)
	defer report()

	pcOffer, pcAnswer, err := newPair()
	if err != nil {
		t.Fatal(err)
	}

	awaitSetup := make(chan struct{})
	pcAnswer.OnDataChannel(func(d *DataChannel) {
		// Make sure this is the data channel we were looking for. (Not the one
		// created in signalPair).
		if d.Label() != "data" {
			return
		}
		close(awaitSetup)
	})

	awaitICEClosed := make(chan struct{})
	pcAnswer.OnICEConnectionStateChange(func(i ICEConnectionState) {
		if i == ICEConnectionStateClosed {
			close(awaitICEClosed)
		}
	})

	_, err = pcOffer.CreateDataChannel("data", nil)
	if err != nil {
		t.Fatal(err)
	}

	err = signalPair(pcOffer, pcAnswer)
	if err != nil {
		t.Fatal(err)
	}

	<-awaitSetup

	closePairNow(t, pcOffer, pcAnswer)

	<-awaitICEClosed
}

// Assert that a PeerConnection that is shutdown before ICE starts doesn't leak
func TestPeerConnection_Close_PreICE(t *testing.T) {
	// Limit runtime in case of deadlocks
	lim := test.TimeOut(time.Second * 30)
	defer lim.Stop()

	report := test.CheckRoutines(t)
	defer report()

	pcOffer, pcAnswer, err := newPair()
	if err != nil {
		t.Fatal(err)
	}

	_, err = pcOffer.CreateDataChannel("test-channel", nil)
	if err != nil {
		t.Fatal(err)
	}

	answer, err := pcOffer.CreateOffer(nil)
	if err != nil {
		t.Fatal(err)
	}

	assert.NoError(t, pcOffer.Close())

	if err = pcAnswer.SetRemoteDescription(answer); err != nil {
		t.Fatal(err)
	}

	for {
		if pcAnswer.iceTransport.State() == ICETransportStateChecking {
			break
		}
		time.Sleep(time.Second)
	}

	assert.NoError(t, pcAnswer.Close())

	// Assert that ICETransport is shutdown, test timeout will prevent deadlock
	for {
		if pcAnswer.iceTransport.State() == ICETransportStateClosed {
			time.Sleep(time.Second * 3)
			return
		}

		time.Sleep(time.Second)
	}
}

func TestPeerConnection_Close_DuringICE(t *testing.T) {
	// Limit runtime in case of deadlocks
	lim := test.TimeOut(time.Second * 30)
	defer lim.Stop()

	report := test.CheckRoutines(t)
	defer report()

	pcOffer, pcAnswer, err := newPair()
	if err != nil {
		t.Fatal(err)
	}
	closedOffer := make(chan struct{})
	closedAnswer := make(chan struct{})
	pcAnswer.OnICEConnectionStateChange(func(iceState ICEConnectionState) {
		if iceState == ICEConnectionStateConnected {
			go func() {
				assert.NoError(t, pcAnswer.Close())
				close(closedAnswer)

				assert.NoError(t, pcOffer.Close())
				close(closedOffer)
			}()
		}
	})

	_, err = pcOffer.CreateDataChannel("test-channel", nil)
	if err != nil {
		t.Fatal(err)
	}

	offer, err := pcOffer.CreateOffer(nil)
	if err != nil {
		t.Fatal(err)
	}

	offerGatheringComplete := GatheringCompletePromise(pcOffer)
	if err = pcOffer.SetLocalDescription(offer); err != nil {
		t.Fatal(err)
	}
	<-offerGatheringComplete

	if err = pcAnswer.SetRemoteDescription(*pcOffer.LocalDescription()); err != nil {
		t.Fatal(err)
	}

	answer, err := pcAnswer.CreateAnswer(nil)
	if err != nil {
		t.Fatal(err)
	}
	answerGatheringComplete := GatheringCompletePromise(pcAnswer)
	if err = pcAnswer.SetLocalDescription(answer); err != nil {
		t.Fatal(err)
	}
	<-answerGatheringComplete
	if err = pcOffer.SetRemoteDescription(*pcAnswer.LocalDescription()); err != nil {
		t.Fatal(err)
	}

	select {
	case <-closedAnswer:
	case <-time.After(5 * time.Second):
		t.Error("pcAnswer.Close() Timeout")
	}
	select {
	case <-closedOffer:
	case <-time.After(5 * time.Second):
		t.Error("pcOffer.Close() Timeout")
	}
}
<commit_msg>Reduce PeerConnection_Close_PreICE<commit_after>// +build !js

package webrtc

import (
	"testing"
	"time"

	"github.com/pion/transport/test"
	"github.com/stretchr/testify/assert"
)

func TestPeerConnection_Close(t *testing.T) {
	// Limit runtime in case of deadlocks
	lim := test.TimeOut(time.Second * 20)
	defer lim.Stop()

	report := test.CheckRoutines(t)
	defer report()

	pcOffer, pcAnswer, err := newPair()
	if err != nil {
		t.Fatal(err)
	}

	awaitSetup := make(chan struct{})
	pcAnswer.OnDataChannel(func(d *DataChannel) {
		// Make sure this is the data channel we were looking for. (Not the one
		// created in signalPair).
		if d.Label() != "data" {
			return
		}
		close(awaitSetup)
	})

	awaitICEClosed := make(chan struct{})
	pcAnswer.OnICEConnectionStateChange(func(i ICEConnectionState) {
		if i == ICEConnectionStateClosed {
			close(awaitICEClosed)
		}
	})

	_, err = pcOffer.CreateDataChannel("data", nil)
	if err != nil {
		t.Fatal(err)
	}

	err = signalPair(pcOffer, pcAnswer)
	if err != nil {
		t.Fatal(err)
	}

	<-awaitSetup

	closePairNow(t, pcOffer, pcAnswer)

	<-awaitICEClosed
}

// Assert that a PeerConnection that is shutdown before ICE starts doesn't leak
func TestPeerConnection_Close_PreICE(t *testing.T) {
	// Limit runtime in case of deadlocks
	lim := test.TimeOut(time.Second * 30)
	defer lim.Stop()

	report := test.CheckRoutines(t)
	defer report()

	pcOffer, pcAnswer, err := newPair()
	if err != nil {
		t.Fatal(err)
	}

	_, err = pcOffer.CreateDataChannel("test-channel", nil)
	if err != nil {
		t.Fatal(err)
	}

	answer, err := pcOffer.CreateOffer(nil)
	if err != nil {
		t.Fatal(err)
	}

	assert.NoError(t, pcOffer.Close())

	if err = pcAnswer.SetRemoteDescription(answer); err != nil {
		t.Fatal(err)
	}

	for {
		if pcAnswer.iceTransport.State() == ICETransportStateChecking {
			break
		}
		time.Sleep(time.Second / 4)
	}

	assert.NoError(t, pcAnswer.Close())

	// Assert that ICETransport is shutdown, test timeout will prevent deadlock
	for {
		if pcAnswer.iceTransport.State() == ICETransportStateClosed {
			return
		}
		time.Sleep(time.Second / 4)
	}
}

func TestPeerConnection_Close_DuringICE(t *testing.T) {
	// Limit runtime in case of deadlocks
	lim := test.TimeOut(time.Second * 30)
	defer lim.Stop()

	report := test.CheckRoutines(t)
	defer report()

	pcOffer, pcAnswer, err := newPair()
	if err != nil {
		t.Fatal(err)
	}
	closedOffer := make(chan struct{})
	closedAnswer := make(chan struct{})
	pcAnswer.OnICEConnectionStateChange(func(iceState ICEConnectionState) {
		if iceState == ICEConnectionStateConnected {
			go func() {
				assert.NoError(t, pcAnswer.Close())
				close(closedAnswer)

				assert.NoError(t, pcOffer.Close())
				close(closedOffer)
			}()
		}
	})

	_, err = pcOffer.CreateDataChannel("test-channel", nil)
	if err != nil {
		t.Fatal(err)
	}

	offer, err := pcOffer.CreateOffer(nil)
	if err != nil {
		t.Fatal(err)
	}

	offerGatheringComplete := GatheringCompletePromise(pcOffer)
	if err = pcOffer.SetLocalDescription(offer); err != nil {
		t.Fatal(err)
	}
	<-offerGatheringComplete

	if err = pcAnswer.SetRemoteDescription(*pcOffer.LocalDescription()); err != nil {
		t.Fatal(err)
	}

	answer, err := pcAnswer.CreateAnswer(nil)
	if err != nil {
		t.Fatal(err)
	}
	answerGatheringComplete := GatheringCompletePromise(pcAnswer)
	if err = pcAnswer.SetLocalDescription(answer); err != nil {
		t.Fatal(err)
	}
	<-answerGatheringComplete
	if err = pcOffer.SetRemoteDescription(*pcAnswer.LocalDescription()); err != nil {
		t.Fatal(err)
	}

	select {
	case <-closedAnswer:
	case <-time.After(5 * time.Second):
		t.Error("pcAnswer.Close() Timeout")
	}
	select {
	case <-closedOffer:
	case <-time.After(5 * time.Second):
		t.Error("pcOffer.Close() Timeout")
	}
}
<|endoftext|>


<commit_before>// Copyright 2015 PingCAP, 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package optimizer

import (
	"github.com/pingcap/tidb/ast"
	"github.com/pingcap/tidb/context"
	"github.com/pingcap/tidb/mysql"
	"github.com/pingcap/tidb/optimizer/evaluator"
	"github.com/pingcap/tidb/parser/opcode"
	"github.com/pingcap/tidb/util/types"
)

// InferType infers result type for ast.ExprNode.
func InferType(node ast.Node) error {
	var inferrer typeInferrer
	node.Accept(&inferrer)
	return inferrer.err
}

// preEvaluate evaluates preEvaluable expression and rewrites constant expression to value expression.
func preEvaluate(ctx context.Context, node ast.Node) error {
	pe := preEvaluator{ctx: ctx}
	node.Accept(&pe)
	return pe.err
}

type typeInferrer struct {
	err error
}

func (v *typeInferrer) Enter(in ast.Node) (out ast.Node, skipChildren bool) {
	return in, false
}

func (v *typeInferrer) Leave(in ast.Node) (out ast.Node, ok bool) {
	switch x := in.(type) {
	case *ast.ColumnNameExpr:
		x.SetType(&x.Refer.Column.FieldType)
	case *ast.FuncCastExpr:
		x.SetType(x.Tp)
	case *ast.SelectStmt:
		v.selectStmt(x)
	case *ast.ParamMarkerExpr:
		x.SetType(types.DefaultTypeForValue(x.GetValue()))
	case *ast.BinaryOperationExpr:
		v.binaryOperation(x)
	case *ast.UnaryOperationExpr:
		v.unaryOperation(x)
	case *ast.BetweenExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.CompareSubqueryExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.ExistsSubqueryExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.PatternInExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.PatternLikeExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.PatternRegexpExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.IsNullExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.IsTruthExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.ParenthesesExpr:
		x.SetType(x.Expr.GetType())
		// TODO: handle all expression types.
	}
	return in, true
}

func (v *typeInferrer) selectStmt(x *ast.SelectStmt) {
	rf := x.GetResultFields()
	for _, val := range rf {
		if val.Column.ID == 0 && val.Expr.GetType() != nil {
			val.Column.FieldType = *(val.Expr.GetType())
		}
	}
}

func (v *typeInferrer) binaryOperation(x *ast.BinaryOperationExpr) {
	switch x.Op {
	case opcode.AndAnd, opcode.OrOr, opcode.LogicXor:
		x.Type = types.NewFieldType(mysql.TypeLonglong)
	case opcode.LT, opcode.LE, opcode.GE, opcode.GT, opcode.EQ, opcode.NE, opcode.NullEQ:
		x.Type = types.NewFieldType(mysql.TypeLonglong)
	case opcode.RightShift, opcode.LeftShift, opcode.And, opcode.Or, opcode.Xor:
		x.Type = types.NewFieldType(mysql.TypeLonglong)
		x.Type.Flag |= mysql.UnsignedFlag
	case opcode.IntDiv:
		x.Type = types.NewFieldType(mysql.TypeLonglong)
	case opcode.Plus, opcode.Minus, opcode.Mul, opcode.Mod:
		if x.L.GetType() != nil && x.R.GetType() != nil {
			xTp := mergeArithType(x.L.GetType().Tp, x.R.GetType().Tp)
			x.Type = types.NewFieldType(xTp)
			leftUnsigned := x.L.GetType().Flag & mysql.UnsignedFlag
			rightUnsigned := x.R.GetType().Flag & mysql.UnsignedFlag
			// If both operand is unsigned, result is unsigned.
			x.Type.Flag |= (leftUnsigned & rightUnsigned)
		}
	case opcode.Div:
		if x.L.GetType() != nil && x.R.GetType() != nil {
			xTp := mergeArithType(x.L.GetType().Tp, x.R.GetType().Tp)
			if xTp == mysql.TypeLonglong {
				xTp = mysql.TypeDecimal
			}
			x.Type = types.NewFieldType(xTp)
		}
	}
}

func mergeArithType(a, b byte) byte {
	switch a {
	case mysql.TypeString, mysql.TypeVarchar, mysql.TypeVarString, mysql.TypeDouble:
		return mysql.TypeDouble
	}
	switch b {
	case mysql.TypeString, mysql.TypeVarchar, mysql.TypeVarString, mysql.TypeDouble, mysql.TypeFloat:
		return mysql.TypeDouble
	}
	if a == mysql.TypeNewDecimal || b == mysql.TypeNewDecimal {
		return mysql.TypeNewDecimal
	}
	return mysql.TypeLonglong
}

func (v *typeInferrer) unaryOperation(x *ast.UnaryOperationExpr) {
	switch x.Op {
	case opcode.Not:
		x.Type = types.NewFieldType(mysql.TypeLonglong)
	case opcode.BitNeg:
		x.Type = types.NewFieldType(mysql.TypeLonglong)
		x.Type.Flag |= mysql.UnsignedFlag
	case opcode.Plus:
		x.Type = x.V.GetType()
	case opcode.Minus:
		x.Type = types.NewFieldType(mysql.TypeLonglong)
		if x.V.GetType() != nil {
			switch x.V.GetType().Tp {
			case mysql.TypeString, mysql.TypeVarchar, mysql.TypeVarString, mysql.TypeDouble, mysql.TypeFloat:
				x.Type.Tp = mysql.TypeDouble
			case mysql.TypeNewDecimal:
				x.Type.Tp = mysql.TypeNewDecimal
			}
		}
	}
}

type preEvaluator struct {
	ctx context.Context
	err error
}

func (r *preEvaluator) Enter(in ast.Node) (ast.Node, bool) {
	return in, false
}

func (r *preEvaluator) Leave(in ast.Node) (ast.Node, bool) {
	if expr, ok := in.(ast.ExprNode); ok {
		if _, ok = expr.(*ast.ValueExpr); ok {
			return in, true
		} else if ast.IsPreEvaluable(expr) {
			val, err := evaluator.Eval(r.ctx, expr)
			if err != nil {
				r.err = err
				return in, false
			}
			if ast.IsConstant(expr) {
				// The expression is constant, rewrite the expression to value expression.
				valExpr := &ast.ValueExpr{}
				valExpr.SetText(expr.Text())
				valExpr.SetType(expr.GetType())
				valExpr.SetValue(val)
				return valExpr, true
			}
			expr.SetValue(val)
		}
	}
	return in, true
}
<commit_msg>optmizer: address comment<commit_after>// Copyright 2015 PingCAP, 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package optimizer

import (
	"github.com/pingcap/tidb/ast"
	"github.com/pingcap/tidb/context"
	"github.com/pingcap/tidb/mysql"
	"github.com/pingcap/tidb/optimizer/evaluator"
	"github.com/pingcap/tidb/parser/opcode"
	"github.com/pingcap/tidb/util/types"
)

// InferType infers result type for ast.ExprNode.
func InferType(node ast.Node) error {
	var inferrer typeInferrer
	node.Accept(&inferrer)
	return inferrer.err
}

// preEvaluate evaluates preEvaluable expression and rewrites constant expression to value expression.
func preEvaluate(ctx context.Context, node ast.Node) error {
	pe := preEvaluator{ctx: ctx}
	node.Accept(&pe)
	return pe.err
}

type typeInferrer struct {
	err error
}

func (v *typeInferrer) Enter(in ast.Node) (out ast.Node, skipChildren bool) {
	return in, false
}

func (v *typeInferrer) Leave(in ast.Node) (out ast.Node, ok bool) {
	switch x := in.(type) {
	case *ast.ColumnNameExpr:
		x.SetType(&x.Refer.Column.FieldType)
	case *ast.FuncCastExpr:
		x.SetType(x.Tp)
	case *ast.SelectStmt:
		v.selectStmt(x)
	case *ast.ParamMarkerExpr:
		x.SetType(types.DefaultTypeForValue(x.GetValue()))
	case *ast.BinaryOperationExpr:
		v.binaryOperation(x)
	case *ast.UnaryOperationExpr:
		v.unaryOperation(x)
	case *ast.BetweenExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.CompareSubqueryExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.ExistsSubqueryExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.PatternInExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.PatternLikeExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.PatternRegexpExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.IsNullExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.IsTruthExpr:
		x.SetType(types.NewFieldType(mysql.TypeLonglong))
	case *ast.ParenthesesExpr:
		x.SetType(x.Expr.GetType())
		// TODO: handle all expression types.
	}
	return in, true
}

func (v *typeInferrer) selectStmt(x *ast.SelectStmt) {
	rf := x.GetResultFields()
	for _, val := range rf {
		if val.Column.ID == 0 && val.Expr.GetType() != nil {
			val.Column.FieldType = *(val.Expr.GetType())
		}
	}
}

func (v *typeInferrer) binaryOperation(x *ast.BinaryOperationExpr) {
	switch x.Op {
	case opcode.AndAnd, opcode.OrOr, opcode.LogicXor:
		x.Type = types.NewFieldType(mysql.TypeLonglong)
	case opcode.LT, opcode.LE, opcode.GE, opcode.GT, opcode.EQ, opcode.NE, opcode.NullEQ:
		x.Type = types.NewFieldType(mysql.TypeLonglong)
	case opcode.RightShift, opcode.LeftShift, opcode.And, opcode.Or, opcode.Xor:
		x.Type = types.NewFieldType(mysql.TypeLonglong)
		x.Type.Flag |= mysql.UnsignedFlag
	case opcode.IntDiv:
		x.Type = types.NewFieldType(mysql.TypeLonglong)
	case opcode.Plus, opcode.Minus, opcode.Mul, opcode.Mod:
		if x.L.GetType() != nil && x.R.GetType() != nil {
			xTp := mergeArithType(x.L.GetType().Tp, x.R.GetType().Tp)
			x.Type = types.NewFieldType(xTp)
			leftUnsigned := x.L.GetType().Flag & mysql.UnsignedFlag
			rightUnsigned := x.R.GetType().Flag & mysql.UnsignedFlag
			// If both operand is unsigned, result is unsigned.
			x.Type.Flag |= (leftUnsigned & rightUnsigned)
		}
	case opcode.Div:
		if x.L.GetType() != nil && x.R.GetType() != nil {
			xTp := mergeArithType(x.L.GetType().Tp, x.R.GetType().Tp)
			if xTp == mysql.TypeLonglong {
				xTp = mysql.TypeDecimal
			}
			x.Type = types.NewFieldType(xTp)
		}
	}
}

func mergeArithType(a, b byte) byte {
	switch a {
	case mysql.TypeString, mysql.TypeVarchar, mysql.TypeVarString, mysql.TypeDouble, mysql.TypeFloat:
		return mysql.TypeDouble
	}
	switch b {
	case mysql.TypeString, mysql.TypeVarchar, mysql.TypeVarString, mysql.TypeDouble, mysql.TypeFloat:
		return mysql.TypeDouble
	}
	if a == mysql.TypeNewDecimal || b == mysql.TypeNewDecimal {
		return mysql.TypeNewDecimal
	}
	return mysql.TypeLonglong
}

func (v *typeInferrer) unaryOperation(x *ast.UnaryOperationExpr) {
	switch x.Op {
	case opcode.Not:
		x.Type = types.NewFieldType(mysql.TypeLonglong)
	case opcode.BitNeg:
		x.Type = types.NewFieldType(mysql.TypeLonglong)
		x.Type.Flag |= mysql.UnsignedFlag
	case opcode.Plus:
		x.Type = x.V.GetType()
	case opcode.Minus:
		x.Type = types.NewFieldType(mysql.TypeLonglong)
		if x.V.GetType() != nil {
			switch x.V.GetType().Tp {
			case mysql.TypeString, mysql.TypeVarchar, mysql.TypeVarString, mysql.TypeDouble, mysql.TypeFloat:
				x.Type.Tp = mysql.TypeDouble
			case mysql.TypeNewDecimal:
				x.Type.Tp = mysql.TypeNewDecimal
			}
		}
	}
}

type preEvaluator struct {
	ctx context.Context
	err error
}

func (r *preEvaluator) Enter(in ast.Node) (ast.Node, bool) {
	return in, false
}

func (r *preEvaluator) Leave(in ast.Node) (ast.Node, bool) {
	if expr, ok := in.(ast.ExprNode); ok {
		if _, ok = expr.(*ast.ValueExpr); ok {
			return in, true
		} else if ast.IsPreEvaluable(expr) {
			val, err := evaluator.Eval(r.ctx, expr)
			if err != nil {
				r.err = err
				return in, false
			}
			if ast.IsConstant(expr) {
				// The expression is constant, rewrite the expression to value expression.
				valExpr := &ast.ValueExpr{}
				valExpr.SetText(expr.Text())
				valExpr.SetType(expr.GetType())
				valExpr.SetValue(val)
				return valExpr, true
			}
			expr.SetValue(val)
		}
	}
	return in, true
}
<|endoftext|>


<commit_before>/*
   Hockeypuck - OpenPGP key server
   Copyright (C) 2012-2014  Casey Marshall

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published by
   the Free Software Foundation, version 3.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package openpgp

import (
	"crypto/md5"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"hash"
	"io"
	"os"
	"sort"

	"golang.org/x/crypto/openpgp"
	"golang.org/x/crypto/openpgp/armor"
	"golang.org/x/crypto/openpgp/errors"
	"golang.org/x/crypto/openpgp/packet"
	"gopkg.in/errgo.v1"

	log "hockeypuck/logrus"
)

var ErrMissingSignature = fmt.Errorf("Key material missing an expected signature")

func WritePackets(w io.Writer, key *PrimaryKey) error {
	for _, node := range key.contents() {
		op, err := newOpaquePacket(node.packet().Packet)
		if err != nil {
			return errgo.Mask(err)
		}
		err = op.Serialize(w)
		if err != nil {
			return errgo.Mask(err)
		}
	}
	return nil
}

func WriteArmoredPackets(w io.Writer, roots []*PrimaryKey) error {
	armw, err := armor.Encode(w, openpgp.PublicKeyType, nil)
	defer armw.Close()
	if err != nil {
		return errgo.Mask(err)
	}
	for _, node := range roots {
		err = WritePackets(armw, node)
		if err != nil {
			return errgo.Mask(err)
		}
	}
	return nil
}

type OpaqueKeyring struct {
	Packets      []*packet.OpaquePacket
	RFingerprint string
	Md5          string
	Sha256       string
	Error        error
	Position     int64
}

func (okr *OpaqueKeyring) setPosition(r io.Reader) {
	f, ok := r.(*os.File)
	if ok {
		pos, err := f.Seek(0, 1)
		if err == nil {
			okr.Position = pos
			return
		}
	}
	okr.Position = -1
}

func (ok *OpaqueKeyring) Parse() (*PrimaryKey, error) {
	var err error
	var pubkey *PrimaryKey
	var signablePacket signable
	for _, opkt := range ok.Packets {
		var badPacket *packet.OpaquePacket
		if opkt.Tag == 6 { //packet.PacketTypePublicKey:
			if pubkey != nil {
				return nil, errgo.Newf("multiple public keys in keyring")
			}
			pubkey, err = ParsePrimaryKey(opkt)
			if err != nil {
				return nil, errgo.Notef(err, "invalid public key packet type")
			}
			signablePacket = pubkey
		} else if pubkey != nil {
			switch opkt.Tag {
			case 14: //packet.PacketTypePublicSubKey:
				signablePacket = nil
				subkey, err := ParseSubKey(opkt)
				if err != nil {
					log.Debugf("unreadable subkey packet in key 0x%s: %v", err, pubkey.KeyID())
					badPacket = opkt
				} else {
					pubkey.SubKeys = append(pubkey.SubKeys, subkey)
					signablePacket = subkey
				}
			case 13: //packet.PacketTypeUserId:
				signablePacket = nil
				uid, err := ParseUserID(opkt, pubkey.UUID)
				if err != nil {
					log.Debugf("unreadable user id packet in key 0x%s: %v", err, pubkey.KeyID())
					badPacket = opkt
				} else {
					pubkey.UserIDs = append(pubkey.UserIDs, uid)
					signablePacket = uid
				}
			case 17: //packet.PacketTypeUserAttribute:
				signablePacket = nil
				uat, err := ParseUserAttribute(opkt, pubkey.UUID)
				if err != nil {
					log.Debugf("unreadable user attribute packet in key 0x%s: %v", err, pubkey.KeyID())
					badPacket = opkt
				} else {
					pubkey.UserAttributes = append(pubkey.UserAttributes, uat)
					signablePacket = uat
				}
			case 2: //packet.PacketTypeSignature:
				if signablePacket == nil {
					log.Debugf("signature out of context")
					badPacket = opkt
				} else {
					sig, err := ParseSignature(opkt, pubkey.UUID, signablePacket.uuid())
					if err != nil {
						log.Debugf("unreadable signature packet in key 0x%s: %v", err, pubkey.KeyID())
						badPacket = opkt
					} else {
						signablePacket.appendSignature(sig)
					}
				}
			default:
				badPacket = opkt
			}

			if badPacket != nil {
				var badParent string
				if signablePacket != nil {
					badParent = signablePacket.uuid()
				} else {
					badParent = pubkey.uuid()
				}
				other, err := ParseOther(badPacket, badParent)
				if err != nil {
					return nil, errgo.Mask(err)
				}
				_, isStructuralError := badPacket.Reason.(errors.StructuralError)
				if badPacket.Reason == io.ErrUnexpectedEOF || isStructuralError {
					log.Debugf("malformed packet in key 0x%s: %v", pubkey.KeyID(), badPacket.Reason)
					other.Malformed = true
				}
				pubkey.Others = append(pubkey.Others, other)
			}
		}
	}
	if pubkey == nil {
		return nil, errgo.New("primary public key not found")
	}
	pubkey.MD5, err = SksDigest(pubkey, md5.New())
	if err != nil {
		return nil, err
	}
	return pubkey, nil
}

type OpaqueKeyringChan chan *OpaqueKeyring

func ReadOpaqueKeyrings(r io.Reader) OpaqueKeyringChan {
	c := make(OpaqueKeyringChan)
	or := packet.NewOpaqueReader(r)
	go func() {
		defer close(c)
		var op *packet.OpaquePacket
		var err error
		var current *OpaqueKeyring
		for op, err = or.Next(); err == nil; op, err = or.Next() {
			switch op.Tag {
			case 6: //packet.PacketTypePublicKey:
				if current != nil {
					c <- current
					current = nil
				}
				current = &OpaqueKeyring{}
				current.setPosition(r)
				fallthrough
			case 2, 13, 14, 17:
				//packet.PacketTypeUserId,
				//packet.PacketTypeUserAttribute,
				//packet.PacketTypePublicSubKey,
				//packet.PacketTypeSignature
				if current != nil {
					current.Packets = append(current.Packets, op)
				}
			}
		}
		if err == io.EOF && current != nil {
			c <- current
		} else if err != nil {
			if current == nil {
				current = &OpaqueKeyring{}
			}
			current.Error = errgo.Mask(err)
			c <- current
		}
	}()
	return c
}

// SksDigest calculates a cumulative message digest on all OpenPGP packets for
// a given primary public key, using the same ordering as SKS, the
// Synchronizing Key Server. Use MD5 for matching digest values with SKS.
func SksDigest(key *PrimaryKey, h hash.Hash) (string, error) {
	var fail string
	var packets opaquePacketSlice
	for _, node := range key.contents() {
		op, err := newOpaquePacket(node.packet().Packet)
		if err != nil {
			return fail, errgo.Mask(err)
		}
		packets = append(packets, op)
	}
	if len(packets) == 0 {
		return fail, errgo.New("no packets found")
	}
	return sksDigestOpaque(packets, h), nil
}

func sksDigestOpaque(packets []*packet.OpaquePacket, h hash.Hash) string {
	sort.Sort(opaquePacketSlice(packets))
	for _, opkt := range packets {
		binary.Write(h, binary.BigEndian, int32(opkt.Tag))
		binary.Write(h, binary.BigEndian, int32(len(opkt.Contents)))
		h.Write(opkt.Contents)
	}
	return hex.EncodeToString(h.Sum(nil))
}

type ReadKeyResult struct {
	*PrimaryKey
	Error error
}

type PrimaryKeyChan chan *ReadKeyResult

func (c PrimaryKeyChan) MustParse() []*PrimaryKey {
	var result []*PrimaryKey
	for readKey := range c {
		if readKey.Error != nil {
			panic(readKey.Error)
		}
		result = append(result, readKey.PrimaryKey)
	}
	return result
}

// ReadKeys reads public key material from input and sends them on a channel.
// Caller must receive all keys until the channel is closed.
func ReadKeys(r io.Reader) PrimaryKeyChan {
	c := make(PrimaryKeyChan)
	go func() {
		defer close(c)
		for keyRead := range readKeys(r) {
			c <- keyRead
		}
		if closer, ok := r.(io.Closer); ok {
			closer.Close()
		}
	}()
	return c
}

func readKeys(r io.Reader) PrimaryKeyChan {
	c := make(PrimaryKeyChan)
	go func() {
		defer close(c)
		for opkr := range ReadOpaqueKeyrings(r) {
			pubkey, err := opkr.Parse()
			if err != nil {
				c <- &ReadKeyResult{Error: err}
			} else {
				c <- &ReadKeyResult{PrimaryKey: pubkey}
			}
		}
	}()
	return c
}

func ReadArmorKeys(r io.Reader) (PrimaryKeyChan, error) {
	block, err := armor.Decode(r)
	if err != nil {
		return nil, err
	}
	return ReadKeys(block.Body), nil
}

func MustReadArmorKeys(r io.Reader) PrimaryKeyChan {
	c, err := ReadArmorKeys(r)
	if err != nil {
		panic(err)
	}
	return c
}
<commit_msg>use correct argument order when logging parse errors<commit_after>/*
   Hockeypuck - OpenPGP key server
   Copyright (C) 2012-2014  Casey Marshall

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU Affero General Public License as published by
   the Free Software Foundation, version 3.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Affero General Public License for more details.

   You should have received a copy of the GNU Affero General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

package openpgp

import (
	"crypto/md5"
	"encoding/binary"
	"encoding/hex"
	"fmt"
	"hash"
	"io"
	"os"
	"sort"

	"golang.org/x/crypto/openpgp"
	"golang.org/x/crypto/openpgp/armor"
	"golang.org/x/crypto/openpgp/errors"
	"golang.org/x/crypto/openpgp/packet"
	"gopkg.in/errgo.v1"

	log "hockeypuck/logrus"
)

var ErrMissingSignature = fmt.Errorf("Key material missing an expected signature")

func WritePackets(w io.Writer, key *PrimaryKey) error {
	for _, node := range key.contents() {
		op, err := newOpaquePacket(node.packet().Packet)
		if err != nil {
			return errgo.Mask(err)
		}
		err = op.Serialize(w)
		if err != nil {
			return errgo.Mask(err)
		}
	}
	return nil
}

func WriteArmoredPackets(w io.Writer, roots []*PrimaryKey) error {
	armw, err := armor.Encode(w, openpgp.PublicKeyType, nil)
	defer armw.Close()
	if err != nil {
		return errgo.Mask(err)
	}
	for _, node := range roots {
		err = WritePackets(armw, node)
		if err != nil {
			return errgo.Mask(err)
		}
	}
	return nil
}

type OpaqueKeyring struct {
	Packets      []*packet.OpaquePacket
	RFingerprint string
	Md5          string
	Sha256       string
	Error        error
	Position     int64
}

func (okr *OpaqueKeyring) setPosition(r io.Reader) {
	f, ok := r.(*os.File)
	if ok {
		pos, err := f.Seek(0, 1)
		if err == nil {
			okr.Position = pos
			return
		}
	}
	okr.Position = -1
}

func (ok *OpaqueKeyring) Parse() (*PrimaryKey, error) {
	var err error
	var pubkey *PrimaryKey
	var signablePacket signable
	for _, opkt := range ok.Packets {
		var badPacket *packet.OpaquePacket
		if opkt.Tag == 6 { //packet.PacketTypePublicKey:
			if pubkey != nil {
				return nil, errgo.Newf("multiple public keys in keyring")
			}
			pubkey, err = ParsePrimaryKey(opkt)
			if err != nil {
				return nil, errgo.Notef(err, "invalid public key packet type")
			}
			signablePacket = pubkey
		} else if pubkey != nil {
			switch opkt.Tag {
			case 14: //packet.PacketTypePublicSubKey:
				signablePacket = nil
				subkey, err := ParseSubKey(opkt)
				if err != nil {
					log.Debugf("unreadable subkey packet in key 0x%s: %v", pubkey.KeyID(), err)
					badPacket = opkt
				} else {
					pubkey.SubKeys = append(pubkey.SubKeys, subkey)
					signablePacket = subkey
				}
			case 13: //packet.PacketTypeUserId:
				signablePacket = nil
				uid, err := ParseUserID(opkt, pubkey.UUID)
				if err != nil {
					log.Debugf("unreadable user id packet in key 0x%s: %v", pubkey.KeyID(), err)
					badPacket = opkt
				} else {
					pubkey.UserIDs = append(pubkey.UserIDs, uid)
					signablePacket = uid
				}
			case 17: //packet.PacketTypeUserAttribute:
				signablePacket = nil
				uat, err := ParseUserAttribute(opkt, pubkey.UUID)
				if err != nil {
					log.Debugf("unreadable user attribute packet in key 0x%s: %v", pubkey.KeyID(), err)
					badPacket = opkt
				} else {
					pubkey.UserAttributes = append(pubkey.UserAttributes, uat)
					signablePacket = uat
				}
			case 2: //packet.PacketTypeSignature:
				if signablePacket == nil {
					log.Debugf("signature out of context")
					badPacket = opkt
				} else {
					sig, err := ParseSignature(opkt, pubkey.UUID, signablePacket.uuid())
					if err != nil {
						log.Debugf("unreadable signature packet in key 0x%s: %v", pubkey.KeyID(), err)
						badPacket = opkt
					} else {
						signablePacket.appendSignature(sig)
					}
				}
			default:
				badPacket = opkt
			}

			if badPacket != nil {
				var badParent string
				if signablePacket != nil {
					badParent = signablePacket.uuid()
				} else {
					badParent = pubkey.uuid()
				}
				other, err := ParseOther(badPacket, badParent)
				if err != nil {
					return nil, errgo.Mask(err)
				}
				_, isStructuralError := badPacket.Reason.(errors.StructuralError)
				if badPacket.Reason == io.ErrUnexpectedEOF || isStructuralError {
					log.Debugf("malformed packet in key 0x%s: %v", pubkey.KeyID(), badPacket.Reason)
					other.Malformed = true
				}
				pubkey.Others = append(pubkey.Others, other)
			}
		}
	}
	if pubkey == nil {
		return nil, errgo.New("primary public key not found")
	}
	pubkey.MD5, err = SksDigest(pubkey, md5.New())
	if err != nil {
		return nil, err
	}
	return pubkey, nil
}

type OpaqueKeyringChan chan *OpaqueKeyring

func ReadOpaqueKeyrings(r io.Reader) OpaqueKeyringChan {
	c := make(OpaqueKeyringChan)
	or := packet.NewOpaqueReader(r)
	go func() {
		defer close(c)
		var op *packet.OpaquePacket
		var err error
		var current *OpaqueKeyring
		for op, err = or.Next(); err == nil; op, err = or.Next() {
			switch op.Tag {
			case 6: //packet.PacketTypePublicKey:
				if current != nil {
					c <- current
					current = nil
				}
				current = &OpaqueKeyring{}
				current.setPosition(r)
				fallthrough
			case 2, 13, 14, 17:
				//packet.PacketTypeUserId,
				//packet.PacketTypeUserAttribute,
				//packet.PacketTypePublicSubKey,
				//packet.PacketTypeSignature
				if current != nil {
					current.Packets = append(current.Packets, op)
				}
			}
		}
		if err == io.EOF && current != nil {
			c <- current
		} else if err != nil {
			if current == nil {
				current = &OpaqueKeyring{}
			}
			current.Error = errgo.Mask(err)
			c <- current
		}
	}()
	return c
}

// SksDigest calculates a cumulative message digest on all OpenPGP packets for
// a given primary public key, using the same ordering as SKS, the
// Synchronizing Key Server. Use MD5 for matching digest values with SKS.
func SksDigest(key *PrimaryKey, h hash.Hash) (string, error) {
	var fail string
	var packets opaquePacketSlice
	for _, node := range key.contents() {
		op, err := newOpaquePacket(node.packet().Packet)
		if err != nil {
			return fail, errgo.Mask(err)
		}
		packets = append(packets, op)
	}
	if len(packets) == 0 {
		return fail, errgo.New("no packets found")
	}
	return sksDigestOpaque(packets, h), nil
}

func sksDigestOpaque(packets []*packet.OpaquePacket, h hash.Hash) string {
	sort.Sort(opaquePacketSlice(packets))
	for _, opkt := range packets {
		binary.Write(h, binary.BigEndian, int32(opkt.Tag))
		binary.Write(h, binary.BigEndian, int32(len(opkt.Contents)))
		h.Write(opkt.Contents)
	}
	return hex.EncodeToString(h.Sum(nil))
}

type ReadKeyResult struct {
	*PrimaryKey
	Error error
}

type PrimaryKeyChan chan *ReadKeyResult

func (c PrimaryKeyChan) MustParse() []*PrimaryKey {
	var result []*PrimaryKey
	for readKey := range c {
		if readKey.Error != nil {
			panic(readKey.Error)
		}
		result = append(result, readKey.PrimaryKey)
	}
	return result
}

// ReadKeys reads public key material from input and sends them on a channel.
// Caller must receive all keys until the channel is closed.
func ReadKeys(r io.Reader) PrimaryKeyChan {
	c := make(PrimaryKeyChan)
	go func() {
		defer close(c)
		for keyRead := range readKeys(r) {
			c <- keyRead
		}
		if closer, ok := r.(io.Closer); ok {
			closer.Close()
		}
	}()
	return c
}

func readKeys(r io.Reader) PrimaryKeyChan {
	c := make(PrimaryKeyChan)
	go func() {
		defer close(c)
		for opkr := range ReadOpaqueKeyrings(r) {
			pubkey, err := opkr.Parse()
			if err != nil {
				c <- &ReadKeyResult{Error: err}
			} else {
				c <- &ReadKeyResult{PrimaryKey: pubkey}
			}
		}
	}()
	return c
}

func ReadArmorKeys(r io.Reader) (PrimaryKeyChan, error) {
	block, err := armor.Decode(r)
	if err != nil {
		return nil, err
	}
	return ReadKeys(block.Body), nil
}

func MustReadArmorKeys(r io.Reader) PrimaryKeyChan {
	c, err := ReadArmorKeys(r)
	if err != nil {
		panic(err)
	}
	return c
}
<|endoftext|>


<commit_before>/*
** Haaf's Game Engine 1.8
** Copyright (C) 2003-2007, Relish Games
** hge.relishgames.com
**
** hge_tut02 - Using input, sound and rendering
 */

package main

import (
	"fmt"
	"hge"
)

var h *hge.HGE

var quad hge.Quad

var snd hge.Effect

var (
	x  float32
	y  float32
	dx float32
	dy float32
)

const (
	speed    = 90
	friction = 0.98
)

func setup() {
	x = 100.0
	y = 100.0
	dx = 0.0
	dy = 0.0
}

func boom() {
	pan := int((x - 400) / 4)
	pitch := (dx*dx+dy*dy)*0.0005 + 0.2
	h.Effect_PlayEx(snd, 100, pan, pitch)
}

func FrameFunc() int {
	dt := h.Timer_GetDelta()

	if h.Input_GetKeyState(hge.K_ESCAPE) {
		return 1
	}
	if h.Input_GetKeyState(hge.K_LEFT) {
		dx -= speed * dt
	}
	if h.Input_GetKeyState(hge.K_RIGHT) {
		dx += speed * dt
	}
	if h.Input_GetKeyState(hge.K_UP) {
		dy -= speed * dt
	}
	if h.Input_GetKeyState(hge.K_DOWN) {
		dy += speed * dt
	}

	// Do some movement calculations and collision detection
	dx *= friction
	dy *= friction
	x += dx
	y += dy
	if x > 784 {
		x = 784 - (x - 784)
		dx = -dx
		boom()
	}
	if x < 16 {
		x = 16 + 16 - x
		dx = -dx
		boom()
	}
	if y > 584 {
		y = 584 - (y - 584)
		dy = -dy
		boom()
	}
	if y < 16 {
		y = 16 + 16 - y
		dy = -dy
		boom()
	}

	// Set up quad's screen coordinates
	quad.V[0].X = x - 16
	quad.V[0].Y = y - 16
	quad.V[1].X = x + 16
	quad.V[1].Y = y - 16
	quad.V[2].X = x + 16
	quad.V[2].Y = y + 16
	quad.V[3].X = x - 16
	quad.V[3].Y = y + 16

	// Continue execution
	return 0
}

// This function will be called by HGE when
// the application window should be redrawn.
// Put your rendering code here.
func RenderFunc() int {
	// Begin rendering quads.
	// This function must be called
	// before any actual rendering.
	h.Gfx_BeginScene()

	// Clear screen with black color
	h.Gfx_Clear(0)

	// Render quads here. This time just
	// one of them will serve our needs.
	h.Gfx_RenderQuad(&quad)

	// End rendering and update the screen
	h.Gfx_EndScene()

	// RenderFunc should always return false
	return 0
}

func main() {
	setup()
	// Get HGE interface
	h = hge.Create(hge.VERSION)

	// Set up log file, frame function, render function and window title
	h.System_SetState(hge.LOGFILE, "tutorial02.log")
	h.System_SetState(hge.FRAMEFUNC, FrameFunc)
	h.System_SetState(hge.RENDERFUNC, RenderFunc)
	h.System_SetState(hge.TITLE, "HGE Tutorial 02 - Using input, sound and rendering")

	// Set up video mode
	h.System_SetState(hge.WINDOWED, true)
	h.System_SetState(hge.SCREENWIDTH, 800)
	h.System_SetState(hge.SCREENHEIGHT, 600)
	h.System_SetState(hge.SCREENBPP, 32)

	if h.System_Initiate() {
		// Load sound and texture
		snd = h.Effect_Load("menu.ogg")
		quad.Tex = h.Texture_Load("particles.png")
		if snd == 0 || quad.Tex == 0 {
			// If one of the data files is not found, display
			// an error message and shutdown.
			fmt.Println("Error: Can't load menu.ogg or particles.png")
			h.System_Shutdown()
			h.Release()
			return
		}

		// Set up quad which we will use for rendering sprite
		quad.Blend = hge.BLEND_ALPHAADD | hge.BLEND_COLORMUL | hge.BLEND_ZWRITE

		for i := 0; i < 4; i++ {
			// Set up z-coordinate of vertices
			quad.V[i].Z = 0.5
			// Set up color. The format of DWORD col is 0xAARRGGBB
			quad.V[i].Col = 0xFFFFA000
		}

		// Set up quad's texture coordinates.
		// 0,0 means top left corner and 1,1 -
		// bottom right corner of the texture.
		quad.V[0].TX = 96.0 / 128.0
		quad.V[0].TY = 64.0 / 128.0
		quad.V[1].TX = 128.0 / 128.0
		quad.V[1].TY = 64.0 / 128.0
		quad.V[2].TX = 128.0 / 128.0
		quad.V[2].TY = 96.0 / 128.0
		quad.V[3].TX = 96.0 / 128.0
		quad.V[3].TY = 96.0 / 128.0

		// Let's rock now!
		h.System_Start()

		// Free loaded texture and sound
		h.Texture_Free(quad.Tex)
		h.Effect_Free(snd)
	} else {
		fmt.Println("Error: %s\n", h.System_GetErrorMessage())
	}

	// Clean up and shutdown
	h.System_Shutdown()
	h.Release()
}
<commit_msg>Cleanup tutorial02 a bit<commit_after>/*
 * Haaf's Game Engine 1.8
 * Copyright (C) 2003-2007, Relish Games
 * hge.relishgames.com
 *
 * hge_tut02 - Using input, sound and rendering
 */

package main

import (
	"fmt"
	"hge"
)

var (
	h *hge.HGE

	quad hge.Quad

	snd hge.Effect

	x  = float32(100.0)
	y  = float32(100.0)
	dx = float32(0.0)
	dy = float32(0.0)
)

const (
	speed    = 90.0
	friction = 0.98
)

func boom() {
	pan := int((x - 400) / 4)
	pitch := (dx*dx+dy*dy)*0.0005 + 0.2
	h.Effect_PlayEx(snd, 100, pan, pitch)
}

func FrameFunc() int {
	dt := h.Timer_GetDelta()

	// Process keys
	if h.Input_GetKeyState(hge.K_ESCAPE) {
		return 1
	}
	if h.Input_GetKeyState(hge.K_LEFT) {
		dx -= speed * dt
	}
	if h.Input_GetKeyState(hge.K_RIGHT) {
		dx += speed * dt
	}
	if h.Input_GetKeyState(hge.K_UP) {
		dy -= speed * dt
	}
	if h.Input_GetKeyState(hge.K_DOWN) {
		dy += speed * dt
	}

	// Do some movement calculations and collision detection
	dx *= friction
	dy *= friction
	x += dx
	y += dy
	if x > 784 {
		x = 784 - (x - 784)
		dx = -dx
		boom()
	}
	if x < 16 {
		x = 16 + 16 - x
		dx = -dx
		boom()
	}
	if y > 584 {
		y = 584 - (y - 584)
		dy = -dy
		boom()
	}
	if y < 16 {
		y = 16 + 16 - y
		dy = -dy
		boom()
	}

	// Set up quad's screen coordinates
	quad.V[0].X = x - 16
	quad.V[0].Y = y - 16
	quad.V[1].X = x + 16
	quad.V[1].Y = y - 16
	quad.V[2].X = x + 16
	quad.V[2].Y = y + 16
	quad.V[3].X = x - 16
	quad.V[3].Y = y + 16

	// Continue execution
	return 0
}

// This function will be called by HGE when
// the application window should be redrawn.
// Put your rendering code here.
func RenderFunc() int {
	// Begin rendering quads.
	// This function must be called
	// before any actual rendering.
	h.Gfx_BeginScene()

	// Clear screen with black color
	h.Gfx_Clear(0)

	// Render quads here. This time just
	// one of them will serve our needs.
	h.Gfx_RenderQuad(&quad)

	// End rendering and update the screen
	h.Gfx_EndScene()

	// RenderFunc should always return false
	return 0
}

func main() {
	// Get HGE interface
	h = hge.Create(hge.VERSION)

	// Set up log file, frame function, render function and window title
	h.System_SetState(hge.LOGFILE, "tutorial02.log")
	h.System_SetState(hge.FRAMEFUNC, FrameFunc)
	h.System_SetState(hge.RENDERFUNC, RenderFunc)
	h.System_SetState(hge.TITLE, "HGE Tutorial 02 - Using input, sound and rendering")

	// Set up video mode
	h.System_SetState(hge.WINDOWED, true)
	h.System_SetState(hge.SCREENWIDTH, 800)
	h.System_SetState(hge.SCREENHEIGHT, 600)
	h.System_SetState(hge.SCREENBPP, 32)

	if h.System_Initiate() {
		// Load sound and texture
		snd = h.Effect_Load("menu.ogg")
		quad.Tex = h.Texture_Load("particles.png")
		if snd == 0 || quad.Tex == 0 {
			// If one of the data files is not found, display
			// an error message and shutdown.
			fmt.Println("Error: Can't load menu.ogg or particles.png")
			h.System_Shutdown()
			h.Release()
			return
		}

		// Set up quad which we will use for rendering sprite
		quad.Blend = hge.BLEND_ALPHAADD | hge.BLEND_COLORMUL | hge.BLEND_ZWRITE

		for i := 0; i < 4; i++ {
			// Set up z-coordinate of vertices
			quad.V[i].Z = 0.5
			// Set up color. The format of DWORD col is 0xAARRGGBB
			quad.V[i].Col = 0xFFFFA000
		}

		// Set up quad's texture coordinates.
		// 0,0 means top left corner and 1,1 -
		// bottom right corner of the texture.
		quad.V[0].TX = 96.0 / 128.0
		quad.V[0].TY = 64.0 / 128.0
		quad.V[1].TX = 128.0 / 128.0
		quad.V[1].TY = 64.0 / 128.0
		quad.V[2].TX = 128.0 / 128.0
		quad.V[2].TY = 96.0 / 128.0
		quad.V[3].TX = 96.0 / 128.0
		quad.V[3].TY = 96.0 / 128.0

		// Let's rock now!
		h.System_Start()

		// Free loaded texture and sound
		h.Texture_Free(quad.Tex)
		h.Effect_Free(snd)
	} else {
		fmt.Println("Error: %s\n", h.System_GetErrorMessage())
	}

	// Clean up and shutdown
	h.System_Shutdown()
	h.Release()
}
<|endoftext|>


<commit_before>/*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 conf

import (
	"encoding/json"
	"github.com/skyrings/skyring-common/tools/logger"
	"io/ioutil"
	"path"
	"path/filepath"
	"strings"
)

type Route struct {
	Name       string `json:"name"`
	Method     string `json:"method"`
	Pattern    string `json:"pattern"`
	PluginFunc string `json:"pluginFunc"`
	Version    int    `json:"version"`
}

type ProviderConfig struct {
	Name           string  `json:"name"`
	ProviderBinary string  `json:"binary"`
	CompatVersion  float64 `json:"compatible_version"`
}

type ProviderInfo struct {
	Provider    ProviderConfig    `json:"provider"`
	Routes      []Route           `json:"routes"`
	Provisioner ProvisionerConfig `json:"provisioner"`
}

func LoadProviderConfig(providerConfigDir string) []ProviderInfo {
	var (
		data       ProviderInfo
		collection []ProviderInfo
	)

	files, err := ioutil.ReadDir(providerConfigDir)
	if err != nil {
		logger.Get().Error("Unable to read directory. error: %v", err)
		logger.Get().Error("Failed to initialize")
		return collection
	}
	for _, f := range files {
		logger.Get().Debug("File Name: %s", f.Name())

		file, err := ioutil.ReadFile(path.Join(providerConfigDir, f.Name()))
		if err != nil {
			logger.Get().Critical("Error reading config. error: %v", err)
			continue
		}
		if strings.HasSuffix(f.Name(), ".conf") {
			err = json.Unmarshal(file, &data)
			if err != nil {
				logger.Get().Critical("Error unmarshalling config. error: %v", err)
				continue
			}
			collection = append(collection, data)
			SystemConfig.Provisioners[data.Provider.Name] = data.Provisioner
			data = ProviderInfo{}
		} else {
			if SystemConfig.SysCapabilities.ProductName != "" {
				provider_name := strings.TrimSuffix(f.Name(), filepath.Ext(f.Name()))
				version := make(map[string]string)
				err = json.Unmarshal(file, &version)
				if err != nil {
					logger.Get().Critical("Error unmarshalling config. error: %v", err)
					continue
				}
				SystemConfig.SysCapabilities.StorageProviderDetails[provider_name] = version["version"]
			}
		}
	}
	logger.Get().Debug("Collection: %v", collection)
	return collection
}
<commit_msg>Skyring-Common : If condition added to read only .dat conf files for About<commit_after>/*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 conf

import (
	"encoding/json"
	"github.com/skyrings/skyring-common/tools/logger"
	"io/ioutil"
	"path"
	"path/filepath"
	"strings"
)

type Route struct {
	Name       string `json:"name"`
	Method     string `json:"method"`
	Pattern    string `json:"pattern"`
	PluginFunc string `json:"pluginFunc"`
	Version    int    `json:"version"`
}

type ProviderConfig struct {
	Name           string  `json:"name"`
	ProviderBinary string  `json:"binary"`
	CompatVersion  float64 `json:"compatible_version"`
}

type ProviderInfo struct {
	Provider    ProviderConfig    `json:"provider"`
	Routes      []Route           `json:"routes"`
	Provisioner ProvisionerConfig `json:"provisioner"`
}

func LoadProviderConfig(providerConfigDir string) []ProviderInfo {
	var (
		data       ProviderInfo
		collection []ProviderInfo
	)

	files, err := ioutil.ReadDir(providerConfigDir)
	if err != nil {
		logger.Get().Error("Unable to read directory. error: %v", err)
		logger.Get().Error("Failed to initialize")
		return collection
	}
	for _, f := range files {
		logger.Get().Debug("File Name: %s", f.Name())

		file, err := ioutil.ReadFile(path.Join(providerConfigDir, f.Name()))
		if err != nil {
			logger.Get().Critical("Error reading config. error: %v", err)
			continue
		}
		if strings.HasSuffix(f.Name(), ".conf") {
			err = json.Unmarshal(file, &data)
			if err != nil {
				logger.Get().Critical("Error unmarshalling config. error: %v", err)
				continue
			}
			collection = append(collection, data)
			SystemConfig.Provisioners[data.Provider.Name] = data.Provisioner
			data = ProviderInfo{}
		} else if strings.HasSuffix(f.Name(), ".dat") {
			if SystemConfig.SysCapabilities.ProductName != "" {
				provider_name := strings.TrimSuffix(f.Name(), filepath.Ext(f.Name()))
				version := make(map[string]string)
				err = json.Unmarshal(file, &version)
				if err != nil {
					logger.Get().Critical("Error unmarshalling config. error: %v", err)
					continue
				}
				SystemConfig.SysCapabilities.StorageProviderDetails[provider_name] = version["version"]
			}
		}
	}
	logger.Get().Debug("Collection: %v", collection)
	return collection
}
<|endoftext|>


<commit_before>package ubusuma

import (
  "os/exec"
  "fmt"
  "bufio"
  "strings"
)

// returns a slice of strings containing the short Description about
// the base operationg system.
func Metal() <-chan [4]string {
  c := make(chan [4]string)
  go func() {
    lsb := "lsb_release"
    args := []string {
      "-a",
    }
    cmd := exec.Command(lsb, args ...)
    byt, err := cmd.Output()
    var empty [4]string
    if err != nil {
      c <- empty
    }
    file := strings.NewReader(fmt.Sprintf("%s", byt))
    var kam [4]string
    var count int = 0
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
      kam[count] = scanner.Text()
      count += 1
    }
    if err := scanner.Err(); err != nil {
      c <- empty
    }
    c <- kam
  }()

  return c
}

// Generator show running programs
func RunningUser() <-chan string {
  c := make(chan string)
  go func() {
    comm := "ps"
    args := []string {
      "-x",
    }
    cmd := exec.Command(comm, args...)
    byt, err := cmd.Output()
    if err != nil {
      c <- fmt.Sprintf("%s", err)
    }
    c <- fmt.Sprintf("%s", byt)
  }()

  return c
}

// kill process
func Kill(pid string) <-chan string {
  c := make(chan string)
  go func() {
    comm := "kill"
    var args []string
    args = append(args, "-KILL")
    args = append(args, pid)

    cmd := exec.Command(comm, args...)
    err := cmd.Run()
    if err != nil {
      c <- fmt.Sprintf("%s", err)
    }
    c <- fmt.Sprintf("%s", "Killed")
  }()

  return c
}

func Term(cd string) <-chan string {
  c := make(chan string)
  go func() {
    var comm string // this is used below

    // Check if there is a space at prefix
    checkfront := strings.HasPrefix(cd, " ")
    if checkfront == true {
      c <- fmt.Sprintf("%s", "Clear space at the Prefix")
      return
    }

    // Check if there is a space at suffix
    checkend := strings.HasSuffix(cd, " ")
    if checkend == true {
      c <- fmt.Sprintf("%s", "Clear space at the Suffix")
      return
    }

    // collect all the spaces and dump them
    // in the spaces slice
    var spaces []int
    for i := 0; i < len(cd); i++ {
      if string(cd[i]) == " " {
        spaces = append(spaces, i)
      }
    }

    // Run the single commant without arguments
    if len(spaces) == 0 {
      comm = cd
      cmd := exec.Command(comm)
      byt, err := cmd.Output()
      if err != nil {
        c <- fmt.Sprintf("%s", err)
      }
      c <- fmt.Sprintf("%s", byt)
      return
    }else if len(spaces) == 1 { // Now deal with one argument
      cmdSlice := spaces[0]
      comm = cd[:cmdSlice] // remember this variable?

      // argument holder
      var args []string

      // holds the argument with a space at the prefix
      // waiting to be removed
      ar := cd[cmdSlice:]
      args = append(args, ar[1:])

      cmd := exec.Command(comm, args...)
      byt, err := cmd.Output()
      if err != nil {
        c <- fmt.Sprintf("%s", err)
      }
      c <- fmt.Sprintf("%s", byt)
      return
    }

  }()

  return c
}
<commit_msg>more cleaning<commit_after>package ubusuma

import (
  "os/exec"
  "fmt"
  "bufio"
  "strings"
)

// returns a slice of strings containing the short Description about
// the base operationg system.
func Metal() <-chan [4]string {
  c := make(chan [4]string)
  go func() {
    lsb := "lsb_release"
    args := []string {
      "-a",
    }
    cmd := exec.Command(lsb, args ...)
    byt, err := cmd.Output()
    var empty [4]string
    if err != nil {
      c <- empty
    }
    file := strings.NewReader(fmt.Sprintf("%s", byt))
    var kam [4]string
    var count int = 0
    scanner := bufio.NewScanner(file)
    for scanner.Scan() {
      kam[count] = scanner.Text()
      count += 1
    }
    if err := scanner.Err(); err != nil {
      c <- empty
    }
    c <- kam
  }()

  return c
}

// Generator show running programs
func RunningUser() <-chan string {
  c := make(chan string)
  go func() {
    comm := "ps"
    args := []string {
      "-x",
    }
    cmd := exec.Command(comm, args...)
    byt, err := cmd.Output()
    if err != nil {
      c <- fmt.Sprintf("%s", err)
    }
    c <- fmt.Sprintf("%s", byt)
  }()

  return c
}

// kill process
func Kill(pid string) <-chan string {
  c := make(chan string)
  go func() {
    comm := "kill"
    var args []string
    args = append(args, "-KILL")
    args = append(args, pid)

    cmd := exec.Command(comm, args...)
    err := cmd.Run()
    if err != nil {
      c <- fmt.Sprintf("%s", err)
    }
    c <- fmt.Sprintf("%s", "Killed")
  }()

  return c
}

func Term(cd string) <-chan string {
  c := make(chan string)
  go func() {
    var comm string // this is used below

    // Check if there is a space at prefix
    checkfront := strings.HasPrefix(cd, " ")
    if checkfront == true {
      c <- fmt.Sprintf("%s", "Clear space at the Prefix")
      return
    }

    // Check if there is a space at suffix
    checkend := strings.HasSuffix(cd, " ")
    if checkend == true {
      c <- fmt.Sprintf("%s", "Clear space at the Suffix")
      return
    }

    // collect all the spaces and dump them
    // in the spaces slice
    var spaces []int
    for i := 0; i < len(cd); i++ {
      if string(cd[i]) == " " {
        spaces = append(spaces, i)
      }
    }

    // Run the single commant without arguments
    if len(spaces) == 0 {
      comm = cd
      cmd := exec.Command(comm)
      byt, err := cmd.Output()
      if err != nil {
        c <- fmt.Sprintf("%s", err)
      }
      c <- fmt.Sprintf("%s", byt)
      return
    }else if len(spaces) == 1 { // Now deal with one argument
      cmdSlice := spaces[0]
      comm = cd[:cmdSlice] // remember this variable?

      // argument holder
      var args []string

      // holds the argument with a space at the prefix
      // waiting to be removed
      ar := cd[cmdSlice:]
      args = append(args, ar[1:])

      cmd := exec.Command(comm, args...)
      byt, err := cmd.Output()
      if err != nil {
        c <- fmt.Sprintf("%s", err)
      }
      c <- fmt.Sprintf("%s", byt)
      return
    }else {
      c <- fmt.Sprintf("%s", "syam{p} currently does not support that manny arguments")
      return
    }

  }()

  return c
}
<|endoftext|>


<commit_before>package config

import (
	"fmt"
	"testing"
)

func TestLoadConfig(t *testing.T) {
	c, err := New("../tests/awsnycast.yaml")
	if err != nil {
		t.Log(err)
		t.Fail()
	}
	if c == nil {
		t.Fail()
	}
}

func TestLoadConfigFails(t *testing.T) {
	_, err := New("../tests/doesnotexist.yaml")
	if err == nil {
		t.Fail()
	}
}

func TestLoadConfigHealthchecks(t *testing.T) {
	c, _ := New("../tests/awsnycast.yaml")
	if c.Healthchecks == nil {
		t.Log("c.Healthchecks == nil")
		t.Fail()
	}
	h, ok := c.Healthchecks["public"]
	if !ok {
		t.Log("c.Healthchecks['public'] not ok")
		t.Fail()
	}
	if h.Type != "ping" {
		t.Log("type not ping")
		t.Fail()
	}
	if h.Destination != "8.8.8.8" {
		t.Log("Destination not 8.8.8.8")
		t.Fail()
	}
	if h.Rise != 2 {
		t.Log("Rise not 2")
		t.Fail()
	}
	if h.Fall != 10 {
		t.Log("fall not 10")
		t.Fail()
	}
	if h.Every != 1 {
		t.Log("every not 1")
		t.Fail()
	}
	a, ok := c.RouteTables["a"]
	if !ok {
		t.Log("RouteTables a not ok")
		t.Fail()
	}
	if a.Find.Type != "by_tag" {
		t.Log("Not by_tag")
		t.Fail()
	}
	if v, ok := a.Find.Config["key"]; ok {
		if v != "Name" {
			t.Log("Config key Name not found")
			t.Fail()
		}
	} else {
		t.Log(fmt.Sprintf("Config key not found: %+v", a.Find.Config))
		t.Fail()
	}
	if v, ok := a.Find.Config["value"]; ok {
		if v != "private a" {
			t.Log("Config value not private a")
			t.Fail()
		}
	} else {
		t.Log("Config value not present")
		t.Fail()
	}
	routes := a.UpsertRoutes
	if len(routes) != 2 {
		t.Log("Route len not 2")
		t.Fail()
	}
	for _, route := range routes {
		if route.Cidr == "0.0.0.0/0" || route.Cidr == "192.168.1.1/32" {
			if route.Instance != "SELF" {
				t.Log("route.Instance not SELF")
				t.Fail()
			}
			if route.Cidr == "0.0.0.0/0" {
				if route.Healthcheck != "public" {
					t.Log("Healthcheck not public")
					t.Fail()
				}
			} else {
				if route.Healthcheck != "localservice" {
					t.Fail()
				}
			}
		} else {
			t.Fail()
		}
	}
	b, ok := c.RouteTables["b"]
	if !ok {
		t.Fail()
	}
	if b.Find.Type != "by_tag" {
		t.Fail()
	}
}

func TestHealthcheckDefault(t *testing.T) {
	h := Healthcheck{
		Type: "ping",
	}
	h.Default()
	if h.Rise != 2 {
		t.Fail()
	}
	if h.Fall != 3 {
		t.Fail()
	}
}

func TestHealthcheckValidate(t *testing.T) {
	h := Healthcheck{
		Type: "ping",
	}
	h.Default()
	err := h.Validate("foo")
	if err != nil {
		t.Log(err)
		t.Fail()
	}
}

func TestHealthcheckValidateFailType(t *testing.T) {
	h := Healthcheck{
		Type: "notping",
	}
	err := h.Validate("foo")
	if err == nil {
		t.Fail()
	}
	if err.Error() != "Unknown healthcheck type 'notping' in foo" {
		t.Log(err.Error())
		t.Fail()
	}
}

func TestHealthcheckValidateFailRise(t *testing.T) {
	h := Healthcheck{
		Type: "ping",
		Fall: 1,
	}
	err := h.Validate("foo")
	if err == nil {
		t.Fail()
	}
	if err.Error() != "rise must be > 0 in foo" {
		t.Log(err.Error())
		t.Fail()
	}
}

func TestHealthcheckValidateFailFall(t *testing.T) {
	h := Healthcheck{
		Type: "ping",
		Rise: 1,
	}
	err := h.Validate("foo")
	if err == nil {
		t.Fail()
	}
	if err.Error() != "fall must be > 0 in foo" {
		t.Log(err.Error())
		t.Fail()
	}
}

func TestConfigDefault(t *testing.T) {
	r := make(map[string]RouteTable)
	c := Config{
		RouteTables: r,
	} // FIXME
	c.Default()
	if c.Healthchecks == nil {
		t.Fail()
	}
	// FIXME check things
}

func TestConfigValidateNoRouteTables(t *testing.T) {
	c := Config{}
	c.Default()
	err := c.Validate()
	if err == nil {
		t.Fail()
	}
	// FIXME check error
}

func TestConfigValidate(t *testing.T) {
	u := make([]UpsertRoutesSpec, 1)
	u[0] = UpsertRoutesSpec{
		Cidr: "127.0.0.1",
	}
	r := make(map[string]RouteTable)
	r["a"] = RouteTable{
		UpsertRoutes: u,
	}
	c := Config{
		RouteTables: r,
	}
	c.Default()
	err := c.Validate()
	if err != nil {
		t.Log(err)
		t.Fail()
	}
	rt := c.RouteTables["a"]
	ur := rt.UpsertRoutes[0]
	if ur.Cidr != "127.0.0.1/32" {
		t.Fail()
	}
}

func TestConfigValidateEmpty(t *testing.T) {
	c := Config{}
	c.Default()
	err := c.Validate()
	if err == nil {
		t.Fail()
	}
	// FIXME test err
}

func TestConfigValidateEmptyRouteTables(t *testing.T) {
	r := make(map[string]RouteTable)
	c := Config{
		RouteTables: r,
	}
	c.Default()
	err := c.Validate()
	if err == nil {
		t.Fail()
	}
	// FIXME test err
}

// FIXME - need tests for each part of config failing, and check errors.

func TestUpsertRoutesSpecDefault(t *testing.T) {
	u := UpsertRoutesSpec{
		Cidr: "127.0.0.1",
	}
	u.Default()
	if u.Cidr != "127.0.0.1/32" {
		t.Log("Not canonicalized in UpsertRoutesSpecDefault")
		t.Fail()
	}
	if u.Instance != "SELF" {
		t.Log("Instance not defaulted to SELF")
	}
}

func TestUpsertRoutesSpecValidateBadInstance(t *testing.T) {
	r := UpsertRoutesSpec{
		Instance: "vpc-1234",
		Cidr:     "127.0.0.1",
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestUpsertRoutesSpecValidateMissingCidr(t *testing.T) {
	r := UpsertRoutesSpec{
		Instance: "SELF",
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestUpsertRoutesSpecValidateBadCidr1(t *testing.T) {
	r := UpsertRoutesSpec{
		Cidr:     "300.0.0.0/16",
		Instance: "SELF",
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestUpsertRoutesSpecValidateBadCidr2(t *testing.T) {
	r := UpsertRoutesSpec{
		Cidr:     "3.0.0.0/160",
		Instance: "SELF",
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestUpsertRoutesSpecValidateBadCidr3(t *testing.T) {
	r := UpsertRoutesSpec{
		Cidr:     "foo",
		Instance: "SELF",
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestUpsertRoutesSpecValidate(t *testing.T) {
	r := UpsertRoutesSpec{
		Cidr:     "0.0.0.0/0",
		Instance: "SELF",
	}
	err := r.Validate("foo")
	if err != nil {
		t.Log(err)
		t.Fail()
	}
}

func TestRouteFindSpecDefault(t *testing.T) {
	r := RouteFindSpec{}
	r.Default()
	if r.Config == nil {
		t.Fail()
	}
}
func TestRouteFindSpecValidate(t *testing.T) {
	c := make(map[string]string)
	c["key"] = "Name"
	c["value"] = "private a"
	r := RouteFindSpec{
		Type:   "by_tag",
		Config: c,
	}
	err := r.Validate("foo")
	if err != nil {
		t.Log(err)
		t.Fail()
	}
}

func TestRouteFindSpecValidateNoType(t *testing.T) {
	c := make(map[string]string)
	c["key"] = "Name"
	c["value"] = "private a"
	r := RouteFindSpec{
		Config: c,
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestRouteFindSpecValidateNoConfig(t *testing.T) {
	r := RouteFindSpec{
		Type: "by_tag",
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestRouteTableDefaultEmpty(t *testing.T) {
	r := RouteTable{}
	r.Default()
}

func TestRouteTableDefault(t *testing.T) {
	routes := make([]UpsertRoutesSpec, 1)
	routes[0] = UpsertRoutesSpec{
		Cidr: "127.0.0.1",
	}
	r := RouteTable{
		UpsertRoutes: routes,
	}
	r.Default()
	if len(r.UpsertRoutes) != 1 {
		t.Fail()
	}
	routeSpec := r.UpsertRoutes[0]
	if routeSpec.Cidr != "127.0.0.1/32" {
		t.Fail()
	}
}

func TestRouteTableValidateNullRoutes(t *testing.T) {
	r := RouteTable{}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestRouteTableValidateNoRoutes(t *testing.T) {
	r := RouteTable{
		UpsertRoutes: make([]UpsertRoutesSpec, 0),
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestRouteTableValidate(t *testing.T) {
	routes := make([]UpsertRoutesSpec, 1)
	routes[0] = UpsertRoutesSpec{
		Cidr: "127.0.0.1",
	}
	r := RouteTable{
		UpsertRoutes: routes,
	}
	r.Default()
	err := r.Validate("foo")
	if err != nil {
		t.Fail()
	}
}
<commit_msg>More tests of default config<commit_after>package config

import (
	"fmt"
	"testing"
)

func TestLoadConfig(t *testing.T) {
	c, err := New("../tests/awsnycast.yaml")
	if err != nil {
		t.Log(err)
		t.Fail()
	}
	if c == nil {
		t.Fail()
	}
}

func TestLoadConfigFails(t *testing.T) {
	_, err := New("../tests/doesnotexist.yaml")
	if err == nil {
		t.Fail()
	}
}

func TestLoadConfigHealthchecks(t *testing.T) {
	c, _ := New("../tests/awsnycast.yaml")
	if c.Healthchecks == nil {
		t.Log("c.Healthchecks == nil")
		t.Fail()
	}
	h, ok := c.Healthchecks["public"]
	if !ok {
		t.Log("c.Healthchecks['public'] not ok")
		t.Fail()
	}
	if h.Type != "ping" {
		t.Log("type not ping")
		t.Fail()
	}
	if h.Destination != "8.8.8.8" {
		t.Log("Destination not 8.8.8.8")
		t.Fail()
	}
	if h.Rise != 2 {
		t.Log("Rise not 2")
		t.Fail()
	}
	if h.Fall != 10 {
		t.Log("fall not 10")
		t.Fail()
	}
	if h.Every != 1 {
		t.Log("every not 1")
		t.Fail()
	}
	a, ok := c.RouteTables["a"]
	if !ok {
		t.Log("RouteTables a not ok")
		t.Fail()
	}
	if a.Find.Type != "by_tag" {
		t.Log("Not by_tag")
		t.Fail()
	}
	if v, ok := a.Find.Config["key"]; ok {
		if v != "Name" {
			t.Log("Config key Name not found")
			t.Fail()
		}
	} else {
		t.Log(fmt.Sprintf("Config key not found: %+v", a.Find.Config))
		t.Fail()
	}
	if v, ok := a.Find.Config["value"]; ok {
		if v != "private a" {
			t.Log("Config value not private a")
			t.Fail()
		}
	} else {
		t.Log("Config value not present")
		t.Fail()
	}
	routes := a.UpsertRoutes
	if len(routes) != 2 {
		t.Log("Route len not 2")
		t.Fail()
	}
	for _, route := range routes {
		if route.Cidr == "0.0.0.0/0" || route.Cidr == "192.168.1.1/32" {
			if route.Instance != "SELF" {
				t.Log("route.Instance not SELF")
				t.Fail()
			}
			if route.Cidr == "0.0.0.0/0" {
				if route.Healthcheck != "public" {
					t.Log("Healthcheck not public")
					t.Fail()
				}
			} else {
				if route.Healthcheck != "localservice" {
					t.Fail()
				}
			}
		} else {
			t.Fail()
		}
	}
	b, ok := c.RouteTables["b"]
	if !ok {
		t.Fail()
	}
	if b.Find.Type != "by_tag" {
		t.Fail()
	}
}

func TestHealthcheckDefault(t *testing.T) {
	h := Healthcheck{
		Type: "ping",
	}
	h.Default()
	if h.Rise != 2 {
		t.Fail()
	}
	if h.Fall != 3 {
		t.Fail()
	}
}

func TestHealthcheckValidate(t *testing.T) {
	h := Healthcheck{
		Type: "ping",
	}
	h.Default()
	err := h.Validate("foo")
	if err != nil {
		t.Log(err)
		t.Fail()
	}
}

func TestHealthcheckValidateFailType(t *testing.T) {
	h := Healthcheck{
		Type: "notping",
	}
	err := h.Validate("foo")
	if err == nil {
		t.Fail()
	}
	if err.Error() != "Unknown healthcheck type 'notping' in foo" {
		t.Log(err.Error())
		t.Fail()
	}
}

func TestHealthcheckValidateFailRise(t *testing.T) {
	h := Healthcheck{
		Type: "ping",
		Fall: 1,
	}
	err := h.Validate("foo")
	if err == nil {
		t.Fail()
	}
	if err.Error() != "rise must be > 0 in foo" {
		t.Log(err.Error())
		t.Fail()
	}
}

func TestHealthcheckValidateFailFall(t *testing.T) {
	h := Healthcheck{
		Type: "ping",
		Rise: 1,
	}
	err := h.Validate("foo")
	if err == nil {
		t.Fail()
	}
	if err.Error() != "fall must be > 0 in foo" {
		t.Log(err.Error())
		t.Fail()
	}
}

func TestConfigDefault(t *testing.T) {
	r := make(map[string]RouteTable)
	r["a"] = RouteTable{
		UpsertRoutes: []UpsertRoutesSpec{UpsertRoutesSpec{Cidr: "127.0.0.1"}},
	}
	c := Config{
		RouteTables: r,
	}
	c.Default()
	if c.Healthchecks == nil {
		t.Fail()
	}
	if c.RouteTables["a"].UpsertRoutes[0].Cidr != "127.0.0.1/32" {
		t.Fail()
	}
}

func TestConfigValidateNoRouteTables(t *testing.T) {
	c := Config{}
	c.Default()
	err := c.Validate()
	if err == nil {
		t.Fail()
	}
	// FIXME check error
}

func TestConfigValidate(t *testing.T) {
	u := make([]UpsertRoutesSpec, 1)
	u[0] = UpsertRoutesSpec{
		Cidr: "127.0.0.1",
	}
	r := make(map[string]RouteTable)
	r["a"] = RouteTable{
		UpsertRoutes: u,
	}
	c := Config{
		RouteTables: r,
	}
	c.Default()
	err := c.Validate()
	if err != nil {
		t.Log(err)
		t.Fail()
	}
	rt := c.RouteTables["a"]
	ur := rt.UpsertRoutes[0]
	if ur.Cidr != "127.0.0.1/32" {
		t.Fail()
	}
}

func TestConfigValidateEmpty(t *testing.T) {
	c := Config{}
	c.Default()
	err := c.Validate()
	if err == nil {
		t.Fail()
	}
	// FIXME test err
}

func TestConfigValidateEmptyRouteTables(t *testing.T) {
	r := make(map[string]RouteTable)
	c := Config{
		RouteTables: r,
	}
	c.Default()
	err := c.Validate()
	if err == nil {
		t.Fail()
	}
	// FIXME test err
}

// FIXME - need tests for each part of config failing, and check errors.

func TestUpsertRoutesSpecDefault(t *testing.T) {
	u := UpsertRoutesSpec{
		Cidr: "127.0.0.1",
	}
	u.Default()
	if u.Cidr != "127.0.0.1/32" {
		t.Log("Not canonicalized in UpsertRoutesSpecDefault")
		t.Fail()
	}
	if u.Instance != "SELF" {
		t.Log("Instance not defaulted to SELF")
	}
}

func TestUpsertRoutesSpecValidateBadInstance(t *testing.T) {
	r := UpsertRoutesSpec{
		Instance: "vpc-1234",
		Cidr:     "127.0.0.1",
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestUpsertRoutesSpecValidateMissingCidr(t *testing.T) {
	r := UpsertRoutesSpec{
		Instance: "SELF",
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestUpsertRoutesSpecValidateBadCidr1(t *testing.T) {
	r := UpsertRoutesSpec{
		Cidr:     "300.0.0.0/16",
		Instance: "SELF",
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestUpsertRoutesSpecValidateBadCidr2(t *testing.T) {
	r := UpsertRoutesSpec{
		Cidr:     "3.0.0.0/160",
		Instance: "SELF",
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestUpsertRoutesSpecValidateBadCidr3(t *testing.T) {
	r := UpsertRoutesSpec{
		Cidr:     "foo",
		Instance: "SELF",
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestUpsertRoutesSpecValidate(t *testing.T) {
	r := UpsertRoutesSpec{
		Cidr:     "0.0.0.0/0",
		Instance: "SELF",
	}
	err := r.Validate("foo")
	if err != nil {
		t.Log(err)
		t.Fail()
	}
}

func TestRouteFindSpecDefault(t *testing.T) {
	r := RouteFindSpec{}
	r.Default()
	if r.Config == nil {
		t.Fail()
	}
}
func TestRouteFindSpecValidate(t *testing.T) {
	c := make(map[string]string)
	c["key"] = "Name"
	c["value"] = "private a"
	r := RouteFindSpec{
		Type:   "by_tag",
		Config: c,
	}
	err := r.Validate("foo")
	if err != nil {
		t.Log(err)
		t.Fail()
	}
}

func TestRouteFindSpecValidateNoType(t *testing.T) {
	c := make(map[string]string)
	c["key"] = "Name"
	c["value"] = "private a"
	r := RouteFindSpec{
		Config: c,
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestRouteFindSpecValidateNoConfig(t *testing.T) {
	r := RouteFindSpec{
		Type: "by_tag",
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestRouteTableDefaultEmpty(t *testing.T) {
	r := RouteTable{}
	r.Default()
}

func TestRouteTableDefault(t *testing.T) {
	routes := make([]UpsertRoutesSpec, 1)
	routes[0] = UpsertRoutesSpec{
		Cidr: "127.0.0.1",
	}
	r := RouteTable{
		UpsertRoutes: routes,
	}
	r.Default()
	if len(r.UpsertRoutes) != 1 {
		t.Fail()
	}
	routeSpec := r.UpsertRoutes[0]
	if routeSpec.Cidr != "127.0.0.1/32" {
		t.Fail()
	}
}

func TestRouteTableValidateNullRoutes(t *testing.T) {
	r := RouteTable{}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestRouteTableValidateNoRoutes(t *testing.T) {
	r := RouteTable{
		UpsertRoutes: make([]UpsertRoutesSpec, 0),
	}
	err := r.Validate("foo")
	if err == nil {
		t.Fail()
	}
	// FIXME Check error
}

func TestRouteTableValidate(t *testing.T) {
	routes := make([]UpsertRoutesSpec, 1)
	routes[0] = UpsertRoutesSpec{
		Cidr: "127.0.0.1",
	}
	r := RouteTable{
		UpsertRoutes: routes,
	}
	r.Default()
	err := r.Validate("foo")
	if err != nil {
		t.Fail()
	}
}
<|endoftext|>


<commit_before>package config

import (
	"testing"
	"os"
	. "github.com/smartystreets/goconvey/convey"
)

func TestConfig(t *testing.T) {
	err := os.Setenv("PILOSA_CONFIG", "test.yaml")
	if err != nil {
		t.Fatal("Error setting PILOSA_CONFIG")
	}
	Convey("config.Get()", t, func() {
		So(Get("port_tcp").(int), ShouldEqual, 12000)
		So(Get("port_http").(int), ShouldEqual, 15000)
		So(Get("temp").(string), ShouldEqual, "/tmp")
		So(Get("notfound"), ShouldBeNil)
	})
	Convey("config.GetSafe()", t, func() {
		val, ok := GetSafe("port_tcp")
		So(ok, ShouldBeTrue)
		So(val.(int), ShouldEqual, 12000)
		val, ok = GetSafe("derp")
		So(ok, ShouldBeFalse)
		So(val, ShouldBeNil)
	})
	Convey("config.GetInt()", t, func() {
		So(GetInt("port_tcp"), ShouldEqual, 12000)
		So(GetInt("port_http"), ShouldEqual, 15000)
		So(GetInt("notfound"), ShouldEqual, 0)
	})
	Convey("config.GetString()", t, func() {
		So(GetString("temp"), ShouldEqual, "/tmp")
	})
}
<commit_msg>Type assertions not needed with convey.<commit_after>package config

import (
	"testing"
	"os"
	. "github.com/smartystreets/goconvey/convey"
)

func TestConfig(t *testing.T) {
	err := os.Setenv("PILOSA_CONFIG", "test.yaml")
	if err != nil {
		t.Fatal("Error setting PILOSA_CONFIG")
	}
	Convey("config.Get()", t, func() {
		So(Get("port_tcp"), ShouldEqual, 12000)
		So(Get("port_http"), ShouldEqual, 15000)
		So(Get("temp"), ShouldEqual, "/tmp")
		So(Get("notfound"), ShouldBeNil)
	})
	Convey("config.GetSafe()", t, func() {
		val, ok := GetSafe("port_tcp")
		So(ok, ShouldBeTrue)
		So(val, ShouldEqual, 12000)
		val, ok = GetSafe("derp")
		So(ok, ShouldBeFalse)
		So(val, ShouldBeNil)
	})
	Convey("config.GetInt()", t, func() {
		So(GetInt("port_tcp"), ShouldEqual, 12000)
		So(GetInt("port_http"), ShouldEqual, 15000)
		So(GetInt("notfound"), ShouldEqual, 0)
	})
	Convey("config.GetString()", t, func() {
		So(GetString("temp"), ShouldEqual, "/tmp")
	})
}
<|endoftext|>


<commit_before>package config

import (
	"errors"
	"os"
	"testing"

	must "github.com/theothertomelliott/go-must"

	"github.com/yext/edward/common"
	"github.com/yext/edward/services"
)

var service1 = services.ServiceConfig{
	Name:         "service1",
	Path:         common.StringToStringPointer("."),
	RequiresSudo: true,
	Commands: services.ServiceConfigCommands{
		Build:  "buildCmd",
		Launch: "launchCmd",
		Stop:   "stopCmd",
	},
	LaunchChecks: &services.LaunchChecks{
		LogText: "startedProperty",
	},
	Logger: common.NullLogger{},
}

var group1 = services.ServiceGroupConfig{
	Name:     "group1",
	Services: []*services.ServiceConfig{&service1},
	Groups:   []*services.ServiceGroupConfig{},
	Logger:   common.NullLogger{},
}

var service2 = services.ServiceConfig{
	Name: "service2",
	Path: common.StringToStringPointer("service2/path"),
	Commands: services.ServiceConfigCommands{
		Build:  "buildCmd2",
		Launch: "launchCmd2",
		Stop:   "stopCmd2",
	},
	Logger: common.NullLogger{},
}

var group2 = services.ServiceGroupConfig{
	Name:     "group2",
	Services: []*services.ServiceConfig{&service2},
	Groups:   []*services.ServiceGroupConfig{},
	Logger:   common.NullLogger{},
}

var service3 = services.ServiceConfig{
	Name:         "service3",
	Path:         common.StringToStringPointer("."),
	RequiresSudo: true,
	Commands: services.ServiceConfigCommands{
		Build:  "buildCmd",
		Launch: "launchCmd",
		Stop:   "stopCmd",
	},
	LaunchChecks: &services.LaunchChecks{
		LogText: "startedProperty",
	},
	Logger: common.NullLogger{},
}

var group3 = services.ServiceGroupConfig{
	Name:     "group3",
	Services: []*services.ServiceConfig{&service3},
	Groups:   []*services.ServiceGroupConfig{},
	Logger:   common.NullLogger{},
}

var fileBasedTests = []struct {
	name          string
	inFile        string
	outServiceMap map[string]*services.ServiceConfig
	outGroupMap   map[string]*services.ServiceGroupConfig
	outErr        error
}{
	{
		name:   "Config with imports",
		inFile: "test1.json",
		outServiceMap: map[string]*services.ServiceConfig{
			"service1": &service1,
			"service2": &service2,
			"service3": &service3,
		},
		outGroupMap: map[string]*services.ServiceGroupConfig{
			"group1": &group1,
			"group2": &group2,
			"group3": &group3,
		},
		outErr: nil,
	},
	{
		name:          "Config missing imports",
		inFile:        "test2.json",
		outServiceMap: nil,
		outGroupMap:   nil,
		outErr:        errors.New("open imports2/import2.json: no such file or directory"),
	},
	{
		name:          "Duplicated import",
		inFile:        "test3.json",
		outServiceMap: nil,
		outGroupMap:   nil,
		outErr:        errors.New("Service name already exists: service2"),
	},
	{
		name:          "Duplicated service",
		inFile:        "test4.json",
		outServiceMap: nil,
		outGroupMap:   nil,
		outErr:        errors.New("Service name already exists: service1"),
	},
	{
		name:          "Duplicated group",
		inFile:        "test5.json",
		outServiceMap: nil,
		outGroupMap:   nil,
		outErr:        errors.New("Group name already exists: group"),
	},
	{
		name:          "Group and service clash",
		inFile:        "test6.json",
		outServiceMap: nil,
		outGroupMap:   nil,
		outErr:        errors.New("A service already exists with the name: group"),
	},
}

func TestLoadConfigWithImports(t *testing.T) {
	err := os.Chdir("testdata")
	if err != nil {
		t.Errorf("%v", err)
		return
	}
	for _, test := range fileBasedTests {
		cfg, err := LoadConfig(test.inFile, "", nil)
		validateTestResults(cfg, err, test.outServiceMap, test.outGroupMap, test.outErr, test.name, t)
	}
}

func validateTestResults(cfg Config, err error, expectedServices map[string]*services.ServiceConfig, expectedGroups map[string]*services.ServiceGroupConfig, expectedErr error, name string, t *testing.T) {
	for _, s := range cfg.ServiceMap {
		s.ConfigFile = ""
	}
	must.BeEqual(t, expectedServices, cfg.ServiceMap, name+": services did not match.")
	must.BeEqual(t, expectedGroups, cfg.GroupMap, name+": groups did not match.")

	must.BeEqualErrors(t, expectedErr, err, name+": Errors did not match.")
}
<commit_msg>Use the expected config file path for testing.<commit_after>package config

import (
	"errors"
	"os"
	"path/filepath"
	"testing"

	must "github.com/theothertomelliott/go-must"

	"github.com/yext/edward/common"
	"github.com/yext/edward/services"
)

var service1 = services.ServiceConfig{
	Name:         "service1",
	Path:         common.StringToStringPointer("."),
	RequiresSudo: true,
	Commands: services.ServiceConfigCommands{
		Build:  "buildCmd",
		Launch: "launchCmd",
		Stop:   "stopCmd",
	},
	LaunchChecks: &services.LaunchChecks{
		LogText: "startedProperty",
	},
	Logger: common.NullLogger{},
}

var group1 = services.ServiceGroupConfig{
	Name:     "group1",
	Services: []*services.ServiceConfig{&service1},
	Groups:   []*services.ServiceGroupConfig{},
	Logger:   common.NullLogger{},
}

var service2 = services.ServiceConfig{
	Name: "service2",
	Path: common.StringToStringPointer("service2/path"),
	Commands: services.ServiceConfigCommands{
		Build:  "buildCmd2",
		Launch: "launchCmd2",
		Stop:   "stopCmd2",
	},
	Logger: common.NullLogger{},
}

var group2 = services.ServiceGroupConfig{
	Name:     "group2",
	Services: []*services.ServiceConfig{&service2},
	Groups:   []*services.ServiceGroupConfig{},
	Logger:   common.NullLogger{},
}

var service3 = services.ServiceConfig{
	Name:         "service3",
	Path:         common.StringToStringPointer("."),
	RequiresSudo: true,
	Commands: services.ServiceConfigCommands{
		Build:  "buildCmd",
		Launch: "launchCmd",
		Stop:   "stopCmd",
	},
	LaunchChecks: &services.LaunchChecks{
		LogText: "startedProperty",
	},
	Logger: common.NullLogger{},
}

var group3 = services.ServiceGroupConfig{
	Name:     "group3",
	Services: []*services.ServiceConfig{&service3},
	Groups:   []*services.ServiceGroupConfig{},
	Logger:   common.NullLogger{},
}

var fileBasedTests = []struct {
	name          string
	inFile        string
	outServiceMap map[string]*services.ServiceConfig
	outGroupMap   map[string]*services.ServiceGroupConfig
	outErr        error
}{
	{
		name:   "Config with imports",
		inFile: "test1.json",
		outServiceMap: map[string]*services.ServiceConfig{
			"service1": &service1,
			"service2": &service2,
			"service3": &service3,
		},
		outGroupMap: map[string]*services.ServiceGroupConfig{
			"group1": &group1,
			"group2": &group2,
			"group3": &group3,
		},
		outErr: nil,
	},
	{
		name:          "Config missing imports",
		inFile:        "test2.json",
		outServiceMap: nil,
		outGroupMap:   nil,
		outErr:        errors.New("open imports2/import2.json: no such file or directory"),
	},
	{
		name:          "Duplicated import",
		inFile:        "test3.json",
		outServiceMap: nil,
		outGroupMap:   nil,
		outErr:        errors.New("Service name already exists: service2"),
	},
	{
		name:          "Duplicated service",
		inFile:        "test4.json",
		outServiceMap: nil,
		outGroupMap:   nil,
		outErr:        errors.New("Service name already exists: service1"),
	},
	{
		name:          "Duplicated group",
		inFile:        "test5.json",
		outServiceMap: nil,
		outGroupMap:   nil,
		outErr:        errors.New("Group name already exists: group"),
	},
	{
		name:          "Group and service clash",
		inFile:        "test6.json",
		outServiceMap: nil,
		outGroupMap:   nil,
		outErr:        errors.New("A service already exists with the name: group"),
	},
}

func TestLoadConfigWithImports(t *testing.T) {
	err := os.Chdir("testdata")
	if err != nil {
		t.Errorf("%v", err)
		return
	}
	for _, test := range fileBasedTests {
		cfg, err := LoadConfig(test.inFile, "", nil)
		validateTestResults(cfg, err, test.inFile, test.outServiceMap, test.outGroupMap, test.outErr, test.name, t)
	}
}

func validateTestResults(cfg Config, err error, file string, expectedServices map[string]*services.ServiceConfig, expectedGroups map[string]*services.ServiceGroupConfig, expectedErr error, name string, t *testing.T) {
	for _, s := range expectedServices {
		s.ConfigFile, _ = filepath.Abs(file)
	}
	must.BeEqual(t, expectedServices, cfg.ServiceMap, name+": services did not match.")
	must.BeEqual(t, expectedGroups, cfg.GroupMap, name+": groups did not match.")

	must.BeEqualErrors(t, expectedErr, err, name+": Errors did not match.")
}
<|endoftext|>