<commit_before>package storage

import (
	"bytes"
	"time"

	"encoding/json"

	"fmt"

	"strconv"

	"os"

	"github.com/boltdb/bolt"
	"github.com/pinfake/pes6go/data/block"
)

type Bolt struct {
	db *bolt.DB
}

func uint32ToBytes(data uint32) []byte {
	return []byte(strconv.Itoa(int(data)))
}

func NewBolt() (*Bolt, error) {
	_ = os.Mkdir("./db", 0700)
	db, err := bolt.Open("./db/pes6godb.bolt", 0600, nil)
	if err != nil {
		return nil, err
	}
	db.Update(func(tx *bolt.Tx) error {
		tx.CreateBucketIfNotExists([]byte("accounts"))
		tx.CreateBucketIfNotExists([]byte("players"))
		return nil
	})

	return &Bolt{
		db: db,
	}, nil
}

func (b Bolt) CreateAccount(account *Account) (uint32, error) {
	err := b.db.Update(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte("accounts"))
		v := bucket.Get([]byte(account.Key))
		if v != nil {
			return fmt.Errorf("Account %s exists", account.Key)
		}
		id, _ := bucket.NextSequence()
		account.Id = uint32(id)
		buf, err := json.Marshal(account)
		if err != nil {
			return err
		}
		err = bucket.Put([]byte(account.Key), buf)
		return err
	})
	return account.Id, err
}

func (b Bolt) CreatePlayer(account *Account, position byte, player *block.Player) (uint32, error) {
	err := b.db.Update(func(tx *bolt.Tx) error {
		accBckt := tx.Bucket([]byte("accounts"))
		plyBckt := tx.Bucket([]byte("players"))
		id, _ := plyBckt.NextSequence()
		player.Id = uint32(id)
		buf, err := json.Marshal(player)
		if err != nil {
			return err
		}
		err = plyBckt.Put(uint32ToBytes(player.Id), buf)
		if err != nil {
			return err
		} else {
			account.Players[position] = player.Id
			buf, err := json.Marshal(account)
			if err != nil {
				return err
			}
			err = accBckt.Put([]byte(account.Key), buf)
			return err
		}
	})
	return player.Id, err
}

func (b Bolt) GetLobbies(serverId uint32) []*block.Lobby {
	switch serverId {
	case 1:
		return []*block.Lobby{
			{Type: 63, Name: "Lobby 1 Kenobi"},
			{Type: 63, Name: "Lobby 2 testá3"},
			{Type: 63, Name: "Lobby 3 testñ3"},
		}
	case 2:
		return []*block.Lobby{
			{Type: 0x1f},
		}
	default:
		return nil
	}
}

func (b Bolt) GetPlayer(id uint32) (*block.Player, error) {
	var player *block.Player
	err := b.db.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte("players"))
		v := bucket.Get(uint32ToBytes(id))
		if v == nil {
			return fmt.Errorf("Player with id %d not found", id)
		}
		player = &block.Player{}
		err := json.Unmarshal(v, player)
		if err != nil {
			return err
		}
		return nil
	})

	return player, err
}

func (b Bolt) GetServerNews() []block.News {
	return []block.News{
		{
			Time:  time.Date(2016, 1, 1, 12, 0, 0, 0, time.UTC),
			Title: "Mariano Speaks!",
			Text: "Es el vecino el que elige al alcalde y es el alcalde el que quiere " +
				"que sean los vecinos el alcalde",
		},
		{
			Time:  time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC),
			Title: "Mariano Keeps Speaking!",
			Text:  "No he dormido nada, no me pregunten demasiado si hacen el favor",
		},
	}
}

func (b Bolt) GetRankUrls() []block.RankUrl {
	return []block.RankUrl{
		{0, "http://pes6web.winning-eleven.net/pes6e2/ranking/we10getrank.html"},
		{1, "https://pes6web.winning-eleven.net/pes6e2/ranking/we10getgrprank.html"},
		{2, "http://pes6web.winning-eleven.net/pes6e2/ranking/we10RankingWeek.html"},
		{3, "https://pes6web.winning-eleven.net/pes6e2/ranking/we10GrpRankingWeek.html"},
		{4, "https://pes6web.winning-eleven.net/pes6e2/ranking/we10RankingCup.html"},
		{5, "http://www.pes6j.net/server/we10getgrpboard.html"},
		{6, "http://www.pes6j.net/server/we10getgrpinvitelist.html"},
	}
}

func (b Bolt) GetAccountPlayers(account *Account) ([3]*block.Player, error) {
	var players [3]*block.Player
	err := b.db.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte("players"))
		for i := range account.Players {
			v := bucket.Get(uint32ToBytes(account.Players[i]))
			var player block.Player
			if v == nil {
				player = block.Player{}
			} else {
				err := json.Unmarshal(v, &player)
				if err != nil {
					return err
				}
			}
			players[i] = &player
		}
		return nil
	})

	return players, err
}

func (b Bolt) GetGroupInfo(id uint32) block.GroupInfo {
	return block.GroupInfo{
		Time: time.Date(2016, 1, 1, 12, 0, 0, 0, time.UTC),
	}
}

func (b Bolt) GetPlayerSettings(id uint32) block.PlayerSettings {
	return block.PlayerSettings{
		Settings: DefaultPlayerSettings,
	}
}

func (b Bolt) Login(account *Account) (*Account, error) {
	var ret *Account
	err := b.db.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte("accounts"))
		v := bucket.Get([]byte(account.Key))
		var acc Account
		err := json.Unmarshal(v, &acc)
		if err != nil {
			return err
		}
		if !bytes.Equal(acc.Hash, account.Hash) {
			return fmt.Errorf("Invalid password (hashes don't match)")
		}
		ret = &acc
		return nil
	})
	return ret, err
}
<commit_msg>Return proper error on a not found account.<commit_after>package storage

import (
	"bytes"
	"time"

	"encoding/json"

	"fmt"

	"strconv"

	"os"

	"github.com/boltdb/bolt"
	"github.com/pinfake/pes6go/data/block"
)

type Bolt struct {
	db *bolt.DB
}

func uint32ToBytes(data uint32) []byte {
	return []byte(strconv.Itoa(int(data)))
}

func NewBolt() (*Bolt, error) {
	_ = os.Mkdir("./db", 0700)
	db, err := bolt.Open("./db/pes6godb.bolt", 0600, nil)
	if err != nil {
		return nil, err
	}
	db.Update(func(tx *bolt.Tx) error {
		tx.CreateBucketIfNotExists([]byte("accounts"))
		tx.CreateBucketIfNotExists([]byte("players"))
		return nil
	})

	return &Bolt{
		db: db,
	}, nil
}

func (b Bolt) CreateAccount(account *Account) (uint32, error) {
	err := b.db.Update(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte("accounts"))
		v := bucket.Get([]byte(account.Key))
		if v != nil {
			return fmt.Errorf("Account %s exists", account.Key)
		}
		id, _ := bucket.NextSequence()
		account.Id = uint32(id)
		buf, err := json.Marshal(account)
		if err != nil {
			return err
		}
		err = bucket.Put([]byte(account.Key), buf)
		return err
	})
	return account.Id, err
}

func (b Bolt) CreatePlayer(account *Account, position byte, player *block.Player) (uint32, error) {
	err := b.db.Update(func(tx *bolt.Tx) error {
		accBckt := tx.Bucket([]byte("accounts"))
		plyBckt := tx.Bucket([]byte("players"))
		id, _ := plyBckt.NextSequence()
		player.Id = uint32(id)
		buf, err := json.Marshal(player)
		if err != nil {
			return err
		}
		err = plyBckt.Put(uint32ToBytes(player.Id), buf)
		if err != nil {
			return err
		} else {
			account.Players[position] = player.Id
			buf, err := json.Marshal(account)
			if err != nil {
				return err
			}
			err = accBckt.Put([]byte(account.Key), buf)
			return err
		}
	})
	return player.Id, err
}

func (b Bolt) GetLobbies(serverId uint32) []*block.Lobby {
	switch serverId {
	case 1:
		return []*block.Lobby{
			{Type: 63, Name: "Lobby 1 Kenobi"},
			{Type: 63, Name: "Lobby 2 testá3"},
			{Type: 63, Name: "Lobby 3 testñ3"},
		}
	case 2:
		return []*block.Lobby{
			{Type: 0x1f},
		}
	default:
		return nil
	}
}

func (b Bolt) GetPlayer(id uint32) (*block.Player, error) {
	var player *block.Player
	err := b.db.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte("players"))
		v := bucket.Get(uint32ToBytes(id))
		if v == nil {
			return fmt.Errorf("Player with id %d not found", id)
		}
		player = &block.Player{}
		err := json.Unmarshal(v, player)
		if err != nil {
			return err
		}
		return nil
	})

	return player, err
}

func (b Bolt) GetServerNews() []block.News {
	return []block.News{
		{
			Time:  time.Date(2016, 1, 1, 12, 0, 0, 0, time.UTC),
			Title: "Mariano Speaks!",
			Text: "Es el vecino el que elige al alcalde y es el alcalde el que quiere " +
				"que sean los vecinos el alcalde",
		},
		{
			Time:  time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC),
			Title: "Mariano Keeps Speaking!",
			Text:  "No he dormido nada, no me pregunten demasiado si hacen el favor",
		},
	}
}

func (b Bolt) GetRankUrls() []block.RankUrl {
	return []block.RankUrl{
		{0, "http://pes6web.winning-eleven.net/pes6e2/ranking/we10getrank.html"},
		{1, "https://pes6web.winning-eleven.net/pes6e2/ranking/we10getgrprank.html"},
		{2, "http://pes6web.winning-eleven.net/pes6e2/ranking/we10RankingWeek.html"},
		{3, "https://pes6web.winning-eleven.net/pes6e2/ranking/we10GrpRankingWeek.html"},
		{4, "https://pes6web.winning-eleven.net/pes6e2/ranking/we10RankingCup.html"},
		{5, "http://www.pes6j.net/server/we10getgrpboard.html"},
		{6, "http://www.pes6j.net/server/we10getgrpinvitelist.html"},
	}
}

func (b Bolt) GetAccountPlayers(account *Account) ([3]*block.Player, error) {
	var players [3]*block.Player
	err := b.db.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte("players"))
		for i := range account.Players {
			v := bucket.Get(uint32ToBytes(account.Players[i]))
			var player block.Player
			if v == nil {
				player = block.Player{}
			} else {
				err := json.Unmarshal(v, &player)
				if err != nil {
					return err
				}
			}
			players[i] = &player
		}
		return nil
	})

	return players, err
}

func (b Bolt) GetGroupInfo(id uint32) block.GroupInfo {
	return block.GroupInfo{
		Time: time.Date(2016, 1, 1, 12, 0, 0, 0, time.UTC),
	}
}

func (b Bolt) GetPlayerSettings(id uint32) block.PlayerSettings {
	return block.PlayerSettings{
		Settings: DefaultPlayerSettings,
	}
}

func (b Bolt) Login(account *Account) (*Account, error) {
	var ret *Account
	err := b.db.View(func(tx *bolt.Tx) error {
		bucket := tx.Bucket([]byte("accounts"))
		v := bucket.Get([]byte(account.Key))
		if v == nil {
			return fmt.Errorf("Account key '%s' not found!", account.Key)
		}
		var acc Account
		err := json.Unmarshal(v, &acc)
		if err != nil {
			return err
		}
		if !bytes.Equal(acc.Hash, account.Hash) {
			return fmt.Errorf("Invalid password (hashes don't match)")
		}
		ret = &acc
		return nil
	})
	return ret, err
}
<|endoftext|>


<commit_before>package hybrid

import (
	"github.com/ready-steady/adapt/algorithm/internal"
)

// Strategy guides the interpolation process.
type strategy interface {
	// Start returns the initial order indices.
	Start() ([]uint64, []uint)

	// Check decides if the interpolation process should go on.
	Check() bool

	// Push takes into account a new interpolation element and its score.
	Push(*Element, []float64)

	// Move selects an active level index, searches admissible level indices in
	// the forward neighborhood of the selected level index, searches admissible
	// order indices with respect to each admissible level index, and returns
	// all the identified order indices.
	Move() ([]uint64, []uint)
}

type basicStrategy struct {
	internal.Active

	ni uint
	no uint

	grid Grid
	hash *internal.Hash
	link map[string]uint

	εt float64
	εl float64

	k uint

	global []float64
	local  []float64
}

func newStrategy(ni, no uint, grid Grid, config *Config) *basicStrategy {
	return &basicStrategy{
		Active: *internal.NewActive(ni, config.MaxLevel, config.MaxIndices),

		ni: ni,
		no: no,

		grid: grid,
		hash: internal.NewHash(ni),
		link: make(map[string]uint),

		εt: config.TotalError,
		εl: config.LocalError,

		k: ^uint(0),
	}
}

func (self *basicStrategy) Start() ([]uint64, []uint) {
	return internal.Index(self.grid, self.Active.Start(), self.ni)
}

func (self *basicStrategy) Check() bool {
	total := 0.0
	for i := range self.Positions {
		total += self.global[i]
	}
	return total > self.εt
}

func (self *basicStrategy) Push(element *Element, local []float64) {
	global := 0.0
	for i := range local {
		global += local[i]
	}
	self.global = append(self.global, global)
	self.local = append(self.local, local...)
}

func (self *basicStrategy) Move() ([]uint64, []uint) {
	self.Remove(self.k)
	self.k = internal.LocateMaxFloat64s(self.global, self.Positions)
	lindices := self.Active.Move(self.k)

	ni := self.ni
	nn := uint(len(lindices)) / ni

	indices, counts := []uint64(nil), make([]uint, nn)
	for i := uint(0); i < nn; i++ {
	}

	return indices, counts
}
<commit_msg>a/hybrid: a minor adjustment<commit_after>package hybrid

import (
	"github.com/ready-steady/adapt/algorithm/internal"
)

// Strategy guides the interpolation process.
type strategy interface {
	// Start returns the initial order indices.
	Start() ([]uint64, []uint)

	// Check decides if the interpolation process should go on.
	Check() bool

	// Push takes into account a new interpolation element and its score.
	Push(*Element, []float64)

	// Move selects an active level index, searches admissible level indices in
	// the forward neighborhood of the selected level index, searches admissible
	// order indices with respect to each admissible level index, and returns
	// all the identified order indices.
	Move() ([]uint64, []uint)
}

type basicStrategy struct {
	internal.Active

	ni uint
	no uint

	grid Grid

	hash *internal.Hash
	find map[string]uint

	εt float64
	εl float64

	k uint

	global []float64
	local  []float64
}

func newStrategy(ni, no uint, grid Grid, config *Config) *basicStrategy {
	return &basicStrategy{
		Active: *internal.NewActive(ni, config.MaxLevel, config.MaxIndices),

		ni: ni,
		no: no,

		grid: grid,

		hash: internal.NewHash(ni),
		find: make(map[string]uint),

		εt: config.TotalError,
		εl: config.LocalError,

		k: ^uint(0),
	}
}

func (self *basicStrategy) Start() ([]uint64, []uint) {
	return internal.Index(self.grid, self.Active.Start(), self.ni)
}

func (self *basicStrategy) Check() bool {
	total := 0.0
	for i := range self.Positions {
		total += self.global[i]
	}
	return total > self.εt
}

func (self *basicStrategy) Push(element *Element, local []float64) {
	ni, ne := self.ni, uint(len(self.local))
	nn := uint(len(element.Indices)) / self.ni

	global := 0.0
	for i := uint(0); i < nn; i++ {
		global += local[i]
		self.find[self.hash.Key(element.Indices[i*ni:(i+1)*ni])] = ne + i
	}

	self.global = append(self.global, global)
	self.local = append(self.local, local...)
}

func (self *basicStrategy) Move() ([]uint64, []uint) {
	self.Remove(self.k)
	self.k = internal.LocateMaxFloat64s(self.global, self.Positions)
	lindices := self.Active.Move(self.k)

	ni := self.ni
	nn := uint(len(lindices)) / ni

	indices, counts := []uint64(nil), make([]uint, nn)
	for i := uint(0); i < nn; i++ {
		lindex := lindices[i*ni : (i+1)*ni]
		for j := uint(0); j < ni; j++ {
			l := lindex[j]
			if l == 0 {
				continue
			}
			lindex[j] = l - 1
			_, ok := self.find[self.hash.Key(lindex)]
			lindex[j] = l
			if !ok {
				continue
			}
		}
	}

	return indices, counts
}
<|endoftext|>


<commit_before><commit_msg>stack: increase performance<commit_after><|endoftext|>


<commit_before>// Copyright 2015 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package datastore

import (
	"fmt"
	"reflect"

	"go.chromium.org/luci/common/errors"

	"google.golang.org/appengine/datastore"
)

type stopErr struct{}

func (stopErr) Error() string { return "stop iteration" }

// These errors are returned by various datastore.Interface methods.
var (
	ErrNoSuchEntity          = datastore.ErrNoSuchEntity
	ErrConcurrentTransaction = datastore.ErrConcurrentTransaction

	// Stop is understood by various services to stop iterative processes. Examples
	// include datastore.Interface.Run's callback.
	Stop = stopErr{}
)

// MakeErrInvalidKey returns an errors.Annotator instance that wraps an invalid
// key error. Calling IsErrInvalidKey on this Annotator or its derivatives will
// return true.
func MakeErrInvalidKey(reason string, args ...interface{}) *errors.Annotator {
	return errors.Annotate(datastore.ErrInvalidKey, reason, args...)
}

// IsErrInvalidKey tests if a given error is a wrapped datastore.ErrInvalidKey
// error.
func IsErrInvalidKey(err error) bool { return errors.Unwrap(err) == datastore.ErrInvalidKey }

// IsErrNoSuchEntity tests if an error is ErrNoSuchEntity,
// or is a MultiError that contains ErrNoSuchEntity and no other errors.
func IsErrNoSuchEntity(err error) (found bool) {
	errors.Walk(err, func(err error) bool {
		found = err == ErrNoSuchEntity
		// If we found an ErrNoSuchEntity, continue walking.
		// If we found a different type of error, signal Walk to stop walking by returning false.
		// Walk does not walk nil errors.
		return found
	})
	return
}

// ErrFieldMismatch is returned when a field is to be loaded into a different
// type than the one it was stored from, or when a field is missing or
// unexported in the destination struct.
// StructType is the type of the struct pointed to by the destination argument
// passed to Get or to Iterator.Next.
type ErrFieldMismatch struct {
	StructType reflect.Type
	FieldName  string
	Reason     string
}

func (e *ErrFieldMismatch) Error() string {
	return fmt.Sprintf("gae: cannot load field %q into a %q: %s",
		e.FieldName, e.StructType, e.Reason)
}
<commit_msg>[datastore] Use errors.WalkLeaves() for IsNoSuchEntity()<commit_after>// Copyright 2015 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package datastore

import (
	"fmt"
	"reflect"

	"go.chromium.org/luci/common/errors"

	"google.golang.org/appengine/datastore"
)

type stopErr struct{}

func (stopErr) Error() string { return "stop iteration" }

// These errors are returned by various datastore.Interface methods.
var (
	ErrNoSuchEntity          = datastore.ErrNoSuchEntity
	ErrConcurrentTransaction = datastore.ErrConcurrentTransaction

	// Stop is understood by various services to stop iterative processes. Examples
	// include datastore.Interface.Run's callback.
	Stop = stopErr{}
)

// MakeErrInvalidKey returns an errors.Annotator instance that wraps an invalid
// key error. Calling IsErrInvalidKey on this Annotator or its derivatives will
// return true.
func MakeErrInvalidKey(reason string, args ...interface{}) *errors.Annotator {
	return errors.Annotate(datastore.ErrInvalidKey, reason, args...)
}

// IsErrInvalidKey tests if a given error is a wrapped datastore.ErrInvalidKey
// error.
func IsErrInvalidKey(err error) bool { return errors.Unwrap(err) == datastore.ErrInvalidKey }

// IsErrNoSuchEntity tests if an error is ErrNoSuchEntity,
// or is a MultiError that contains ErrNoSuchEntity and no other errors.
func IsErrNoSuchEntity(err error) (found bool) {
	errors.WalkLeaves(err, func(ierr error) bool {
		found = ierr == ErrNoSuchEntity
		// If we found an ErrNoSuchEntity, continue walking.
		// If we found a different type of error, signal WalkLeaves to stop walking by returning false.
		// WalkLeaves does not walk nil errors nor wrapper errors.
		return found
	})
	return
}

// ErrFieldMismatch is returned when a field is to be loaded into a different
// type than the one it was stored from, or when a field is missing or
// unexported in the destination struct.
// StructType is the type of the struct pointed to by the destination argument
// passed to Get or to Iterator.Next.
type ErrFieldMismatch struct {
	StructType reflect.Type
	FieldName  string
	Reason     string
}

func (e *ErrFieldMismatch) Error() string {
	return fmt.Sprintf("gae: cannot load field %q into a %q: %s",
		e.FieldName, e.StructType, e.Reason)
}
<|endoftext|>


<commit_before>// Copyright © 2016 Thomas Rabaix <thomas.rabaix@gmail.com>.
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

package api

import (
	"fmt"
	"testing"

	"encoding/json"

	"github.com/rande/pkgmirror/api"
	"github.com/rande/pkgmirror/test"
	"github.com/stretchr/testify/assert"
)

func Test_Api_Ping(t *testing.T) {
	optin := &test.TestOptin{}

	test.RunHttpTest(t, optin, func(args *test.Arguments) {
		res, err := test.RunRequest("GET", fmt.Sprintf("%s/api/ping", args.TestServer.URL))

		assert.NoError(t, err)
		assert.Equal(t, 200, res.StatusCode)
		assert.Equal(t, []byte("pong"), res.GetBody())
	})
}

func Test_Api_List(t *testing.T) {
	optin := &test.TestOptin{true, true, true, true}

	test.RunHttpTest(t, optin, func(args *test.Arguments) {
		res, err := test.RunRequest("GET", fmt.Sprintf("%s/api/mirrors", args.TestServer.URL))

		assert.NoError(t, err)
		assert.Equal(t, 200, res.StatusCode)

		mirrors := []*api.ServiceMirror{}

		data := res.GetBody()

		err = json.Unmarshal(data, &mirrors)
		assert.NoError(t, err)

		assert.Equal(t, 4, len(mirrors))
	})
}
<commit_msg>feat(ci): disable unstable test due to invalid timeout<commit_after>// Copyright © 2016 Thomas Rabaix <thomas.rabaix@gmail.com>.
//
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

package api

import (
	"fmt"
	"testing"
	//"encoding/json"

	//"github.com/rande/pkgmirror/api"
	"github.com/rande/pkgmirror/test"
	"github.com/stretchr/testify/assert"
)

func Test_Api_Ping(t *testing.T) {
	optin := &test.TestOptin{}

	test.RunHttpTest(t, optin, func(args *test.Arguments) {
		res, err := test.RunRequest("GET", fmt.Sprintf("%s/api/ping", args.TestServer.URL))

		assert.NoError(t, err)
		assert.Equal(t, 200, res.StatusCode)
		assert.Equal(t, []byte("pong"), res.GetBody())
	})
}

//func Test_Api_List(t *testing.T) {
//	optin := &test.TestOptin{true, true, true, true}
//
//	test.RunHttpTest(t, optin, func(args *test.Arguments) {
//		res, err := test.RunRequest("GET", fmt.Sprintf("%s/api/mirrors", args.TestServer.URL))
//
//		assert.NoError(t, err)
//		assert.Equal(t, 200, res.StatusCode)
//
//		mirrors := []*api.ServiceMirror{}
//
//		data := res.GetBody()
//
//		err = json.Unmarshal(data, &mirrors)
//		assert.NoError(t, err)
//
//		assert.Equal(t, 4, len(mirrors))
//	})
//}
<|endoftext|>


<commit_before><commit_msg>handle link grabbing for each series in parallel while also checking multiple seasons for new episodes<commit_after><|endoftext|>


<commit_before>package getjoblessbuild_test

import (
	"errors"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/concourse/atc"
	. "github.com/concourse/atc/web/getjoblessbuild"
	cfakes "github.com/concourse/go-concourse/concourse/fakes"
)

var _ = Describe("Handler", func() {
	FDescribe("creating the Template Data", func() {
		var (
			fakeClient   *cfakes.FakeClient
			fetchErr     error
			templateData TemplateData
		)

		BeforeEach(func() {
			fakeClient = new(cfakes.FakeClient)
		})

		JustBeforeEach(func() {
			templateData, fetchErr = FetchTemplateData("3", fakeClient)
		})

		It("uses the client to get the build", func() {
			Expect(fakeClient.BuildCallCount()).To(Equal(1))
			Expect(fakeClient.BuildArgsForCall(0)).To(Equal("3"))
		})

		Context("when the client returns an error", func() {
			var expectedError error

			BeforeEach(func() {
				expectedError = errors.New("NOOOOOOO")
				fakeClient.BuildReturns(atc.Build{}, false, expectedError)
			})

			It("returns the error", func() {
				Expect(fetchErr).To(HaveOccurred())
				Expect(fetchErr).To(Equal(expectedError))
			})
		})

		Context("when the client returns not found", func() {
			BeforeEach(func() {
				fakeClient.BuildReturns(atc.Build{}, false, nil)
			})

			It("returns the error", func() {
				Expect(fetchErr).To(HaveOccurred())
				Expect(fetchErr).To(Equal(ErrBuildNotFound))
			})
		})

		Context("when the client returns a build", func() {
			var expectedBuild atc.Build

			BeforeEach(func() {
				expectedBuild = atc.Build{
					ID: 2,
				}
				fakeClient.BuildReturns(expectedBuild, true, nil)
			})

			It("returns the build in the template data", func() {
				Expect(templateData.Build).To(Equal(expectedBuild))
			})
		})
	})
})
<commit_msg>remove focus<commit_after>package getjoblessbuild_test

import (
	"errors"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/concourse/atc"
	. "github.com/concourse/atc/web/getjoblessbuild"
	cfakes "github.com/concourse/go-concourse/concourse/fakes"
)

var _ = Describe("Handler", func() {
	Describe("creating the Template Data", func() {
		var (
			fakeClient   *cfakes.FakeClient
			fetchErr     error
			templateData TemplateData
		)

		BeforeEach(func() {
			fakeClient = new(cfakes.FakeClient)
		})

		JustBeforeEach(func() {
			templateData, fetchErr = FetchTemplateData("3", fakeClient)
		})

		It("uses the client to get the build", func() {
			Expect(fakeClient.BuildCallCount()).To(Equal(1))
			Expect(fakeClient.BuildArgsForCall(0)).To(Equal("3"))
		})

		Context("when the client returns an error", func() {
			var expectedError error

			BeforeEach(func() {
				expectedError = errors.New("NOOOOOOO")
				fakeClient.BuildReturns(atc.Build{}, false, expectedError)
			})

			It("returns the error", func() {
				Expect(fetchErr).To(HaveOccurred())
				Expect(fetchErr).To(Equal(expectedError))
			})
		})

		Context("when the client returns not found", func() {
			BeforeEach(func() {
				fakeClient.BuildReturns(atc.Build{}, false, nil)
			})

			It("returns the error", func() {
				Expect(fetchErr).To(HaveOccurred())
				Expect(fetchErr).To(Equal(ErrBuildNotFound))
			})
		})

		Context("when the client returns a build", func() {
			var expectedBuild atc.Build

			BeforeEach(func() {
				expectedBuild = atc.Build{
					ID: 2,
				}
				fakeClient.BuildReturns(expectedBuild, true, nil)
			})

			It("returns the build in the template data", func() {
				Expect(templateData.Build).To(Equal(expectedBuild))
			})
		})
	})
})
<|endoftext|>


<commit_before>/* Copyright (c) 2016 PaddlePaddle Authors All Rights Reserve.

   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. */

// sample resource:
/*
apiVersion: paddlepaddle.org/v1
kind: TrainingJob
metadata:
	name: job-1
spec:
	trainer:
		entrypoint: "python train.py"
		workspace: "/home/job-1/"
		min-instance: 3
		max-instance: 6
		resources:
			limits:
				alpha.kubernetes.io/nvidia-gpu: 1
				cpu: "800m"
				memory: "1Gi"
			requests:
				cpu: "500m"
				memory: "600Mi"
	pserver:
		min-instance: 3
		max-instance: 3
		resources:
			limits:
				cpu: "800m"
				memory: "1Gi"
			requests:
				cpu: "500m"
				memory: "600Mi"
	master:
		resources:
			limits:
				cpu: "800m"
				memory: "1Gi"
			requests:
				cpu: "500m"
				memory: "600Mi"
*/

package resource

import (
	"encoding/json"

	"k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/runtime/serializer"
	clientgoapi "k8s.io/client-go/kubernetes/scheme"
	"k8s.io/client-go/rest"
)

// TrainingJobs string for registration
const TrainingJobs = "TrainingJobs"

// TrainingJob defination
// +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type TrainingJob struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata"`
	Spec              TrainingJobSpec   `json:"spec"`
	Status            TrainingJobStatus `json:"status,omitempty"`
}

// TrainingJobSpec defination
// +k8s:deepcopy-gen=true
type TrainingJobSpec struct {
	// General job attributes.
	Image             string           `json:"image,omitempty"`
	Port              int              `json:"port,omitempty"`
	PortsNum          int              `json:"ports_num,omitempty"`
	PortsNumForSparse int              `json:"ports_num_for_sparse,omitempty"`
	FaultTolerant     bool             `json:"fault_tolerant,omitempty"`
	Passes            int              `json:"passes,omitempty"`
	Volumes           []v1.Volume      `json:"volumes"`
	VolumeMounts      []v1.VolumeMount `json:"VolumeMounts"`
	// Job components.
	Trainer TrainerSpec `json:"trainer"`
	Pserver PserverSpec `json:"pserver"`
	Master  MasterSpec  `json:"master,omitempty"`
}

// TrainerSpec defination
// +k8s:deepcopy-gen=true
type TrainerSpec struct {
	Entrypoint  string                  `json:"entrypoint"`
	Workspace   string                  `json:"workspace"`
	MinInstance int                     `json:"min-instance"`
	MaxInstance int                     `json:"max-instance"`
	Resources   v1.ResourceRequirements `json:"resources"`
}

// PserverSpec defination
// +k8s:deepcopy-gen=true
type PserverSpec struct {
	MinInstance int                     `json:"min-instance"`
	MaxInstance int                     `json:"max-instance"`
	Resources   v1.ResourceRequirements `json:"resources"`
}

// MasterSpec defination
// +k8s:deepcopy-gen=true
type MasterSpec struct {
	EtcdEndpoint string                  `json:"etcd-endpoint"`
	Resources    v1.ResourceRequirements `json:"resources"`
}

// TrainingJobStatus defination
// +k8s:deepcopy-gen=true
type TrainingJobStatus struct {
	State   TrainingJobState `json:"state,omitempty"`
	Message string           `json:"message,omitempty"`
}

// TrainingJobState defination
type TrainingJobState string

// TrainingJobState consts
const (
	StateCreated TrainingJobState = "Created"
	StateRunning TrainingJobState = "Running"
	StateFailed  TrainingJobState = "Failed"
	StateSucceed TrainingJobState = "Succeed"
)

// TrainingJobList defination
// +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type TrainingJobList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata"`
	Items           []TrainingJob `json:"items"`
}

// NeedGPU returns true if the job need GPU resource to run.
func (s *TrainingJob) NeedGPU() bool {
	q := s.Spec.Trainer.Resources.Limits.NvidiaGPU()
	return q.CmpInt64(0) == 1
}

// Elastic returns true if the job can scale to more workers.
func (s *TrainingJob) Elastic() bool {
	return s.Spec.Trainer.MinInstance < s.Spec.Trainer.MaxInstance
}

// GPU convert Resource Limit Quantity to int
func (s *TrainingJob) GPU() int {
	q := s.Spec.Trainer.Resources.Limits.NvidiaGPU()
	gpu, ok := q.AsInt64()
	if !ok {
		// FIXME: treat errors
		gpu = 0
	}

	return int(gpu)
}

func (s *TrainingJob) String() string {
	b, _ := json.MarshalIndent(s, "", "   ")
	return string(b[:])
}

// RegisterResource registers a resource type and the corresponding
// resource list type to the local Kubernetes runtime under group
// version "paddlepaddle.org", so the runtime could encode/decode this
// Go type.  It also change config.GroupVersion to "paddlepaddle.org".
func RegisterResource(config *rest.Config, resourceType, resourceListType runtime.Object) *rest.Config {
	groupversion := schema.GroupVersion{
		Group:   "paddlepaddle.org",
		Version: "v1",
	}

	config.GroupVersion = &groupversion
	config.APIPath = "/apis"
	config.ContentType = runtime.ContentTypeJSON
	config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: clientgoapi.Codecs}

	clientgoapi.Scheme.AddKnownTypes(
		groupversion,
		resourceType,
		resourceListType,
		&v1.ListOptions{},
		&v1.DeleteOptions{},
	)

	return config
}
<commit_msg>Commenting training_job.go<commit_after>/* Copyright (c) 2016 PaddlePaddle Authors All Rights Reserve.

   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 resource

import (
	"encoding/json"

	"k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/runtime/serializer"
	clientgoapi "k8s.io/client-go/kubernetes/scheme"
	"k8s.io/client-go/rest"
)

// TrainingJobs string for registration
const TrainingJobs = "TrainingJobs"

// TrainingJob is a Kubernetes resource type defined by EDL.  It
// describes a PaddlePaddle training job.  As a Kubernetes resource,
//
//  - Its content must follow the Kubernetes resource definition convention.
//  - It must be a Go struct with JSON tags.
//  - It must implement the deepcopy interface.
//
// An example TrainingJob instance:
/*
apiVersion: paddlepaddle.org/v1
kind: TrainingJob
metadata:
	name: job-1
spec:
	trainer:
		entrypoint: "python train.py"
		workspace: "/home/job-1/"
		min-instance: 3
		max-instance: 6
		resources:
			limits:
				alpha.kubernetes.io/nvidia-gpu: 1
				cpu: "800m"
				memory: "1Gi"
			requests:
				cpu: "500m"
				memory: "600Mi"
	pserver:
		min-instance: 3
		max-instance: 3
		resources:
			limits:
				cpu: "800m"
				memory: "1Gi"
			requests:
				cpu: "500m"
				memory: "600Mi"
	master:
		resources:
			limits:
				cpu: "800m"
				memory: "1Gi"
			requests:
				cpu: "500m"
				memory: "600Mi"
*/
// +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type TrainingJob struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata"`
	Spec              TrainingJobSpec   `json:"spec"`
	Status            TrainingJobStatus `json:"status,omitempty"`
}

// TrainingJobSpec defination
// +k8s:deepcopy-gen=true
type TrainingJobSpec struct {
	// General job attributes.
	Image             string           `json:"image,omitempty"`
	Port              int              `json:"port,omitempty"`
	PortsNum          int              `json:"ports_num,omitempty"`
	PortsNumForSparse int              `json:"ports_num_for_sparse,omitempty"`
	FaultTolerant     bool             `json:"fault_tolerant,omitempty"`
	Passes            int              `json:"passes,omitempty"`
	Volumes           []v1.Volume      `json:"volumes"`
	VolumeMounts      []v1.VolumeMount `json:"VolumeMounts"`
	// Job components.
	Trainer TrainerSpec `json:"trainer"`
	Pserver PserverSpec `json:"pserver"`
	Master  MasterSpec  `json:"master,omitempty"`
}

// TrainerSpec defination
// +k8s:deepcopy-gen=true
type TrainerSpec struct {
	Entrypoint  string                  `json:"entrypoint"`
	Workspace   string                  `json:"workspace"`
	MinInstance int                     `json:"min-instance"`
	MaxInstance int                     `json:"max-instance"`
	Resources   v1.ResourceRequirements `json:"resources"`
}

// PserverSpec defination
// +k8s:deepcopy-gen=true
type PserverSpec struct {
	MinInstance int                     `json:"min-instance"`
	MaxInstance int                     `json:"max-instance"`
	Resources   v1.ResourceRequirements `json:"resources"`
}

// MasterSpec defination
// +k8s:deepcopy-gen=true
type MasterSpec struct {
	EtcdEndpoint string                  `json:"etcd-endpoint"`
	Resources    v1.ResourceRequirements `json:"resources"`
}

// TrainingJobStatus defination
// +k8s:deepcopy-gen=true
type TrainingJobStatus struct {
	State   TrainingJobState `json:"state,omitempty"`
	Message string           `json:"message,omitempty"`
}

// TrainingJobState defination
type TrainingJobState string

// TrainingJobState consts
const (
	StateCreated TrainingJobState = "Created"
	StateRunning TrainingJobState = "Running"
	StateFailed  TrainingJobState = "Failed"
	StateSucceed TrainingJobState = "Succeed"
)

// TrainingJobList defination
// +k8s:deepcopy-gen=true
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type TrainingJobList struct {
	metav1.TypeMeta `json:",inline"`
	metav1.ListMeta `json:"metadata"`
	Items           []TrainingJob `json:"items"`
}

// Elastic returns true if the job can scale to more workers.
func (s *TrainingJob) Elastic() bool {
	return s.Spec.Trainer.MinInstance < s.Spec.Trainer.MaxInstance
}

// GPU convert Resource Limit Quantity to int
func (s *TrainingJob) GPU() int {
	q := s.Spec.Trainer.Resources.Limits.NvidiaGPU()
	gpu, ok := q.AsInt64()
	if !ok {
		// FIXME: treat errors
		gpu = 0
	}
	return int(gpu)
}

// NeedGPU returns true if the job need GPU resource to run.
func (s *TrainingJob) NeedGPU() bool {
	return s.GPU() > 0
}

func (s *TrainingJob) String() string {
	b, _ := json.MarshalIndent(s, "", "   ")
	return string(b[:])
}

// RegisterResource registers a resource type and the corresponding
// resource list type to the local Kubernetes runtime under group
// version "paddlepaddle.org", so the runtime could encode/decode this
// Go type.  It also change config.GroupVersion to "paddlepaddle.org".
func RegisterResource(config *rest.Config, resourceType, resourceListType runtime.Object) *rest.Config {
	groupversion := schema.GroupVersion{
		Group:   "paddlepaddle.org",
		Version: "v1",
	}

	config.GroupVersion = &groupversion
	config.APIPath = "/apis"
	config.ContentType = runtime.ContentTypeJSON
	config.NegotiatedSerializer = serializer.DirectCodecFactory{CodecFactory: clientgoapi.Codecs}

	clientgoapi.Scheme.AddKnownTypes(
		groupversion,
		resourceType,
		resourceListType,
		&v1.ListOptions{},
		&v1.DeleteOptions{},
	)

	return config
}
<|endoftext|>


<commit_before>package oskite

import (
	"fmt"
	"io/ioutil"
	"koding/virt"
	"strings"
	"time"

	"gopkg.in/fatih/set.v0"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

type VmCollection map[bson.ObjectId]*virt.VM

// mongodbVMs returns a map of VMs that are bind to the given
// serviceUniquename/hostkite in mongodb
func mongodbVMs(serviceUniquename string) (VmCollection, error) {
	vms := make([]*virt.VM, 0)

	query := func(c *mgo.Collection) error {
		return c.Find(bson.M{"hostKite": serviceUniquename}).All(&vms)
	}

	if err := mongodbConn.Run("jVMs", query); err != nil {
		return nil, fmt.Errorf("allVMs fetching err: %s", err.Error())
	}

	vmsMap := make(map[bson.ObjectId]*virt.VM, len(vms))

	for _, vm := range vms {
		vmsMap[vm.Id] = vm
	}

	return vmsMap, nil
}

// Ids returns a set of VM ids
func (v VmCollection) Ids() set.Interface {
	ids := set.NewNonTS()

	for id := range v {
		ids.Add(id)
	}

	return ids
}

// currentVMS returns a set of VM ids on the current host machine with their
// associated mongodb objectid's taken from the directory name
func currentVMs() (set.Interface, error) {
	dirs, err := ioutil.ReadDir("/var/lib/lxc")
	if err != nil {
		return nil, fmt.Errorf("vmsList err %s", err)
	}

	vms := set.NewNonTS()
	for _, dir := range dirs {
		if !strings.HasPrefix(dir.Name(), "vm-") {
			continue
		}

		vmId := bson.ObjectIdHex(dir.Name()[3:])
		vms.Add(vmId)
	}

	return vms, nil
}

// vmUpdater updates the states of current available VMs on the host machine.
func (o *Oskite) vmUpdater() {
	for _ = range time.Tick(time.Second * 10) {
		currentIds, err := currentVMs()
		if err != nil {
			log.Error("vm updater getting current vms err %v", err)
			continue
		}

		vms, err := mongodbVMs(o.ServiceUniquename)
		if err != nil {
			log.Error("vm updater mongoDBVms failed err %v", err)
		}

		combined := set.Intersection(currentIds, vms.Ids())

		combined.Each(func(item interface{}) bool {
			vmId, ok := item.(bson.ObjectId)
			if !ok {
				return true
			}

			if vm, ok := vms[vmId]; ok {
				o.startAlwaysOn(vm)
			}

			err := updateState(vmId)
			if err == nil {
				return true
			}

			log.Error("vm updater %s err %v", vmId, err)
			if err != mgo.ErrNotFound {
				return true
			}

			// the VM couldn't be find in mongoDB, this is a leftover VM that
			// needs to be unprepared
			log.Error("vm updater vm not found %s err %v", vmId, err)
			unprepareLeftover(vmId)

			return true
		})
	}
}

// startAlwaysOn  starts a vm if it's alwaysOn and not pinned to the current
// hostname
func (o *Oskite) startAlwaysOn(vm *virt.VM) {
	if !vm.AlwaysOn {
		return
	}

	// means this vm is intended to be start on another kontainer machine
	if vm.PinnedToHost != "" && vm.PinnedToHost != o.ServiceUniquename {
		return
	}

	log.Info("starting alwaysOn VM %s [%s]", vm.HostnameAlias, vm.Id.Hex())
	go o.startSingleVM(vm, nil)
}

func unprepareLeftover(vmId bson.ObjectId) {
	prepareQueue <- &QueueJob{
		msg: fmt.Sprintf("unprepare leftover vm %s", vmId.Hex()),
		f: func() error {
			mockVM := &virt.VM{Id: vmId}
			if err := mockVM.Unprepare(nil, false); err != nil {
				log.Error("leftover unprepare: %v", err)
			}

			if err := updateState(vmId); err != nil {
				log.Error("%v", err)
			}

			return nil
		},
	}
}
<commit_msg>oskite: do not start alwaysOn VMs if if fails<commit_after>package oskite

import (
	"fmt"
	"io/ioutil"
	"koding/virt"
	"strings"
	"time"

	"gopkg.in/fatih/set.v0"
	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

type VmCollection map[bson.ObjectId]*virt.VM

var blacklist = set.New()

// mongodbVMs returns a map of VMs that are bind to the given
// serviceUniquename/hostkite in mongodb
func mongodbVMs(serviceUniquename string) (VmCollection, error) {
	vms := make([]*virt.VM, 0)

	query := func(c *mgo.Collection) error {
		return c.Find(bson.M{"hostKite": serviceUniquename}).All(&vms)
	}

	if err := mongodbConn.Run("jVMs", query); err != nil {
		return nil, fmt.Errorf("allVMs fetching err: %s", err.Error())
	}

	vmsMap := make(map[bson.ObjectId]*virt.VM, len(vms))

	for _, vm := range vms {
		vmsMap[vm.Id] = vm
	}

	return vmsMap, nil
}

// Ids returns a set of VM ids
func (v VmCollection) Ids() set.Interface {
	ids := set.NewNonTS()

	for id := range v {
		ids.Add(id)
	}

	return ids
}

// currentVMS returns a set of VM ids on the current host machine with their
// associated mongodb objectid's taken from the directory name
func currentVMs() (set.Interface, error) {
	dirs, err := ioutil.ReadDir("/var/lib/lxc")
	if err != nil {
		return nil, fmt.Errorf("vmsList err %s", err)
	}

	vms := set.NewNonTS()
	for _, dir := range dirs {
		if !strings.HasPrefix(dir.Name(), "vm-") {
			continue
		}

		vmId := bson.ObjectIdHex(dir.Name()[3:])
		vms.Add(vmId)
	}

	return vms, nil
}

// vmUpdater updates the states of current available VMs on the host machine.
func (o *Oskite) vmUpdater() {
	for _ = range time.Tick(time.Second * 10) {
		currentIds, err := currentVMs()
		if err != nil {
			log.Error("vm updater getting current vms err %v", err)
			continue
		}

		vms, err := mongodbVMs(o.ServiceUniquename)
		if err != nil {
			log.Error("vm updater mongoDBVms failed err %v", err)
		}

		combined := set.Intersection(currentIds, vms.Ids())

		combined.Each(func(item interface{}) bool {
			vmId, ok := item.(bson.ObjectId)
			if !ok {
				return true
			}

			if vm, ok := vms[vmId]; ok && !blacklist.Has(vmId) {
				o.startAlwaysOn(vm)
			}

			err := updateState(vmId)
			if err == nil {
				return true
			}

			log.Error("vm updater %s err %v", vmId, err)
			if err != mgo.ErrNotFound {
				return true
			}

			// the VM couldn't be find in mongoDB, this is a leftover VM that
			// needs to be unprepared
			log.Error("vm updater vm not found %s err %v", vmId, err)
			unprepareLeftover(vmId)

			return true
		})
	}
}

// startAlwaysOn  starts a vm if it's alwaysOn and not pinned to the current
// hostname
func (o *Oskite) startAlwaysOn(vm *virt.VM) {
	if !vm.AlwaysOn {
		return
	}

	// means this vm is intended to be start on another kontainer machine
	if vm.PinnedToHost != "" && vm.PinnedToHost != o.ServiceUniquename {
		return
	}

	go func() {
		err := o.startSingleVM(vm, nil)
		if err == nil {
			return
		}

		if blacklist.Has(vm.Id) {
			return
		}

		log.Error("alwaysOn vm %s - %s  couldn't be started, adding to blacklist for one hour. err %s",
			vm.HostnameAlias, vm.Id, err)

		blacklist.Add(vm.Id)
		time.AfterFunc(time.Hour, func() {
			blacklist.Remove(vm.Id)
		})
	}()
}

func unprepareLeftover(vmId bson.ObjectId) {
	prepareQueue <- &QueueJob{
		msg: fmt.Sprintf("unprepare leftover vm %s", vmId.Hex()),
		f: func() error {
			mockVM := &virt.VM{Id: vmId}
			if err := mockVM.Unprepare(nil, false); err != nil {
				log.Error("leftover unprepare: %v", err)
			}

			if err := updateState(vmId); err != nil {
				log.Error("%v", err)
			}

			return nil
		},
	}
}
<|endoftext|>


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

// Package scopegraph defines methods for creating and interacting with the Scope Information Graph, which
// represents the determing scopes of all expressions and statements.
package scopegraph

import (
	"log"
	"strconv"

	"github.com/serulian/compiler/compilercommon"
	"github.com/serulian/compiler/compilergraph"
	"github.com/serulian/compiler/graphs/srg/typerefresolver"

	"github.com/serulian/compiler/graphs/scopegraph/proto"
	"github.com/serulian/compiler/graphs/srg"
	srgtc "github.com/serulian/compiler/graphs/srg/typeconstructor"
	"github.com/serulian/compiler/graphs/typegraph"
	"github.com/serulian/compiler/packageloader"
	"github.com/serulian/compiler/webidl"
	webidltc "github.com/serulian/compiler/webidl/typeconstructor"
)

// PromisingAccessType defines an enumeration of access types for the IsPromisingMember check.
type PromisingAccessType int

const (
	// PromisingAccessFunctionCall indicates that the expression is being invoked as a function
	// call and the function itself should be checked if promising.
	PromisingAccessFunctionCall PromisingAccessType = iota

	// PromisingAccessImplicitGet indicates the expression is calling a property via an implicit
	// get and the property's getter should be checked.
	PromisingAccessImplicitGet

	// PromisingAccessImplicitSet indicates the expression is calling a property via an implicit
	// set and the property's setter should be checked.
	PromisingAccessImplicitSet

	// PromisingAccessInitializer indicates that the initializer of a variable is being accessed
	// and should be checked.
	PromisingAccessInitializer
)

// ScopeGraph represents the ScopeGraph layer and all its associated helper methods.
type ScopeGraph struct {
	srg           *srg.SRG                     // The SRG behind this scope graph.
	tdg           *typegraph.TypeGraph         // The TDG behind this scope graph.
	irg           *webidl.WebIRG               // The IRG for WebIDL behind this scope graph.
	packageLoader *packageloader.PackageLoader // The package loader behind this scope graph.
	graph         *compilergraph.SerulianGraph // The root graph.

	srgRefResolver        *typerefresolver.TypeReferenceResolver // The resolver to use for SRG type refs.
	dynamicPromisingNames map[string]bool

	layer *compilergraph.GraphLayer // The ScopeGraph layer in the graph.
}

// Result represents the results of building a scope graph.
type Result struct {
	Status   bool                           // Whether the construction succeeded.
	Warnings []compilercommon.SourceWarning // Any warnings encountered during construction.
	Errors   []compilercommon.SourceError   // Any errors encountered during construction.
	Graph    *ScopeGraph                    // The constructed scope graph.
}

// BuildTarget defines the target of the scoping being performed.
type BuildTarget string

const (
	// Compilation indicates the scope graph is being built for compilation of code
	// and therefore should not process the remaining phases if any errors occur.
	Compilation BuildTarget = "compilation"

	// Tooling indicates the scope graph is being built for IDE or other forms of tooling,
	// and that a partially valid graph should be returned.
	Tooling BuildTarget = "tooling"
)

// Config defines the configuration for scoping.
type Config struct {
	// RootSourceFilePath is the root source file path from which to begin scoping.
	RootSourceFilePath string

	// VCSDevelopmentDirectories are the paths to the development directories, if any, that
	// override VCS imports.
	VCSDevelopmentDirectories []string

	// Libraries defines the libraries, if any, to import along with the root source file.
	Libraries []packageloader.Library

	// Target defines the target of the scope building.
	Target BuildTarget

	// PathLoader defines the path loader to use when parsing.
	PathLoader packageloader.PathLoader
}

// ParseAndBuildScopeGraph conducts full parsing, type graph construction and scoping for the project
// starting at the given root source file.
func ParseAndBuildScopeGraph(rootSourceFilePath string, vcsDevelopmentDirectories []string, libraries ...packageloader.Library) Result {
	result, err := ParseAndBuildScopeGraphWithConfig(Config{
		RootSourceFilePath:        rootSourceFilePath,
		VCSDevelopmentDirectories: vcsDevelopmentDirectories,
		Libraries:                 libraries,
		Target:                    Compilation,
		PathLoader:                packageloader.LocalFilePathLoader{},
	})

	if err != nil {
		log.Fatalf("Could not build graph: %v", err)
	}

	return result
}

// ParseAndBuildScopeGraphWithConfig conducts full parsing, type graph construction and scoping for the project
// starting at the root source file specified in configuration. If an *internal error* occurs, it is
// returned as the `err`. Parsing and scoping errors are returned in the Result.
func ParseAndBuildScopeGraphWithConfig(config Config) (Result, error) {
	graph, err := compilergraph.NewGraph(config.RootSourceFilePath)
	if err != nil {
		return Result{}, err
	}

	// Create the SRG for the source and load it.
	sourcegraph := srg.NewSRG(graph)
	webidlgraph := webidl.NewIRG(graph)

	loader := packageloader.NewPackageLoader(packageloader.Config{
		RootSourceFilePath:        config.RootSourceFilePath,
		PathLoader:                config.PathLoader,
		VCSDevelopmentDirectories: config.VCSDevelopmentDirectories,
		AlwaysValidate:            config.Target == Tooling,

		SourceHandlers: []packageloader.SourceHandler{
			sourcegraph.PackageLoaderHandler(),
			webidlgraph.PackageLoaderHandler()},
	})

	loaderResult := loader.Load(config.Libraries...)
	if !loaderResult.Status && config.Target != Tooling {
		return Result{
			Status:   false,
			Errors:   loaderResult.Errors,
			Warnings: loaderResult.Warnings,
		}, nil
	}

	// Construct the type graph.
	resolver := typerefresolver.NewResolver(sourcegraph)
	srgConstructor := srgtc.GetConstructorWithResolver(sourcegraph, resolver)
	typeResult := typegraph.BuildTypeGraph(sourcegraph.Graph, webidltc.GetConstructor(webidlgraph), srgConstructor)
	if !typeResult.Status && config.Target != Tooling {
		return Result{
			Status:   false,
			Errors:   typeResult.Errors,
			Warnings: combineWarnings(loaderResult.Warnings, typeResult.Warnings),
		}, nil
	}

	// Freeze the resolver's cache.
	resolver.FreezeCache()

	// Construct the scope graph.
	scopeResult := buildScopeGraphWithResolver(sourcegraph, webidlgraph, typeResult.Graph, resolver, loader)
	return Result{
		Status:   scopeResult.Status && typeResult.Status && loaderResult.Status,
		Errors:   scopeResult.Errors,
		Warnings: combineWarnings(loaderResult.Warnings, typeResult.Warnings, scopeResult.Warnings),
		Graph:    scopeResult.Graph,
	}, nil
}

// SourceGraph returns the SRG behind this scope graph.
func (sg *ScopeGraph) SourceGraph() *srg.SRG {
	return sg.srg
}

// TypeGraph returns the type graph behind this scope graph.
func (sg *ScopeGraph) TypeGraph() *typegraph.TypeGraph {
	return sg.tdg
}

// PackageLoader returns the package loader behind this scope graph.
func (sg *ScopeGraph) PackageLoader() *packageloader.PackageLoader {
	return sg.packageLoader
}

// GetScope returns the scope for the given SRG node, if any.
func (sg *ScopeGraph) GetScope(srgNode compilergraph.GraphNode) (proto.ScopeInfo, bool) {
	scopeNode, found := sg.layer.
		StartQuery(srgNode.NodeId).
		In(NodePredicateSource).
		TryGetNode()

	if !found {
		return proto.ScopeInfo{}, false
	}

	scopeInfo := scopeNode.GetTagged(NodePredicateScopeInfo, &proto.ScopeInfo{}).(*proto.ScopeInfo)
	return *scopeInfo, true
}

// BuildTransientScope builds the scope for the given transient node, as scoped under the given parent node.
// Note that this method should *only* be used for transient nodes (i.e. expressions in something like Grok),
// and that the scope created will not be saved anywhere once this method returns.
func (sg *ScopeGraph) BuildTransientScope(transientNode compilergraph.GraphNode, parentImplementable srg.SRGImplementable) (proto.ScopeInfo, bool) {
	// TODO: maybe skip writing the scope to the graph layer?
	builder := newScopeBuilder(sg)
	defer builder.modifier.Close()

	// TODO: Change these types into interfaces and use no-op implementations here as performance
	// improvement.
	staticDependencyCollector := newStaticDependencyCollector()
	dynamicDependencyCollector := newDynamicDependencyCollector()

	context := scopeContext{
		parentImplemented:          parentImplementable.GraphNode,
		rootNode:                   parentImplementable.GraphNode,
		staticDependencyCollector:  staticDependencyCollector,
		dynamicDependencyCollector: dynamicDependencyCollector,
		rootLabelSet:               newLabelSet(),
	}

	scopeInfo := builder.getScope(transientNode, context)
	return *scopeInfo, builder.Status
}

// HasSecondaryLabel returns whether the given SRG node has a secondary scope label of the given kind.
func (sg *ScopeGraph) HasSecondaryLabel(srgNode compilergraph.GraphNode, label proto.ScopeLabel) bool {
	_, found := sg.layer.
		StartQuery(srgNode.NodeId).
		In(NodePredicateLabelSource).
		Has(NodePredicateSecondaryLabelValue, strconv.Itoa(int(label))).
		TryGetNode()

	return found
}

// ResolveSRGTypeRef builds an SRG type reference into a resolved type reference.
func (sg *ScopeGraph) ResolveSRGTypeRef(srgTypeRef srg.SRGTypeRef) (typegraph.TypeReference, error) {
	return sg.srgRefResolver.ResolveTypeRef(srgTypeRef, sg.tdg)
}

// IsPromisingMember returns whether the member, when accessed via the given access type, returns a promise.
func (sg *ScopeGraph) IsPromisingMember(member typegraph.TGMember, accessType PromisingAccessType) bool {
	// If this member is not implicitly called and we are asking for implicit access information, then
	// it cannot return a promise.
	if (accessType != PromisingAccessFunctionCall && accessType != PromisingAccessInitializer) && !member.IsImplicitlyCalled() {
		return false
	}

	// Switch based on the typegraph-defined promising metric. Most SRG-constructed members will be
	// "dynamic" (since they are not known to promise until after scoping runs), but some members will
	// be defined by the type system as either promising or not.
	switch member.IsPromising() {
	case typegraph.MemberNotPromising:
		return false

	case typegraph.MemberPromising:
		return true

	case typegraph.MemberPromisingDynamic:
		// If the type member is marked as dynamically promising, we need to either check the scopegraph
		// for the promising label or infer the promising for implicitly constructed members. First, we
		// find the associated SRG member (if any).
		sourceId, hasSourceNode := member.SourceNodeId()
		if !hasSourceNode {
			// This is a member constructed by the type system implicitly, so it needs to be inferred
			// here based on other metrics.
			return sg.inferMemberPromising(member)
		}

		// Find the associated SRG member.
		srgNode, hasSRGNode := sg.srg.TryGetNode(sourceId)
		if !hasSRGNode {
			panic("Missing SRG node on dynamically promising member")
		}

		// Based on access type, lookup the scoping label on the proper implementation.
		srgMember := sg.srg.GetMemberReference(srgNode)

		// If the member is an interface,  check its name.
		if !srgMember.HasImplementation() {
			_, exists := sg.dynamicPromisingNames[member.Name()]
			return exists
		}

		implNode := srgMember.GraphNode

		switch accessType {
		case PromisingAccessInitializer:
			fallthrough

		case PromisingAccessFunctionCall:
			implNode = srgMember.GraphNode // The member itself

		case PromisingAccessImplicitGet:
			getter, hasGetter := srgMember.Getter()
			if !hasGetter {
				return false
			}

			implNode = getter.GraphNode

		case PromisingAccessImplicitSet:
			setter, hasSetter := srgMember.Setter()
			if !hasSetter {
				return false
			}

			implNode = setter.GraphNode
		}

		// Check the SRG for the scope label on the implementation node, if any.
		return !sg.HasSecondaryLabel(implNode, proto.ScopeLabel_SML_PROMISING_NO)

	default:
		panic("Missing promising case")
	}
}
<commit_msg>Have scopegraph use new VCS caching option if used for tooling<commit_after>// Copyright 2015 The Serulian Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package scopegraph defines methods for creating and interacting with the Scope Information Graph, which
// represents the determing scopes of all expressions and statements.
package scopegraph

import (
	"log"
	"strconv"

	"github.com/serulian/compiler/compilercommon"
	"github.com/serulian/compiler/compilergraph"
	"github.com/serulian/compiler/graphs/srg/typerefresolver"

	"github.com/serulian/compiler/graphs/scopegraph/proto"
	"github.com/serulian/compiler/graphs/srg"
	srgtc "github.com/serulian/compiler/graphs/srg/typeconstructor"
	"github.com/serulian/compiler/graphs/typegraph"
	"github.com/serulian/compiler/packageloader"
	"github.com/serulian/compiler/webidl"
	webidltc "github.com/serulian/compiler/webidl/typeconstructor"
)

// PromisingAccessType defines an enumeration of access types for the IsPromisingMember check.
type PromisingAccessType int

const (
	// PromisingAccessFunctionCall indicates that the expression is being invoked as a function
	// call and the function itself should be checked if promising.
	PromisingAccessFunctionCall PromisingAccessType = iota

	// PromisingAccessImplicitGet indicates the expression is calling a property via an implicit
	// get and the property's getter should be checked.
	PromisingAccessImplicitGet

	// PromisingAccessImplicitSet indicates the expression is calling a property via an implicit
	// set and the property's setter should be checked.
	PromisingAccessImplicitSet

	// PromisingAccessInitializer indicates that the initializer of a variable is being accessed
	// and should be checked.
	PromisingAccessInitializer
)

// ScopeGraph represents the ScopeGraph layer and all its associated helper methods.
type ScopeGraph struct {
	srg           *srg.SRG                     // The SRG behind this scope graph.
	tdg           *typegraph.TypeGraph         // The TDG behind this scope graph.
	irg           *webidl.WebIRG               // The IRG for WebIDL behind this scope graph.
	packageLoader *packageloader.PackageLoader // The package loader behind this scope graph.
	graph         *compilergraph.SerulianGraph // The root graph.

	srgRefResolver        *typerefresolver.TypeReferenceResolver // The resolver to use for SRG type refs.
	dynamicPromisingNames map[string]bool

	layer *compilergraph.GraphLayer // The ScopeGraph layer in the graph.
}

// Result represents the results of building a scope graph.
type Result struct {
	Status   bool                           // Whether the construction succeeded.
	Warnings []compilercommon.SourceWarning // Any warnings encountered during construction.
	Errors   []compilercommon.SourceError   // Any errors encountered during construction.
	Graph    *ScopeGraph                    // The constructed scope graph.
}

// BuildTarget defines the target of the scoping being performed.
type BuildTarget string

const (
	// Compilation indicates the scope graph is being built for compilation of code
	// and therefore should not process the remaining phases if any errors occur.
	Compilation BuildTarget = "compilation"

	// Tooling indicates the scope graph is being built for IDE or other forms of tooling,
	// and that a partially valid graph should be returned.
	Tooling BuildTarget = "tooling"
)

// Config defines the configuration for scoping.
type Config struct {
	// RootSourceFilePath is the root source file path from which to begin scoping.
	RootSourceFilePath string

	// VCSDevelopmentDirectories are the paths to the development directories, if any, that
	// override VCS imports.
	VCSDevelopmentDirectories []string

	// Libraries defines the libraries, if any, to import along with the root source file.
	Libraries []packageloader.Library

	// Target defines the target of the scope building.
	Target BuildTarget

	// PathLoader defines the path loader to use when parsing.
	PathLoader packageloader.PathLoader
}

// ParseAndBuildScopeGraph conducts full parsing, type graph construction and scoping for the project
// starting at the given root source file.
func ParseAndBuildScopeGraph(rootSourceFilePath string, vcsDevelopmentDirectories []string, libraries ...packageloader.Library) Result {
	result, err := ParseAndBuildScopeGraphWithConfig(Config{
		RootSourceFilePath:        rootSourceFilePath,
		VCSDevelopmentDirectories: vcsDevelopmentDirectories,
		Libraries:                 libraries,
		Target:                    Compilation,
		PathLoader:                packageloader.LocalFilePathLoader{},
	})

	if err != nil {
		log.Fatalf("Could not build graph: %v", err)
	}

	return result
}

// ParseAndBuildScopeGraphWithConfig conducts full parsing, type graph construction and scoping for the project
// starting at the root source file specified in configuration. If an *internal error* occurs, it is
// returned as the `err`. Parsing and scoping errors are returned in the Result.
func ParseAndBuildScopeGraphWithConfig(config Config) (Result, error) {
	graph, err := compilergraph.NewGraph(config.RootSourceFilePath)
	if err != nil {
		return Result{}, err
	}

	// Create the SRG for the source and load it.
	sourcegraph := srg.NewSRG(graph)
	webidlgraph := webidl.NewIRG(graph)

	loader := packageloader.NewPackageLoader(packageloader.Config{
		RootSourceFilePath:        config.RootSourceFilePath,
		PathLoader:                config.PathLoader,
		VCSDevelopmentDirectories: config.VCSDevelopmentDirectories,
		AlwaysValidate:            config.Target == Tooling,
		SkipVCSRefresh:            config.Target == Tooling,

		SourceHandlers: []packageloader.SourceHandler{
			sourcegraph.PackageLoaderHandler(),
			webidlgraph.PackageLoaderHandler()},
	})

	loaderResult := loader.Load(config.Libraries...)
	if !loaderResult.Status && config.Target != Tooling {
		return Result{
			Status:   false,
			Errors:   loaderResult.Errors,
			Warnings: loaderResult.Warnings,
		}, nil
	}

	// Construct the type graph.
	resolver := typerefresolver.NewResolver(sourcegraph)
	srgConstructor := srgtc.GetConstructorWithResolver(sourcegraph, resolver)
	typeResult := typegraph.BuildTypeGraph(sourcegraph.Graph, webidltc.GetConstructor(webidlgraph), srgConstructor)
	if !typeResult.Status && config.Target != Tooling {
		return Result{
			Status:   false,
			Errors:   typeResult.Errors,
			Warnings: combineWarnings(loaderResult.Warnings, typeResult.Warnings),
		}, nil
	}

	// Freeze the resolver's cache.
	resolver.FreezeCache()

	// Construct the scope graph.
	scopeResult := buildScopeGraphWithResolver(sourcegraph, webidlgraph, typeResult.Graph, resolver, loader)
	return Result{
		Status:   scopeResult.Status && typeResult.Status && loaderResult.Status,
		Errors:   scopeResult.Errors,
		Warnings: combineWarnings(loaderResult.Warnings, typeResult.Warnings, scopeResult.Warnings),
		Graph:    scopeResult.Graph,
	}, nil
}

// SourceGraph returns the SRG behind this scope graph.
func (sg *ScopeGraph) SourceGraph() *srg.SRG {
	return sg.srg
}

// TypeGraph returns the type graph behind this scope graph.
func (sg *ScopeGraph) TypeGraph() *typegraph.TypeGraph {
	return sg.tdg
}

// PackageLoader returns the package loader behind this scope graph.
func (sg *ScopeGraph) PackageLoader() *packageloader.PackageLoader {
	return sg.packageLoader
}

// GetScope returns the scope for the given SRG node, if any.
func (sg *ScopeGraph) GetScope(srgNode compilergraph.GraphNode) (proto.ScopeInfo, bool) {
	scopeNode, found := sg.layer.
		StartQuery(srgNode.NodeId).
		In(NodePredicateSource).
		TryGetNode()

	if !found {
		return proto.ScopeInfo{}, false
	}

	scopeInfo := scopeNode.GetTagged(NodePredicateScopeInfo, &proto.ScopeInfo{}).(*proto.ScopeInfo)
	return *scopeInfo, true
}

// BuildTransientScope builds the scope for the given transient node, as scoped under the given parent node.
// Note that this method should *only* be used for transient nodes (i.e. expressions in something like Grok),
// and that the scope created will not be saved anywhere once this method returns.
func (sg *ScopeGraph) BuildTransientScope(transientNode compilergraph.GraphNode, parentImplementable srg.SRGImplementable) (proto.ScopeInfo, bool) {
	// TODO: maybe skip writing the scope to the graph layer?
	builder := newScopeBuilder(sg)
	defer builder.modifier.Close()

	// TODO: Change these types into interfaces and use no-op implementations here as performance
	// improvement.
	staticDependencyCollector := newStaticDependencyCollector()
	dynamicDependencyCollector := newDynamicDependencyCollector()

	context := scopeContext{
		parentImplemented:          parentImplementable.GraphNode,
		rootNode:                   parentImplementable.GraphNode,
		staticDependencyCollector:  staticDependencyCollector,
		dynamicDependencyCollector: dynamicDependencyCollector,
		rootLabelSet:               newLabelSet(),
	}

	scopeInfo := builder.getScope(transientNode, context)
	return *scopeInfo, builder.Status
}

// HasSecondaryLabel returns whether the given SRG node has a secondary scope label of the given kind.
func (sg *ScopeGraph) HasSecondaryLabel(srgNode compilergraph.GraphNode, label proto.ScopeLabel) bool {
	_, found := sg.layer.
		StartQuery(srgNode.NodeId).
		In(NodePredicateLabelSource).
		Has(NodePredicateSecondaryLabelValue, strconv.Itoa(int(label))).
		TryGetNode()

	return found
}

// ResolveSRGTypeRef builds an SRG type reference into a resolved type reference.
func (sg *ScopeGraph) ResolveSRGTypeRef(srgTypeRef srg.SRGTypeRef) (typegraph.TypeReference, error) {
	return sg.srgRefResolver.ResolveTypeRef(srgTypeRef, sg.tdg)
}

// IsPromisingMember returns whether the member, when accessed via the given access type, returns a promise.
func (sg *ScopeGraph) IsPromisingMember(member typegraph.TGMember, accessType PromisingAccessType) bool {
	// If this member is not implicitly called and we are asking for implicit access information, then
	// it cannot return a promise.
	if (accessType != PromisingAccessFunctionCall && accessType != PromisingAccessInitializer) && !member.IsImplicitlyCalled() {
		return false
	}

	// Switch based on the typegraph-defined promising metric. Most SRG-constructed members will be
	// "dynamic" (since they are not known to promise until after scoping runs), but some members will
	// be defined by the type system as either promising or not.
	switch member.IsPromising() {
	case typegraph.MemberNotPromising:
		return false

	case typegraph.MemberPromising:
		return true

	case typegraph.MemberPromisingDynamic:
		// If the type member is marked as dynamically promising, we need to either check the scopegraph
		// for the promising label or infer the promising for implicitly constructed members. First, we
		// find the associated SRG member (if any).
		sourceId, hasSourceNode := member.SourceNodeId()
		if !hasSourceNode {
			// This is a member constructed by the type system implicitly, so it needs to be inferred
			// here based on other metrics.
			return sg.inferMemberPromising(member)
		}

		// Find the associated SRG member.
		srgNode, hasSRGNode := sg.srg.TryGetNode(sourceId)
		if !hasSRGNode {
			panic("Missing SRG node on dynamically promising member")
		}

		// Based on access type, lookup the scoping label on the proper implementation.
		srgMember := sg.srg.GetMemberReference(srgNode)

		// If the member is an interface,  check its name.
		if !srgMember.HasImplementation() {
			_, exists := sg.dynamicPromisingNames[member.Name()]
			return exists
		}

		implNode := srgMember.GraphNode

		switch accessType {
		case PromisingAccessInitializer:
			fallthrough

		case PromisingAccessFunctionCall:
			implNode = srgMember.GraphNode // The member itself

		case PromisingAccessImplicitGet:
			getter, hasGetter := srgMember.Getter()
			if !hasGetter {
				return false
			}

			implNode = getter.GraphNode

		case PromisingAccessImplicitSet:
			setter, hasSetter := srgMember.Setter()
			if !hasSetter {
				return false
			}

			implNode = setter.GraphNode
		}

		// Check the SRG for the scope label on the implementation node, if any.
		return !sg.HasSecondaryLabel(implNode, proto.ScopeLabel_SML_PROMISING_NO)

	default:
		panic("Missing promising case")
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2014 Workiva, LLC

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

 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 queue

import (
	"sync"
	"sync/atomic"
	"testing"

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

func TestPut(t *testing.T) {
	q := New(10)

	q.Put(`test`)
	assert.Equal(t, int64(1), q.Len())

	results, err := q.Get(1)
	assert.Nil(t, err)

	result := results[0]
	assert.Equal(t, `test`, result)
	assert.True(t, q.Empty())

	q.Put(`test2`)
	assert.Equal(t, int64(1), q.Len())

	results, err = q.Get(1)
	assert.Nil(t, err)

	result = results[0]
	assert.Equal(t, `test2`, result)
	assert.True(t, q.Empty())
}

func TestGet(t *testing.T) {
	q := New(10)

	q.Put(`test`)
	result, err := q.Get(2)
	if !assert.Nil(t, err) {
		return
	}

	assert.Len(t, result, 1)
	assert.Equal(t, `test`, result[0])
	assert.Equal(t, int64(0), q.Len())

	q.Put(`1`)
	q.Put(`2`)

	result, err = q.Get(1)
	if !assert.Nil(t, err) {
		return
	}

	assert.Len(t, result, 1)
	assert.Equal(t, `1`, result[0])
	assert.Equal(t, int64(1), q.Len())

	result, err = q.Get(2)
	if !assert.Nil(t, err) {
		return
	}

	assert.Equal(t, `2`, result[0])
}

func TestAddEmptyPut(t *testing.T) {
	q := New(10)

	q.Put()

	if q.Len() != 0 {
		t.Errorf(`Expected len: %d, received: %d`, 0, q.Len())
	}
}

func TestGetNonPositiveNumber(t *testing.T) {
	q := New(10)

	q.Put(`test`)
	result, err := q.Get(0)
	if !assert.Nil(t, err) {
		return
	}

	if len(result) != 0 {
		t.Errorf(`Expected len: %d, received: %d`, 0, len(result))
	}
}

func TestEmpty(t *testing.T) {
	q := New(10)

	if !q.Empty() {
		t.Errorf(`Expected empty queue.`)
	}

	q.Put(`test`)
	if q.Empty() {
		t.Errorf(`Expected non-empty queue.`)
	}
}

func TestGetEmpty(t *testing.T) {
	q := New(10)

	go func() {
		q.Put(`a`)
	}()

	result, err := q.Get(2)
	if !assert.Nil(t, err) {
		return
	}

	assert.Len(t, result, 1)
	assert.Equal(t, `a`, result[0])
}

func TestMultipleGetEmpty(t *testing.T) {
	q := New(10)
	var wg sync.WaitGroup
	wg.Add(2)
	results := make([][]interface{}, 2)

	go func() {
		wg.Done()
		local, err := q.Get(1)
		assert.Nil(t, err)
		results[0] = local
		wg.Done()
	}()

	go func() {
		wg.Done()
		local, err := q.Get(1)
		assert.Nil(t, err)
		results[1] = local
		wg.Done()
	}()

	wg.Wait()
	wg.Add(2)

	q.Put(`a`, `b`, `c`)
	wg.Wait()

	if assert.Len(t, results[0], 1) && assert.Len(t, results[1], 1) {
		assert.True(t, (results[0][0] == `a` && results[1][0] == `b`) ||
			(results[0][0] == `b` && results[1][0] == `a`),
			`The array should be a, b or b, a`)
	}
}

func TestEmptyGetWithDispose(t *testing.T) {
	q := New(10)
	var wg sync.WaitGroup
	wg.Add(1)

	var err error

	go func() {
		wg.Done()
		_, err = q.Get(1)
		wg.Done()
	}()

	wg.Wait()
	wg.Add(1)

	q.Dispose()

	wg.Wait()

	assert.IsType(t, ErrDisposed, err)
}

func TestGetPutDisposed(t *testing.T) {
	q := New(10)

	q.Dispose()

	_, err := q.Get(1)
	assert.IsType(t, ErrDisposed, err)

	err = q.Put(`a`)
	assert.IsType(t, ErrDisposed, err)
}

func BenchmarkQueue(b *testing.B) {
	q := New(int64(b.N))
	var wg sync.WaitGroup
	wg.Add(1)
	i := 0

	go func() {
		for {
			q.Get(1)
			i++
			if i == b.N {
				wg.Done()
				break
			}
		}
	}()

	for i := 0; i < b.N; i++ {
		q.Put(`a`)
	}

	wg.Wait()
}

func BenchmarkChannel(b *testing.B) {
	ch := make(chan interface{}, 1)
	var wg sync.WaitGroup
	wg.Add(1)
	i := 0

	go func() {
		for {
			<-ch
			i++
			if i == b.N {
				wg.Done()
				break
			}
		}
	}()

	for i := 0; i < b.N; i++ {
		ch <- `a`
	}

	wg.Wait()
}

func TestTakeUntil(t *testing.T) {
	q := New(10)
	q.Put(`a`, `b`, `c`)
	result, err := q.TakeUntil(func(item interface{}) bool {
		return item != `c`
	})

	if !assert.Nil(t, err) {
		return
	}

	expected := []interface{}{`a`, `b`}
	assert.Equal(t, expected, result)
}

func TestTakeUntilEmptyQueue(t *testing.T) {
	q := New(10)
	result, err := q.TakeUntil(func(item interface{}) bool {
		return item != `c`
	})

	if !assert.Nil(t, err) {
		return
	}

	expected := []interface{}{}
	assert.Equal(t, expected, result)
}

func TestTakeUntilOnDisposedQueue(t *testing.T) {
	q := New(10)
	q.Dispose()
	result, err := q.TakeUntil(func(item interface{}) bool {
		return true
	})

	assert.Nil(t, result)
	assert.IsType(t, ErrDisposed, err)
}

func TestExecuteInParallel(t *testing.T) {
	q := New(10)
	for i := 0; i < 10; i++ {
		q.Put(i)
	}

	numCalls := uint64(0)

	ExecuteInParallel(q, func(item interface{}) {
		t.Logf("ExecuteInParallel called us with %+v", item)
		atomic.AddUint64(&numCalls, 1)
	})

	assert.Equal(t, uint64(10), numCalls)
	assert.True(t, q.Disposed())
}

func TestExecuteInParallelEmptyQueue(t *testing.T) {
	q := New(1)

	// basically just ensuring we don't deadlock here
	ExecuteInParallel(q, func(interface{}) {
		t.Fail()
	})
}

func BenchmarkQueuePut(b *testing.B) {
	numItems := int64(1000)

	qs := make([]*Queue, 0, b.N)

	for i := 0; i < b.N; i++ {
		q := New(10)
		qs = append(qs, q)
	}

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		q := qs[i]
		for j := int64(0); j < numItems; j++ {
			q.Put(j)
		}
	}
}

func BenchmarkQueueGet(b *testing.B) {
	numItems := int64(1000)

	qs := make([]*Queue, 0, b.N)

	for i := 0; i < b.N; i++ {
		q := New(numItems)
		for j := int64(0); j < numItems; j++ {
			q.Put(j)
		}
		qs = append(qs, q)
	}

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		q := qs[i]
		for j := int64(0); j < numItems; j++ {
			q.Get(1)
		}
	}
}

func BenchmarkExecuteInParallel(b *testing.B) {
	numItems := int64(1000)

	qs := make([]*Queue, 0, b.N)

	for i := 0; i < b.N; i++ {
		q := New(numItems)
		for j := int64(0); j < numItems; j++ {
			q.Put(j)
		}
		qs = append(qs, q)
	}

	var counter int64
	fn := func(ifc interface{}) {
		c := ifc.(int64)
		atomic.AddInt64(&counter, c)
	}

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		q := qs[i]
		ExecuteInParallel(q, fn)
	}
}
<commit_msg>Add unit test around Poll<commit_after>/*
Copyright 2014 Workiva, LLC

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

 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 queue

import (
	"sync"
	"sync/atomic"
	"testing"
	"time"

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

func TestPut(t *testing.T) {
	q := New(10)

	q.Put(`test`)
	assert.Equal(t, int64(1), q.Len())

	results, err := q.Get(1)
	assert.Nil(t, err)

	result := results[0]
	assert.Equal(t, `test`, result)
	assert.True(t, q.Empty())

	q.Put(`test2`)
	assert.Equal(t, int64(1), q.Len())

	results, err = q.Get(1)
	assert.Nil(t, err)

	result = results[0]
	assert.Equal(t, `test2`, result)
	assert.True(t, q.Empty())
}

func TestGet(t *testing.T) {
	q := New(10)

	q.Put(`test`)
	result, err := q.Get(2)
	if !assert.Nil(t, err) {
		return
	}

	assert.Len(t, result, 1)
	assert.Equal(t, `test`, result[0])
	assert.Equal(t, int64(0), q.Len())

	q.Put(`1`)
	q.Put(`2`)

	result, err = q.Get(1)
	if !assert.Nil(t, err) {
		return
	}

	assert.Len(t, result, 1)
	assert.Equal(t, `1`, result[0])
	assert.Equal(t, int64(1), q.Len())

	result, err = q.Get(2)
	if !assert.Nil(t, err) {
		return
	}

	assert.Equal(t, `2`, result[0])
}

func TestPoll(t *testing.T) {
	q := New(10)

	q.Put(`test`)
	result, err := q.Poll(2, 0)
	if !assert.Nil(t, err) {
		return
	}

	assert.Len(t, result, 1)
	assert.Equal(t, `test`, result[0])
	assert.Equal(t, int64(0), q.Len())

	q.Put(`1`)
	q.Put(`2`)

	result, err = q.Poll(1, time.Millisecond)
	if !assert.Nil(t, err) {
		return
	}

	assert.Len(t, result, 1)
	assert.Equal(t, `1`, result[0])
	assert.Equal(t, int64(1), q.Len())

	result, err = q.Poll(2, time.Millisecond)
	if !assert.Nil(t, err) {
		return
	}

	assert.Equal(t, `2`, result[0])

	before := time.Now()
	_, err = q.Poll(1, 5*time.Millisecond)
	assert.InDelta(t, 5, time.Since(before).Seconds()*1000, 2)
	assert.Equal(t, ErrTimeout, err)
}

func TestAddEmptyPut(t *testing.T) {
	q := New(10)

	q.Put()

	if q.Len() != 0 {
		t.Errorf(`Expected len: %d, received: %d`, 0, q.Len())
	}
}

func TestGetNonPositiveNumber(t *testing.T) {
	q := New(10)

	q.Put(`test`)
	result, err := q.Get(0)
	if !assert.Nil(t, err) {
		return
	}

	if len(result) != 0 {
		t.Errorf(`Expected len: %d, received: %d`, 0, len(result))
	}
}

func TestEmpty(t *testing.T) {
	q := New(10)

	if !q.Empty() {
		t.Errorf(`Expected empty queue.`)
	}

	q.Put(`test`)
	if q.Empty() {
		t.Errorf(`Expected non-empty queue.`)
	}
}

func TestGetEmpty(t *testing.T) {
	q := New(10)

	go func() {
		q.Put(`a`)
	}()

	result, err := q.Get(2)
	if !assert.Nil(t, err) {
		return
	}

	assert.Len(t, result, 1)
	assert.Equal(t, `a`, result[0])
}

func TestMultipleGetEmpty(t *testing.T) {
	q := New(10)
	var wg sync.WaitGroup
	wg.Add(2)
	results := make([][]interface{}, 2)

	go func() {
		wg.Done()
		local, err := q.Get(1)
		assert.Nil(t, err)
		results[0] = local
		wg.Done()
	}()

	go func() {
		wg.Done()
		local, err := q.Get(1)
		assert.Nil(t, err)
		results[1] = local
		wg.Done()
	}()

	wg.Wait()
	wg.Add(2)

	q.Put(`a`, `b`, `c`)
	wg.Wait()

	if assert.Len(t, results[0], 1) && assert.Len(t, results[1], 1) {
		assert.True(t, (results[0][0] == `a` && results[1][0] == `b`) ||
			(results[0][0] == `b` && results[1][0] == `a`),
			`The array should be a, b or b, a`)
	}
}

func TestEmptyGetWithDispose(t *testing.T) {
	q := New(10)
	var wg sync.WaitGroup
	wg.Add(1)

	var err error

	go func() {
		wg.Done()
		_, err = q.Get(1)
		wg.Done()
	}()

	wg.Wait()
	wg.Add(1)

	q.Dispose()

	wg.Wait()

	assert.IsType(t, ErrDisposed, err)
}

func TestGetPutDisposed(t *testing.T) {
	q := New(10)

	q.Dispose()

	_, err := q.Get(1)
	assert.IsType(t, ErrDisposed, err)

	err = q.Put(`a`)
	assert.IsType(t, ErrDisposed, err)
}

func BenchmarkQueue(b *testing.B) {
	q := New(int64(b.N))
	var wg sync.WaitGroup
	wg.Add(1)
	i := 0

	go func() {
		for {
			q.Get(1)
			i++
			if i == b.N {
				wg.Done()
				break
			}
		}
	}()

	for i := 0; i < b.N; i++ {
		q.Put(`a`)
	}

	wg.Wait()
}

func BenchmarkChannel(b *testing.B) {
	ch := make(chan interface{}, 1)
	var wg sync.WaitGroup
	wg.Add(1)
	i := 0

	go func() {
		for {
			<-ch
			i++
			if i == b.N {
				wg.Done()
				break
			}
		}
	}()

	for i := 0; i < b.N; i++ {
		ch <- `a`
	}

	wg.Wait()
}

func TestTakeUntil(t *testing.T) {
	q := New(10)
	q.Put(`a`, `b`, `c`)
	result, err := q.TakeUntil(func(item interface{}) bool {
		return item != `c`
	})

	if !assert.Nil(t, err) {
		return
	}

	expected := []interface{}{`a`, `b`}
	assert.Equal(t, expected, result)
}

func TestTakeUntilEmptyQueue(t *testing.T) {
	q := New(10)
	result, err := q.TakeUntil(func(item interface{}) bool {
		return item != `c`
	})

	if !assert.Nil(t, err) {
		return
	}

	expected := []interface{}{}
	assert.Equal(t, expected, result)
}

func TestTakeUntilOnDisposedQueue(t *testing.T) {
	q := New(10)
	q.Dispose()
	result, err := q.TakeUntil(func(item interface{}) bool {
		return true
	})

	assert.Nil(t, result)
	assert.IsType(t, ErrDisposed, err)
}

func TestExecuteInParallel(t *testing.T) {
	q := New(10)
	for i := 0; i < 10; i++ {
		q.Put(i)
	}

	numCalls := uint64(0)

	ExecuteInParallel(q, func(item interface{}) {
		t.Logf("ExecuteInParallel called us with %+v", item)
		atomic.AddUint64(&numCalls, 1)
	})

	assert.Equal(t, uint64(10), numCalls)
	assert.True(t, q.Disposed())
}

func TestExecuteInParallelEmptyQueue(t *testing.T) {
	q := New(1)

	// basically just ensuring we don't deadlock here
	ExecuteInParallel(q, func(interface{}) {
		t.Fail()
	})
}

func BenchmarkQueuePut(b *testing.B) {
	numItems := int64(1000)

	qs := make([]*Queue, 0, b.N)

	for i := 0; i < b.N; i++ {
		q := New(10)
		qs = append(qs, q)
	}

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		q := qs[i]
		for j := int64(0); j < numItems; j++ {
			q.Put(j)
		}
	}
}

func BenchmarkQueueGet(b *testing.B) {
	numItems := int64(1000)

	qs := make([]*Queue, 0, b.N)

	for i := 0; i < b.N; i++ {
		q := New(numItems)
		for j := int64(0); j < numItems; j++ {
			q.Put(j)
		}
		qs = append(qs, q)
	}

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		q := qs[i]
		for j := int64(0); j < numItems; j++ {
			q.Get(1)
		}
	}
}

func BenchmarkExecuteInParallel(b *testing.B) {
	numItems := int64(1000)

	qs := make([]*Queue, 0, b.N)

	for i := 0; i < b.N; i++ {
		q := New(numItems)
		for j := int64(0); j < numItems; j++ {
			q.Put(j)
		}
		qs = append(qs, q)
	}

	var counter int64
	fn := func(ifc interface{}) {
		c := ifc.(int64)
		atomic.AddInt64(&counter, c)
	}

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		q := qs[i]
		ExecuteInParallel(q, fn)
	}
}
<|endoftext|>


<commit_before>package system

import (
	"errors"
	"fmt"
	"strings"
	"testing"

	. "github.com/smartystreets/goconvey/convey"
)

func TestShell(t *testing.T) {
	for i, test := range cases {
		Convey(fmt.Sprintf("%d - %s", i, test.String()), t, func() {
			fmt.Printf("\n%s\n\n", test.String())
			output, err := invokeShell(test)

			So(output, ShouldEqual, test.output)
			So(err, ShouldResemble, test.err)
		})
	}
}

func invokeShell(test TestCase) (string, error) {
	executor := NewCommandRecorder(test)
	shell := NewShell(executor, "go", test.short, test.coverage, "reports")
	return shell.GoTest("directory", "pack/age")
}

var cases = []TestCase{
	TestCase{
		imports: false,
		output:  "import compilation",
		err:     errors.New("directory|go test -i"),
	},
	TestCase{
		imports: true, short: false, coverage: false, goconvey: false, passes: false,
		output: "test execution",
		err:    errors.New("directory|go test -v -short=false"),
	},
	TestCase{
		imports: true, short: false, coverage: false, goconvey: false, passes: true,
		output: "test execution",
		err:    nil,
	},
	TestCase{
		imports: true, short: false, coverage: false, goconvey: true, passes: false,
		output: "goconvey test execution",
		err:    errors.New("directory|go test -v -short=false -json"),
	},
	TestCase{
		imports: true, short: false, coverage: false, goconvey: true, passes: true,
		output: "goconvey test execution",
		err:    nil,
	},
	TestCase{
		imports: true, short: false, coverage: true, goconvey: false, passes: false,
		output: "test execution", // because the tests fail with coverage, they are re-run without coverage
		err:    errors.New("directory|go test -v -short=false"),
	},
	TestCase{
		imports: true, short: false, coverage: true, goconvey: false, passes: true,
		output: "test coverage execution",
		err:    nil,
	},
	// TestCase{
	// 	imports: true, short: false, coverage: true, goconvey: true, passes: false,
	// 	output: "test execution", // because the tests fail with coverage, they are re-run without coverage
	// 	err:    errors.New("directory|go test -v -short=false -json"),
	// },
	// TestCase{
	// 	imports: true, short: false, coverage: true, goconvey: true, passes: true,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: false, goconvey: false, passes: false,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: false, goconvey: false, passes: true,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: false, goconvey: true, passes: false,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: false, goconvey: true, passes: true,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: true, goconvey: false, passes: false,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: true, goconvey: false, passes: true,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: true, goconvey: true, passes: false,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: true, goconvey: true, passes: true,
	// },
}

type TestCase struct {

	// input parameters
	imports  bool // is `go test -i`  successful?
	short    bool // is `-short` enabled?
	coverage bool // is `-coverage` enabled?
	goconvey bool // do the tests use the GoConvey DSL?
	passes   bool // do the tests pass?

	// expected results
	output string
	err    error
}

func (self TestCase) String() string {
	return fmt.Sprintf("Parameters: | %s | %s | %s | %s | %s |",
		decideCase("imports", self.imports),
		decideCase("short", self.short),
		decideCase("coverage", self.coverage),
		decideCase("goconvey", self.goconvey),
		decideCase("passes", self.passes))
}

// state == true: UPPERCASE
// state == false: lowercase
func decideCase(text string, state bool) string {
	if state {
		return strings.ToUpper(text)
	}
	return strings.ToLower(text)
}
<commit_msg>Using convey.Printf for debugging of shell tests.<commit_after>package system

import (
	"errors"
	"fmt"
	"strings"
	"testing"

	. "github.com/smartystreets/goconvey/convey"
)

func TestShell(t *testing.T) {
	for i, test := range cases {
		Convey(fmt.Sprintf("%d - %s", i, test.String()), t, func() {
			Printf("\n%s\n\n", test.String())
			output, err := invokeShell(test)

			So(output, ShouldEqual, test.output)
			So(err, ShouldResemble, test.err)
		})
	}
}

func invokeShell(test TestCase) (string, error) {
	executor := NewCommandRecorder(test)
	shell := NewShell(executor, "go", test.short, test.coverage, "reports")
	return shell.GoTest("directory", "pack/age")
}

var cases = []TestCase{
	TestCase{
		imports: false,
		output:  "import compilation",
		err:     errors.New("directory|go test -i"),
	},
	TestCase{
		imports: true, short: false, coverage: false, goconvey: false, passes: false,
		output: "test execution",
		err:    errors.New("directory|go test -v -short=false"),
	},
	TestCase{
		imports: true, short: false, coverage: false, goconvey: false, passes: true,
		output: "test execution",
		err:    nil,
	},
	TestCase{
		imports: true, short: false, coverage: false, goconvey: true, passes: false,
		output: "goconvey test execution",
		err:    errors.New("directory|go test -v -short=false -json"),
	},
	TestCase{
		imports: true, short: false, coverage: false, goconvey: true, passes: true,
		output: "goconvey test execution",
		err:    nil,
	},
	TestCase{
		imports: true, short: false, coverage: true, goconvey: false, passes: false,
		output: "test execution", // because the tests fail with coverage, they are re-run without coverage
		err:    errors.New("directory|go test -v -short=false"),
	},
	TestCase{
		imports: true, short: false, coverage: true, goconvey: false, passes: true,
		output: "test coverage execution",
		err:    nil,
	},
	// TestCase{
	// 	imports: true, short: false, coverage: true, goconvey: true, passes: false,
	// 	output: "test execution", // because the tests fail with coverage, they are re-run without coverage
	// 	err:    errors.New("directory|go test -v -short=false -json"),
	// },
	// TestCase{
	// 	imports: true, short: false, coverage: true, goconvey: true, passes: true,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: false, goconvey: false, passes: false,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: false, goconvey: false, passes: true,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: false, goconvey: true, passes: false,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: false, goconvey: true, passes: true,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: true, goconvey: false, passes: false,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: true, goconvey: false, passes: true,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: true, goconvey: true, passes: false,
	// },
	// TestCase{
	// 	imports: true, short: true, coverage: true, goconvey: true, passes: true,
	// },
}

type TestCase struct {

	// input parameters
	imports  bool // is `go test -i`  successful?
	short    bool // is `-short` enabled?
	coverage bool // is `-coverage` enabled?
	goconvey bool // do the tests use the GoConvey DSL?
	passes   bool // do the tests pass?

	// expected results
	output string
	err    error
}

func (self TestCase) String() string {
	return fmt.Sprintf("Parameters: | %s | %s | %s | %s | %s |",
		decideCase("imports", self.imports),
		decideCase("short", self.short),
		decideCase("coverage", self.coverage),
		decideCase("goconvey", self.goconvey),
		decideCase("passes", self.passes))
}

// state == true: UPPERCASE
// state == false: lowercase
func decideCase(text string, state bool) string {
	if state {
		return strings.ToUpper(text)
	}
	return strings.ToLower(text)
}
<|endoftext|>


<commit_before>package test

import (
	"strconv"
	"testing"
	"time"

	"github.com/vkuznet/transfer2go/core"
)

// Compare 1k/10k files of source with the same 1k files of destination
func TestCompare(t *testing.T) {
  input := [2]int{1000, 10000}
  for _, val := range input {
  	var sourceCatalog []core.CatalogEntry
  	destinationCatalog := make([]core.CatalogEntry, val)
  	dataset := "/a/b/c"
  	block := "/a/b/c#123"
  	for i := 0; i < val; i++ {
  		rec := core.CatalogEntry{Dataset: dataset, Block: block, Lfn: block + "-" + dataset + "file" + strconv.Itoa(i) + ".root"}
  		sourceCatalog = append(sourceCatalog, rec)
  	}
  	copy(destinationCatalog[:], sourceCatalog)
  	start := time.Now()

  	records := core.CompareRecords(sourceCatalog, destinationCatalog)
  	elapsed := time.Since(start)
  	t.Logf("For %d it took %s", val, elapsed)
  	if records != nil {
  		t.Errorf("Incorrect Match for 1k files: %d", len(records))
  	}
  }
}

// Compare 1k files of source with the distinct 10k files of destination
func TestCompareTenThousandUncommon(t *testing.T) {
	var sourceCatalog []core.CatalogEntry
	var destinationCatalog []core.CatalogEntry
	dataset := "/a/b/c"
	block := "/a/b/c#123"
	for i := 0; i < 10000; i++ {
		rec := core.CatalogEntry{Dataset: dataset, Block: block, Lfn: block + "-" + dataset + "file" + strconv.Itoa(i) + ".root"}
		sourceCatalog = append(sourceCatalog, rec)
	}
	start := time.Now()
	records := core.CompareRecords(sourceCatalog, destinationCatalog)
	elapsed := time.Since(start)
	t.Log("For 10k uncommon it took", elapsed)
	if records != nil {
		t.Log("Need to transfer total files:", len(records))
	}
}

// Test Request function
func TestGetDestFiles(t *testing.T) {
  start := time.Now()
  rec, err := core.GetDestFiles(core.TransferRequest{SrcUrl:"http://localhost:8000", DstUrl:"http://localhost:9000", Dataset: "/a/b/c"})
  elapsed := time.Since(start)
	t.Log("Time took to get destination file", elapsed)
  if err != nil {
		t.Log("Error in TestGetDestFiles:", err)
	}
  t.Log("Files found on destination:", len(rec))
}
<commit_msg>Apply gofmt -s<commit_after>package test

import (
	"strconv"
	"testing"
	"time"

	"github.com/vkuznet/transfer2go/core"
)

// Compare 1k/10k files of source with the same 1k files of destination
func TestCompare(t *testing.T) {
	input := [2]int{1000, 10000}
	for _, val := range input {
		var sourceCatalog []core.CatalogEntry
		destinationCatalog := make([]core.CatalogEntry, val)
		dataset := "/a/b/c"
		block := "/a/b/c#123"
		for i := 0; i < val; i++ {
			rec := core.CatalogEntry{Dataset: dataset, Block: block, Lfn: block + "-" + dataset + "file" + strconv.Itoa(i) + ".root"}
			sourceCatalog = append(sourceCatalog, rec)
		}
		copy(destinationCatalog[:], sourceCatalog)
		start := time.Now()

		records := core.CompareRecords(sourceCatalog, destinationCatalog)
		elapsed := time.Since(start)
		t.Logf("For %d it took %s", val, elapsed)
		if records != nil {
			t.Errorf("Incorrect Match for 1k files: %d", len(records))
		}
	}
}

// Compare 1k files of source with the distinct 10k files of destination
func TestCompareTenThousandUncommon(t *testing.T) {
	var sourceCatalog []core.CatalogEntry
	var destinationCatalog []core.CatalogEntry
	dataset := "/a/b/c"
	block := "/a/b/c#123"
	for i := 0; i < 10000; i++ {
		rec := core.CatalogEntry{Dataset: dataset, Block: block, Lfn: block + "-" + dataset + "file" + strconv.Itoa(i) + ".root"}
		sourceCatalog = append(sourceCatalog, rec)
	}
	start := time.Now()
	records := core.CompareRecords(sourceCatalog, destinationCatalog)
	elapsed := time.Since(start)
	t.Log("For 10k uncommon it took", elapsed)
	if records != nil {
		t.Log("Need to transfer total files:", len(records))
	}
}

// Test Request function
func TestGetDestFiles(t *testing.T) {
	start := time.Now()
	rec, err := core.GetDestFiles(core.TransferRequest{SrcUrl: "http://localhost:8000", DstUrl: "http://localhost:9000", Dataset: "/a/b/c"})
	elapsed := time.Since(start)
	t.Log("Time took to get destination file", elapsed)
	if err != nil {
		t.Log("Error in TestGetDestFiles:", err)
	}
	t.Log("Files found on destination:", len(rec))
}
<|endoftext|>