<commit_before>// Copyright 2013 tsuru 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 testing

import (
	"errors"
	"fmt"
	"github.com/globocom/tsuru/provision"
	"io"
	"strconv"
	"sync"
	"time"
)

func init() {
	provision.Register("fake", &FakeProvisioner{})
}

// Fake implementation for provision.Unit.
type FakeUnit struct {
	Name       string
	Ip         string
	InstanceId string
	Machine    int
	Status     provision.Status
}

func (u *FakeUnit) GetName() string {
	return u.Name
}

func (u *FakeUnit) GetMachine() int {
	return u.Machine
}

func (u *FakeUnit) GetStatus() provision.Status {
	return u.Status
}

func (u *FakeUnit) GetInstanceId() string {
	return u.InstanceId
}

func (u *FakeUnit) GetIp() string {
	return u.Ip
}

// Fake implementation for provision.App.
type FakeApp struct {
	name      string
	framework string
	units     []provision.AppUnit
	logs      []string
}

func NewFakeApp(name, framework string, units int) *FakeApp {
	app := FakeApp{
		name:      name,
		framework: framework,
		units:     make([]provision.AppUnit, units),
	}
	namefmt := "%s/%d"
	for i := 0; i < units; i++ {
		app.units[i] = &FakeUnit{
			Name:       fmt.Sprintf(namefmt, name, i),
			Machine:    i + 1,
			Status:     provision.StatusStarted,
			Ip:         fmt.Sprintf("10.10.10.%d", i+1),
			InstanceId: fmt.Sprintf("i-0%d", i+1),
		}
	}
	return &app
}

func (a *FakeApp) Log(message, source string) error {
	a.logs = append(a.logs, source+message)
	return nil
}

func (a *FakeApp) GetName() string {
	return a.name
}

func (a *FakeApp) GetFramework() string {
	return a.framework
}

func (a *FakeApp) ProvisionUnits() []provision.AppUnit {
	return a.units
}

func (a *FakeApp) SetUnitStatus(s provision.Status, index int) {
	if index < len(a.units) {
		a.units[index].(*FakeUnit).Status = s
	}
}

type Cmd struct {
	Cmd  string
	Args []string
	App  provision.App
}

type failure struct {
	method string
	err    error
}

// Fake implementation for provision.Provisioner.
type FakeProvisioner struct {
	apps     []provision.App
	units    map[string][]provision.Unit
	cmds     []Cmd
	outputs  chan []byte
	failures chan failure
	cmdMut   sync.Mutex
	unitMut  sync.Mutex
}

func NewFakeProvisioner() *FakeProvisioner {
	p := FakeProvisioner{}
	p.outputs = make(chan []byte, 8)
	p.failures = make(chan failure, 8)
	p.units = make(map[string][]provision.Unit)
	return &p
}

func (p *FakeProvisioner) getError(method string) error {
	select {
	case fail := <-p.failures:
		if fail.method == method {
			return fail.err
		}
		p.failures <- fail
	case <-time.After(1e6):
	}
	return nil
}

// GetCmds returns a list of commands executed in an app. If you don't specify
// the command (""), it will return all commands executed in the given app.
func (p *FakeProvisioner) GetCmds(cmd string, app provision.App) []Cmd {
	var cmds []Cmd
	p.cmdMut.Lock()
	for _, c := range p.cmds {
		if (cmd == "" || c.Cmd == cmd) && app.GetName() == c.App.GetName() {
			cmds = append(cmds, c)
		}
	}
	p.cmdMut.Unlock()
	return cmds
}

func (p *FakeProvisioner) FindApp(app provision.App) int {
	for i, a := range p.apps {
		if a.GetName() == app.GetName() {
			return i
		}
	}
	return -1
}

func (p *FakeProvisioner) GetUnits(app provision.App) []provision.Unit {
	p.unitMut.Lock()
	defer p.unitMut.Unlock()
	return p.units[app.GetName()]
}

func (p *FakeProvisioner) PrepareOutput(b []byte) {
	p.outputs <- b
}

func (p *FakeProvisioner) PrepareFailure(method string, err error) {
	p.failures <- failure{method, err}
}

func (p *FakeProvisioner) Reset() {
	p.unitMut.Lock()
	p.units = make(map[string][]provision.Unit)
	p.unitMut.Unlock()

	p.cmdMut.Lock()
	p.cmds = nil
	p.cmdMut.Unlock()

	for {
		select {
		case <-p.outputs:
		case <-p.failures:
		default:
			return
		}
	}
}

func (p *FakeProvisioner) Provision(app provision.App) error {
	if err := p.getError("Provision"); err != nil {
		return err
	}
	index := p.FindApp(app)
	if index > -1 {
		return &provision.Error{Reason: "App already provisioned."}
	}
	p.apps = append(p.apps, app)
	p.unitMut.Lock()
	p.units[app.GetName()] = []provision.Unit{
		{
			Name:       app.GetName() + "/0",
			AppName:    app.GetName(),
			Type:       app.GetFramework(),
			Status:     provision.StatusStarted,
			InstanceId: "i-080",
			Ip:         "10.10.10.1",
			Machine:    1,
		},
	}
	p.unitMut.Unlock()
	return nil
}

func (p *FakeProvisioner) Destroy(app provision.App) error {
	if err := p.getError("Destroy"); err != nil {
		return err
	}
	index := p.FindApp(app)
	if index == -1 {
		return &provision.Error{Reason: "App is not provisioned."}
	}
	copy(p.apps[index:], p.apps[index+1:])
	p.apps = p.apps[:len(p.apps)-1]
	p.unitMut.Lock()
	delete(p.units, app.GetName())
	p.unitMut.Unlock()
	return nil
}

func (p *FakeProvisioner) AddUnits(app provision.App, n uint) ([]provision.Unit, error) {
	if err := p.getError("AddUnits"); err != nil {
		return nil, err
	}
	if n == 0 {
		return nil, errors.New("Cannot add 0 units.")
	}
	index := p.FindApp(app)
	if index < 0 {
		return nil, errors.New("App is not provisioned.")
	}
	name := app.GetName()
	framework := app.GetFramework()
	p.unitMut.Lock()
	defer p.unitMut.Unlock()
	length := uint(len(p.units[name]))
	for i := uint(0); i < n; i++ {
		unit := provision.Unit{
			Name:       fmt.Sprintf("%s/%d", name, length+i),
			AppName:    name,
			Type:       framework,
			Status:     provision.StatusStarted,
			InstanceId: fmt.Sprintf("i-08%d", length+i),
			Ip:         fmt.Sprintf("10.10.10.%d", length+i),
			Machine:    int(length + i),
		}
		p.units[name] = append(p.units[name], unit)
	}
	return p.units[name][length:], nil
}

func (p *FakeProvisioner) RemoveUnit(app provision.App, name string) error {
	if err := p.getError("RemoveUnit"); err != nil {
		return err
	}
	index := -1
	appName := app.GetName()
	if index := p.FindApp(app); index < 0 {
		return errors.New("App is not provisioned.")
	}
	p.unitMut.Lock()
	defer p.unitMut.Unlock()
	for i, unit := range p.units[appName] {
		if unit.Name == name {
			index = i
			break
		}
	}
	if index == -1 {
		return errors.New("Unit not found.")
	}
	copy(p.units[appName][index:], p.units[appName][index+1:])
	p.units[appName] = p.units[appName][:len(p.units[appName])-1]
	return nil
}

func (p *FakeProvisioner) ExecuteCommand(stdout, stderr io.Writer, app provision.App, cmd string, args ...string) error {
	var (
		output []byte
		err    error
	)
	command := Cmd{
		Cmd:  cmd,
		Args: args,
		App:  app,
	}
	p.cmdMut.Lock()
	p.cmds = append(p.cmds, command)
	p.cmdMut.Unlock()
	select {
	case output = <-p.outputs:
		select {
		case fail := <-p.failures:
			if fail.method == "ExecuteCommand" {
				stderr.Write(output)
				return fail.err
			} else {
				p.failures <- fail
			}
		case <-time.After(1e6):
			stdout.Write(output)
		}
	case fail := <-p.failures:
		if fail.method == "ExecuteCommand" {
			err = fail.err
			select {
			case output = <-p.outputs:
				stderr.Write(output)
			case <-time.After(1e6):
			}
		} else {
			p.failures <- fail
		}
	case <-time.After(2e9):
		return errors.New("FakeProvisioner timed out waiting for output.")
	}
	return err
}

func (p *FakeProvisioner) CollectStatus() ([]provision.Unit, error) {
	if err := p.getError("CollectStatus"); err != nil {
		return nil, err
	}
	units := make([]provision.Unit, len(p.apps))
	for i, app := range p.apps {
		unit := provision.Unit{
			Name:       app.GetName() + "/0",
			AppName:    app.GetName(),
			Type:       app.GetFramework(),
			Status:     "started",
			InstanceId: fmt.Sprintf("i-0%d", 800+i+1),
			Ip:         "10.10.10." + strconv.Itoa(i+1),
			Machine:    i + 1,
		}
		units[i] = unit
	}
	return units, nil
}

func (p *FakeProvisioner) Addr(app provision.App) (string, error) {
	if err := p.getError("Addr"); err != nil {
		return "", err
	}
	return fmt.Sprintf("%s.fake-lb.tsuru.io", app.GetName()), nil
}
<commit_msg>testing: better wording in tests<commit_after>// Copyright 2013 tsuru 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 testing

import (
	"errors"
	"fmt"
	"github.com/globocom/tsuru/provision"
	"io"
	"strconv"
	"sync"
	"time"
)

func init() {
	provision.Register("fake", &FakeProvisioner{})
}

// Fake implementation for provision.Unit.
type FakeUnit struct {
	Name       string
	Ip         string
	InstanceId string
	Machine    int
	Status     provision.Status
}

func (u *FakeUnit) GetName() string {
	return u.Name
}

func (u *FakeUnit) GetMachine() int {
	return u.Machine
}

func (u *FakeUnit) GetStatus() provision.Status {
	return u.Status
}

func (u *FakeUnit) GetInstanceId() string {
	return u.InstanceId
}

func (u *FakeUnit) GetIp() string {
	return u.Ip
}

// Fake implementation for provision.App.
type FakeApp struct {
	name      string
	framework string
	units     []provision.AppUnit
	logs      []string
}

func NewFakeApp(name, framework string, units int) *FakeApp {
	app := FakeApp{
		name:      name,
		framework: framework,
		units:     make([]provision.AppUnit, units),
	}
	namefmt := "%s/%d"
	for i := 0; i < units; i++ {
		app.units[i] = &FakeUnit{
			Name:       fmt.Sprintf(namefmt, name, i),
			Machine:    i + 1,
			Status:     provision.StatusStarted,
			Ip:         fmt.Sprintf("10.10.10.%d", i+1),
			InstanceId: fmt.Sprintf("i-0%d", i+1),
		}
	}
	return &app
}

func (a *FakeApp) Log(message, source string) error {
	a.logs = append(a.logs, source+message)
	return nil
}

func (a *FakeApp) GetName() string {
	return a.name
}

func (a *FakeApp) GetFramework() string {
	return a.framework
}

func (a *FakeApp) ProvisionUnits() []provision.AppUnit {
	return a.units
}

func (a *FakeApp) SetUnitStatus(s provision.Status, index int) {
	if index < len(a.units) {
		a.units[index].(*FakeUnit).Status = s
	}
}

type Cmd struct {
	Cmd  string
	Args []string
	App  provision.App
}

type failure struct {
	method string
	err    error
}

// Fake implementation for provision.Provisioner.
type FakeProvisioner struct {
	apps     []provision.App
	units    map[string][]provision.Unit
	cmds     []Cmd
	outputs  chan []byte
	failures chan failure
	cmdMut   sync.Mutex
	unitMut  sync.Mutex
}

func NewFakeProvisioner() *FakeProvisioner {
	p := FakeProvisioner{}
	p.outputs = make(chan []byte, 8)
	p.failures = make(chan failure, 8)
	p.units = make(map[string][]provision.Unit)
	return &p
}

func (p *FakeProvisioner) getError(method string) error {
	select {
	case fail := <-p.failures:
		if fail.method == method {
			return fail.err
		}
		p.failures <- fail
	case <-time.After(1e6):
	}
	return nil
}

// GetCmds returns a list of commands executed in an app. If you don't specify
// the command (an empty string), it will return all commands executed in the
// given app.
func (p *FakeProvisioner) GetCmds(cmd string, app provision.App) []Cmd {
	var cmds []Cmd
	p.cmdMut.Lock()
	for _, c := range p.cmds {
		if (cmd == "" || c.Cmd == cmd) && app.GetName() == c.App.GetName() {
			cmds = append(cmds, c)
		}
	}
	p.cmdMut.Unlock()
	return cmds
}

func (p *FakeProvisioner) FindApp(app provision.App) int {
	for i, a := range p.apps {
		if a.GetName() == app.GetName() {
			return i
		}
	}
	return -1
}

func (p *FakeProvisioner) GetUnits(app provision.App) []provision.Unit {
	p.unitMut.Lock()
	defer p.unitMut.Unlock()
	return p.units[app.GetName()]
}

func (p *FakeProvisioner) PrepareOutput(b []byte) {
	p.outputs <- b
}

func (p *FakeProvisioner) PrepareFailure(method string, err error) {
	p.failures <- failure{method, err}
}

func (p *FakeProvisioner) Reset() {
	p.unitMut.Lock()
	p.units = make(map[string][]provision.Unit)
	p.unitMut.Unlock()

	p.cmdMut.Lock()
	p.cmds = nil
	p.cmdMut.Unlock()

	for {
		select {
		case <-p.outputs:
		case <-p.failures:
		default:
			return
		}
	}
}

func (p *FakeProvisioner) Provision(app provision.App) error {
	if err := p.getError("Provision"); err != nil {
		return err
	}
	index := p.FindApp(app)
	if index > -1 {
		return &provision.Error{Reason: "App already provisioned."}
	}
	p.apps = append(p.apps, app)
	p.unitMut.Lock()
	p.units[app.GetName()] = []provision.Unit{
		{
			Name:       app.GetName() + "/0",
			AppName:    app.GetName(),
			Type:       app.GetFramework(),
			Status:     provision.StatusStarted,
			InstanceId: "i-080",
			Ip:         "10.10.10.1",
			Machine:    1,
		},
	}
	p.unitMut.Unlock()
	return nil
}

func (p *FakeProvisioner) Destroy(app provision.App) error {
	if err := p.getError("Destroy"); err != nil {
		return err
	}
	index := p.FindApp(app)
	if index == -1 {
		return &provision.Error{Reason: "App is not provisioned."}
	}
	copy(p.apps[index:], p.apps[index+1:])
	p.apps = p.apps[:len(p.apps)-1]
	p.unitMut.Lock()
	delete(p.units, app.GetName())
	p.unitMut.Unlock()
	return nil
}

func (p *FakeProvisioner) AddUnits(app provision.App, n uint) ([]provision.Unit, error) {
	if err := p.getError("AddUnits"); err != nil {
		return nil, err
	}
	if n == 0 {
		return nil, errors.New("Cannot add 0 units.")
	}
	index := p.FindApp(app)
	if index < 0 {
		return nil, errors.New("App is not provisioned.")
	}
	name := app.GetName()
	framework := app.GetFramework()
	p.unitMut.Lock()
	defer p.unitMut.Unlock()
	length := uint(len(p.units[name]))
	for i := uint(0); i < n; i++ {
		unit := provision.Unit{
			Name:       fmt.Sprintf("%s/%d", name, length+i),
			AppName:    name,
			Type:       framework,
			Status:     provision.StatusStarted,
			InstanceId: fmt.Sprintf("i-08%d", length+i),
			Ip:         fmt.Sprintf("10.10.10.%d", length+i),
			Machine:    int(length + i),
		}
		p.units[name] = append(p.units[name], unit)
	}
	return p.units[name][length:], nil
}

func (p *FakeProvisioner) RemoveUnit(app provision.App, name string) error {
	if err := p.getError("RemoveUnit"); err != nil {
		return err
	}
	index := -1
	appName := app.GetName()
	if index := p.FindApp(app); index < 0 {
		return errors.New("App is not provisioned.")
	}
	p.unitMut.Lock()
	defer p.unitMut.Unlock()
	for i, unit := range p.units[appName] {
		if unit.Name == name {
			index = i
			break
		}
	}
	if index == -1 {
		return errors.New("Unit not found.")
	}
	copy(p.units[appName][index:], p.units[appName][index+1:])
	p.units[appName] = p.units[appName][:len(p.units[appName])-1]
	return nil
}

func (p *FakeProvisioner) ExecuteCommand(stdout, stderr io.Writer, app provision.App, cmd string, args ...string) error {
	var (
		output []byte
		err    error
	)
	command := Cmd{
		Cmd:  cmd,
		Args: args,
		App:  app,
	}
	p.cmdMut.Lock()
	p.cmds = append(p.cmds, command)
	p.cmdMut.Unlock()
	select {
	case output = <-p.outputs:
		select {
		case fail := <-p.failures:
			if fail.method == "ExecuteCommand" {
				stderr.Write(output)
				return fail.err
			} else {
				p.failures <- fail
			}
		case <-time.After(1e6):
			stdout.Write(output)
		}
	case fail := <-p.failures:
		if fail.method == "ExecuteCommand" {
			err = fail.err
			select {
			case output = <-p.outputs:
				stderr.Write(output)
			case <-time.After(1e6):
			}
		} else {
			p.failures <- fail
		}
	case <-time.After(2e9):
		return errors.New("FakeProvisioner timed out waiting for output.")
	}
	return err
}

func (p *FakeProvisioner) CollectStatus() ([]provision.Unit, error) {
	if err := p.getError("CollectStatus"); err != nil {
		return nil, err
	}
	units := make([]provision.Unit, len(p.apps))
	for i, app := range p.apps {
		unit := provision.Unit{
			Name:       app.GetName() + "/0",
			AppName:    app.GetName(),
			Type:       app.GetFramework(),
			Status:     "started",
			InstanceId: fmt.Sprintf("i-0%d", 800+i+1),
			Ip:         "10.10.10." + strconv.Itoa(i+1),
			Machine:    i + 1,
		}
		units[i] = unit
	}
	return units, nil
}

func (p *FakeProvisioner) Addr(app provision.App) (string, error) {
	if err := p.getError("Addr"); err != nil {
		return "", err
	}
	return fmt.Sprintf("%s.fake-lb.tsuru.io", app.GetName()), nil
}
<|endoftext|>


<commit_before>package flowgraph_test

import (
	"errors"
	"fmt"
	"github.com/vectaport/fgbase"
	"github.com/vectaport/flowgraph"
	"io"
	"os"
	"testing"
	"time"
)

/*=====================================================================*/

func TestMain(m *testing.M) {
	fgbase.ConfigByFlag(map[string]interface{}{"trace": "QQ"})
	os.Exit(m.Run())
}

/*=====================================================================*/

func TestNewEqual(t *testing.T) {

	t.Parallel()

	fmt.Printf("BEGIN:  TestNewEqual\n")

	// Different allocations should not be equal.
	if flowgraph.New("abc") == flowgraph.New("abc") {
		t.Errorf(`New("abc") == New("abc")`)
	}
	if flowgraph.New("abc") == flowgraph.New("xyz") {
		t.Errorf(`New("abc") == New("xyz")`)
	}

	// Same allocation should be equal to itself (not crash).
	g := flowgraph.New("jkl")
	if g != g {
		t.Errorf(`graph != graph`)
	}

	fmt.Printf("END:    TestNewEqual\n")
}

/*=====================================================================*/

type getter struct {
	cnt int
}

func (g *getter) Transform(hub *flowgraph.Hub, source []interface{}) (result []interface{}, err error) {
	i := g.cnt
	g.cnt++
	return []interface{}{i}, nil
}

func TestIncoming(t *testing.T) {

	t.Parallel()

	fmt.Printf("BEGIN:  TestIncoming\n")

	fg := flowgraph.New("TestIncoming")

	incoming := fg.NewHub("incoming", flowgraph.AllOf, &getter{})
	incoming.SetResultNames("X")

	sink := fg.NewHub("sink", flowgraph.Sink, nil)
	sink.SetSourceNames("A")

	fg.Connect(incoming, "X", sink, "A")

	fg.Run()

	fmt.Printf("END:    TestIncoming\n")
}

/*=====================================================================*/

type putter struct {
	sum int
}

func (p *putter) Transform(hub *flowgraph.Hub, source []interface{}) (result []interface{}, err error) {
	p.sum += source[0].(int)
	return nil, nil
}

func TestOutgoing(t *testing.T) {

	t.Parallel()

	fmt.Printf("BEGIN:  TestOutgoing\n")

	fg := flowgraph.New("TestOutgoing")

	const1 := fg.NewHub("const1", flowgraph.Const, 1)
	const1.SetResultNames("X")

	outgoing := fg.NewHub("outgoing", flowgraph.AllOf, &putter{})
	outgoing.SetSourceNames("A")

	fg.Connect(const1, "X", outgoing, "A")

	fg.Run()

	fmt.Printf("END:    TestOutgoing\n")

}

/*=====================================================================*/

type transformer struct{}

func (t *transformer) Transform(hub *flowgraph.Hub, source []interface{}) (result []interface{}, err error) {
	xv := source[0].(int) * 2
	return []interface{}{xv}, nil
}

func TestAllOf(t *testing.T) {

	t.Parallel()

	fmt.Printf("BEGIN:  TestAllOf\n")

	fg := flowgraph.New("TestAllOf")

	const1 := fg.NewHub("const1", flowgraph.Const, 1)
	const1.SetResultNames("X")

	transformer := fg.NewHub("outgoing", flowgraph.AllOf, &transformer{})
	transformer.SetSourceNames("A")
	transformer.SetResultNames("X")

	sink := fg.NewHub("sink", flowgraph.Sink, nil)
	sink.SetSourceNames("A")

	fg.Connect(const1, "X", transformer, "A")
	fg.Connect(transformer, "X", sink, "A")

	fg.Run()

	fmt.Printf("END:    TestAllOf\n")
}

/*=====================================================================*/

func TestArray(t *testing.T) {

	fmt.Printf("BEGIN:  TestArray\n")

	fg := flowgraph.New("TestArray")

	arr := []interface{}{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	array := fg.NewHub("array", flowgraph.Array, arr)
	array.SetResultNames("X")

	sink := fg.NewHub("sink", flowgraph.Sink, nil)
	sink.SetSourceNames("A")

	fg.Connect(array, "X", sink, "A")

	fg.Run()

	s := sink.Node().Aux.(fgbase.SinkStats)

	if s.Cnt != len(arr) {
		t.Fatalf("SinkStats.Cnt %d != len(arr) (%d)\n", s.Cnt, len(arr))
	}

	sum := 0
	for _, v := range arr {
		sum += v.(int)
	}
	if s.Sum != sum {
		t.Fatalf("SinkStats.Sum %d != sum(arr)\n", s.Sum)
	}

	fmt.Printf("END:  TestArray\n")
}

/*=====================================================================*/

type pass struct{}

func (p *pass) Transform(n *flowgraph.Hub, source []interface{}) (result []interface{}, err error) {
	v := source[n.SourceIndex("A")]
	i := n.ResultIndex("X")
	r := make([]interface{}, i+1)
	r[i] = v
	return r, nil
}

func TestChain(t *testing.T) {
	fmt.Printf("BEGIN:  TestChain\n")
	oldRunTime := fgbase.RunTime
	fgbase.RunTime = 0

	arr := []interface{}{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

	fg := flowgraph.New("TestChain")

	array := fg.NewHub("array", flowgraph.Array, arr)
	array.SetResultNames("X")

	l := 1024
	p := make([]*flowgraph.Hub, l)

	for i := 0; i < l; i++ {
		p[i] = fg.NewHub(fmt.Sprintf("t%04d", i), flowgraph.AllOf, &pass{})
		p[i].SetSourceNames("A")
		p[i].SetResultNames("X")
	}

	sink := fg.NewHub("sink", flowgraph.Sink, nil)
	sink.SetSourceNames("A")

	fg.Connect(array, "X", p[0], "A")
	for i := 0; i < l-1; i++ {
		fg.Connect(p[i], "X", p[i+1], "A")
	}
	fg.Connect(p[l-1], "X", sink, "A")

	fg.Run()

	s := sink.Node().Aux.(fgbase.SinkStats)

	if s.Cnt != len(arr) {
		t.Fatalf("SinkStats.Cnt %d != len(arr)\n", s.Cnt)
	}

	sum := 0
	for _, v := range arr {
		sum += v.(int)
	}
	if s.Sum != sum {
		t.Fatalf("SinkStats.Sum %d != sum(arr)\n", s.Sum)
	}

	fgbase.RunTime = oldRunTime
	fmt.Printf("END:    TestChain\n")
}

/*=====================================================================*/

func TestDotNaming(t *testing.T) {
	fmt.Printf("BEGIN:  TestDotNaming\n")
	oldRunTime := fgbase.RunTime
	oldTracePorts := fgbase.TracePorts
	oldTraceLevel := fgbase.TraceLevel
	fgbase.RunTime = time.Second / 100
	fgbase.TracePorts = true
	fgbase.TraceLevel = fgbase.V

	io.EOF = errors.New("XXX")

	fg := flowgraph.New("TestDotNaming")

	h0 := fg.NewHub("name0", flowgraph.Const, 100)
	h0.SetResultNames("XYZ")

	h1 := fg.NewHub("name1", flowgraph.Sink, nil)
	h1.SetSourceNames("ABC")

	s0, s0ok := h0.FindResult("XYZ")
	if !s0ok {
		t.Fatalf("ERROR Unable to find result port named XYZ\n")
	}

	if s0 == nil {
		t.Fatalf("ERROR Unable to find stream at result port named XYZ\n")
	}

	s1, s1ok := h1.FindSource("ABC")
	if !s1ok {
		t.Fatalf("ERROR Unable to find source port named ABC\n")
	}

	if s1 == nil {
		t.Fatalf("ERROR Unable to find stream at source port named ABC on hub %s\n", h1)
	}

	fg.Connect(h0, "XYZ", h1, "ABC")

	if h0.Result(0) == nil {
		t.Fatalf("ERROR Unable to find result port numbered 0\n")
	}
	if h0.Result(0).Empty() {
		t.Fatalf("ERROR Unable to find stream at result port numbered 0 on hub %s\n", h0.Name())
	}

	if h1.Source(0) == nil {
		t.Fatalf("ERROR Unable to find source port numbered 0\n")
	}
	if h1.Source(0).Empty() {
		t.Fatalf("ERROR Unable to find stream at source port numbered 0\n")
	}

	fg.Run()

	fgbase.RunTime = oldRunTime
	fgbase.TracePorts = oldTracePorts
	fgbase.TraceLevel = oldTraceLevel
	fmt.Printf("END:    TestDotNaming\n")
}

/*=====================================================================*/

func TestAdd(t *testing.T) {
	fmt.Printf("BEGIN:  TestAdd\n")
	oldRunTime := fgbase.RunTime
	oldTracePorts := fgbase.TracePorts
	oldTraceLevel := fgbase.TraceLevel
	fgbase.RunTime = time.Second / 100
	fgbase.TracePorts = true
	fgbase.TraceLevel = fgbase.V

	fg := flowgraph.New("TestAdd")

	const100 := fg.NewHub("const100", flowgraph.Const, 100)
	const100.SetResultNames("X")

	const1 := fg.NewHub("const1", flowgraph.Const, 1)
	const1.SetResultNames("X")

	add := fg.NewHub("add", flowgraph.Add, nil)
	add.SetSourceNames("A", "B")
	add.SetResultNames("X")

	sink := fg.NewHub("sink", flowgraph.Sink, nil)
	sink.SetSourceNames("A")

	fg.Connect(const100, "X", add, "A")
	fg.Connect(const1, "X", add, "B")
	fg.Connect(add, "X", sink, "A")

	fg.Run()

	fgbase.RunTime = oldRunTime
	fgbase.TracePorts = oldTracePorts
	fgbase.TraceLevel = oldTraceLevel
	fmt.Printf("END:    TestAdd\n")
}

/*=====================================================================*/

func TestIterator(t *testing.T) {
	fmt.Printf("BEGIN:  TestIterator\n")
	oldRunTime := fgbase.RunTime
	oldTracePorts := fgbase.TracePorts
	oldTraceLevel := fgbase.TraceLevel
	fgbase.RunTime = time.Second / 100
	fgbase.TracePorts = true
	fgbase.TraceLevel = fgbase.V

	fg := flowgraph.New("TestIterator")

	const100 := fg.NewHub("const100", flowgraph.Const, 100)
	const100.SetResultNames("X")

	const1 := fg.NewHub("const1", flowgraph.Const, 1)
	const1.SetResultNames("X")

	add := fg.NewHub("add", flowgraph.Add, nil)
	add.SetSourceNames("A", "B")
	add.SetResultNames("X")

	sink := fg.NewHub("sink", flowgraph.Sink, nil)
	sink.SetSourceNames("A")

	fg.Connect(const100, "X", add, "A")
	fg.Connect(const1, "X", add, "B")
	fg.Connect(add, "X", sink, "A")

	fg.Run()

	fgbase.RunTime = oldRunTime
	fgbase.TracePorts = oldTracePorts
	fgbase.TraceLevel = oldTraceLevel
	fmt.Printf("END:    TestIterator\n")
}
<commit_msg>working on lineeq<commit_after>package flowgraph_test

import (
	"errors"
	"fmt"
	"github.com/vectaport/fgbase"
	"github.com/vectaport/flowgraph"
	"io"
	"os"
	"testing"
	"time"
)

/*=====================================================================*/

func TestMain(m *testing.M) {
	fgbase.ConfigByFlag(map[string]interface{}{"trace": "QQ"})
	os.Exit(m.Run())
}

/*=====================================================================*/

func TestNewEqual(t *testing.T) {

	t.Parallel()

	fmt.Printf("BEGIN:  TestNewEqual\n")

	// Different allocations should not be equal.
	if flowgraph.New("abc") == flowgraph.New("abc") {
		t.Errorf(`New("abc") == New("abc")`)
	}
	if flowgraph.New("abc") == flowgraph.New("xyz") {
		t.Errorf(`New("abc") == New("xyz")`)
	}

	// Same allocation should be equal to itself (not crash).
	g := flowgraph.New("jkl")
	if g != g {
		t.Errorf(`graph != graph`)
	}

	fmt.Printf("END:    TestNewEqual\n")
}

/*=====================================================================*/

type getter struct {
	cnt int
}

func (g *getter) Transform(hub *flowgraph.Hub, source []interface{}) (result []interface{}, err error) {
	i := g.cnt
	g.cnt++
	return []interface{}{i}, nil
}

func TestIncoming(t *testing.T) {

	t.Parallel()

	fmt.Printf("BEGIN:  TestIncoming\n")

	fg := flowgraph.New("TestIncoming")

	incoming := fg.NewHub("incoming", flowgraph.AllOf, &getter{})
	incoming.SetResultNames("X")

	sink := fg.NewHub("sink", flowgraph.Sink, nil)
	sink.SetSourceNames("A")

	fg.Connect(incoming, "X", sink, "A")

	fg.Run()

	fmt.Printf("END:    TestIncoming\n")
}

/*=====================================================================*/

type putter struct {
	sum int
}

func (p *putter) Transform(hub *flowgraph.Hub, source []interface{}) (result []interface{}, err error) {
	p.sum += source[0].(int)
	return nil, nil
}

func TestOutgoing(t *testing.T) {

	t.Parallel()

	fmt.Printf("BEGIN:  TestOutgoing\n")

	fg := flowgraph.New("TestOutgoing")

	const1 := fg.NewHub("const1", flowgraph.Const, 1)
	const1.SetResultNames("X")

	outgoing := fg.NewHub("outgoing", flowgraph.AllOf, &putter{})
	outgoing.SetSourceNames("A")

	fg.Connect(const1, "X", outgoing, "A")

	fg.Run()

	fmt.Printf("END:    TestOutgoing\n")

}

/*=====================================================================*/

type transformer struct{}

func (t *transformer) Transform(hub *flowgraph.Hub, source []interface{}) (result []interface{}, err error) {
	xv := source[0].(int) * 2
	return []interface{}{xv}, nil
}

func TestAllOf(t *testing.T) {

	t.Parallel()

	fmt.Printf("BEGIN:  TestAllOf\n")

	fg := flowgraph.New("TestAllOf")

	const1 := fg.NewHub("const1", flowgraph.Const, 1)
	const1.SetResultNames("X")

	transformer := fg.NewHub("outgoing", flowgraph.AllOf, &transformer{})
	transformer.SetSourceNames("A")
	transformer.SetResultNames("X")

	sink := fg.NewHub("sink", flowgraph.Sink, nil)
	sink.SetSourceNames("A")

	fg.Connect(const1, "X", transformer, "A")
	fg.Connect(transformer, "X", sink, "A")

	fg.Run()

	fmt.Printf("END:    TestAllOf\n")
}

/*=====================================================================*/

func TestArray(t *testing.T) {

	fmt.Printf("BEGIN:  TestArray\n")

	fg := flowgraph.New("TestArray")

	arr := []interface{}{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
	array := fg.NewHub("array", flowgraph.Array, arr)
	array.SetResultNames("X")

	sink := fg.NewHub("sink", flowgraph.Sink, nil)
	sink.SetSourceNames("A")

	fg.Connect(array, "X", sink, "A")

	fg.Run()

	s := sink.Node().Aux.(fgbase.SinkStats)

	if s.Cnt != len(arr) {
		t.Fatalf("SinkStats.Cnt %d != len(arr) (%d)\n", s.Cnt, len(arr))
	}

	sum := 0
	for _, v := range arr {
		sum += v.(int)
	}
	if s.Sum != sum {
		t.Fatalf("SinkStats.Sum %d != sum(arr)\n", s.Sum)
	}

	fmt.Printf("END:  TestArray\n")
}

/*=====================================================================*/

type pass struct{}

func (p *pass) Transform(n *flowgraph.Hub, source []interface{}) (result []interface{}, err error) {
	v := source[n.SourceIndex("A")]
	i := n.ResultIndex("X")
	r := make([]interface{}, i+1)
	r[i] = v
	return r, nil
}

func TestChain(t *testing.T) {
	fmt.Printf("BEGIN:  TestChain\n")
	oldRunTime := fgbase.RunTime
	fgbase.RunTime = 0

	arr := []interface{}{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

	fg := flowgraph.New("TestChain")

	array := fg.NewHub("array", flowgraph.Array, arr)
	array.SetResultNames("X")

	l := 1024
	p := make([]*flowgraph.Hub, l)

	for i := 0; i < l; i++ {
		p[i] = fg.NewHub(fmt.Sprintf("t%04d", i), flowgraph.AllOf, &pass{})
		p[i].SetSourceNames("A")
		p[i].SetResultNames("X")
	}

	sink := fg.NewHub("sink", flowgraph.Sink, nil)
	sink.SetSourceNames("A")

	fg.Connect(array, "X", p[0], "A")
	for i := 0; i < l-1; i++ {
		fg.Connect(p[i], "X", p[i+1], "A")
	}
	fg.Connect(p[l-1], "X", sink, "A")

	fg.Run()

	s := sink.Node().Aux.(fgbase.SinkStats)

	if s.Cnt != len(arr) {
		t.Fatalf("SinkStats.Cnt %d != len(arr)\n", s.Cnt)
	}

	sum := 0
	for _, v := range arr {
		sum += v.(int)
	}
	if s.Sum != sum {
		t.Fatalf("SinkStats.Sum %d != sum(arr)\n", s.Sum)
	}

	fgbase.RunTime = oldRunTime
	fmt.Printf("END:    TestChain\n")
}

/*=====================================================================*/

func TestDotNaming(t *testing.T) {
	fmt.Printf("BEGIN:  TestDotNaming\n")
	oldRunTime := fgbase.RunTime
	oldTracePorts := fgbase.TracePorts
	oldTraceLevel := fgbase.TraceLevel
	fgbase.RunTime = time.Second / 100
	fgbase.TracePorts = true
	fgbase.TraceLevel = fgbase.V

	io.EOF = errors.New("XXX")

	fg := flowgraph.New("TestDotNaming")

	h0 := fg.NewHub("name0", flowgraph.Const, 100)
	h0.SetResultNames("XYZ")

	h1 := fg.NewHub("name1", flowgraph.Sink, nil)
	h1.SetSourceNames("ABC")

	s0, s0ok := h0.FindResult("XYZ")
	if !s0ok {
		t.Fatalf("ERROR Unable to find result port named XYZ\n")
	}

	if s0 == nil {
		t.Fatalf("ERROR Unable to find stream at result port named XYZ\n")
	}

	s1, s1ok := h1.FindSource("ABC")
	if !s1ok {
		t.Fatalf("ERROR Unable to find source port named ABC\n")
	}

	if s1 == nil {
		t.Fatalf("ERROR Unable to find stream at source port named ABC on hub %s\n", h1)
	}

	fg.Connect(h0, "XYZ", h1, "ABC")

	if h0.Result(0) == nil {
		t.Fatalf("ERROR Unable to find result port numbered 0\n")
	}
	if h0.Result(0).Empty() {
		t.Fatalf("ERROR Unable to find stream at result port numbered 0 on hub %s\n", h0.Name())
	}

	if h1.Source(0) == nil {
		t.Fatalf("ERROR Unable to find source port numbered 0\n")
	}
	if h1.Source(0).Empty() {
		t.Fatalf("ERROR Unable to find stream at source port numbered 0\n")
	}

	fg.Run()

	fgbase.RunTime = oldRunTime
	fgbase.TracePorts = oldTracePorts
	fgbase.TraceLevel = oldTraceLevel
	fmt.Printf("END:    TestDotNaming\n")
}

/*=====================================================================*/

func TestAdd(t *testing.T) {
	fmt.Printf("BEGIN:  TestAdd\n")
	oldRunTime := fgbase.RunTime
	oldTracePorts := fgbase.TracePorts
	oldTraceLevel := fgbase.TraceLevel
	fgbase.RunTime = time.Second / 100
	fgbase.TracePorts = true
	fgbase.TraceLevel = fgbase.V

	fg := flowgraph.New("TestAdd")

	const100 := fg.NewHub("const100", flowgraph.Const, 100)
	const100.SetResultNames("X")

	const1 := fg.NewHub("const1", flowgraph.Const, 1)
	const1.SetResultNames("X")

	add := fg.NewHub("add", flowgraph.Add, nil)
	add.SetSourceNames("A", "B")
	add.SetResultNames("X")

	sink := fg.NewHub("sink", flowgraph.Sink, nil)
	sink.SetSourceNames("A")

	fg.Connect(const100, "X", add, "A")
	fg.Connect(const1, "X", add, "B")
	fg.Connect(add, "X", sink, "A")

	fg.Run()

	fgbase.RunTime = oldRunTime
	fgbase.TracePorts = oldTracePorts
	fgbase.TraceLevel = oldTraceLevel
	fmt.Printf("END:    TestAdd\n")
}

/*=====================================================================*/

func TestLineEq(t *testing.T) {
	fmt.Printf("BEGIN:  TestLineEq\n")
	oldRunTime := fgbase.RunTime
	oldTracePorts := fgbase.TracePorts
	oldTraceLevel := fgbase.TraceLevel
	fgbase.RunTime = time.Second
	fgbase.TracePorts = true
	fgbase.TraceLevel = fgbase.V

	fg := flowgraph.New("TestLineEq")

	marr := []interface{}{-100,-10,-1,0,1,10,100}
	xarr := []interface{}{0, 10, 20, 30, -10, -20, -30}
	barr := []interface{}{40, 20, 10, 0, -10, -20, -40}

	m := fg.NewHub("m", flowgraph.Array, marr)
	m.SetResultNames("X")

	x := fg.NewHub("x", flowgraph.Array, xarr)
	x.SetResultNames("X")

	b := fg.NewHub("b", flowgraph.Array, barr)
	b.SetResultNames("X")

	mul := fg.NewHub("mul", flowgraph.Mul, nil)
	mul.SetSourceNames("A", "B")
	mul.SetResultNames("X")

	add := fg.NewHub("add", flowgraph.Add, nil)
	add.SetSourceNames("A", "B")
	add.SetResultNames("X")

	sink := fg.NewHub("sink", flowgraph.Sink, nil)
	sink.SetSourceNames("A")

	fg.Connect(m, "X", mul, "A")
	fg.Connect(x, "X", mul, "B")
	fg.Connect(mul, "X", add, "A")
	fg.Connect(b, "X", add, "B")
	fg.Connect(add, "X", sink, "A")

	fg.Run()

	fgbase.RunTime = oldRunTime
	fgbase.TracePorts = oldTracePorts
	fgbase.TraceLevel = oldTraceLevel
	fmt.Printf("END:    TestLineEq\n")
}
<|endoftext|>


<commit_before>package imageprocessor

import (
	"bytes"
	"image"
	"image/color"
	"io/ioutil"
	"testing"
)

var (
	jpgPath  = "../test/img/Lenna.jpg"
	bmpPath  = "../test/img/Lenna.bmp"
	pngPath  = "../test/img/Lenna.png"
	gifPath  = "../test/img/Lenna.gif"
	confPath = "../test/test_conf.json"
)

var (
	jpegBin, _ = ioutil.ReadFile(jpgPath)
	bmpBin, _  = ioutil.ReadFile(bmpPath)
	pngBin, _  = ioutil.ReadFile(pngPath)
	gifBin, _  = ioutil.ReadFile(gifPath)
	confBin, _ = ioutil.ReadFile(confPath)
)

var testRect = image.Rect(0, 0, 100, 100)
var ResizeImage = resizeImage
var ResizeAndFillImage = resizeAndFillImage
var Crop = crop

func TestEncodeJpeg(t *testing.T) {
	img, _ := DecodeImage(bytes.NewReader(jpegBin))
	if format := img.GetFormat(); format != "jpeg" {
		t.Fatalf("format is %v, expected jpeg", format)
	}

	bin, err := EncodeJpeg(img.GetImg(), -1)
	if err != nil {
		t.Fatalf("err is %v.", err)
	}
	if bin == nil {
		t.Fatalf("bin is nil.")
	}

	img, _ = DecodeImage(bytes.NewReader(confBin))
	_, err = EncodeJpeg(img.GetImg(), 50)
	if err == nil {
		t.Fatalf("err is %v.", err)
	}
}

func TestEncodePNG(t *testing.T) {
	img, _ := DecodeImage(bytes.NewReader(pngBin))
	if format := img.GetFormat(); format != "png" {
		t.Fatalf("format is %v, expected png", format)
	}

	bin, err := EncodePNG(img.GetImg(), -1)
	if err != nil {
		t.Fatalf("err is %v.", err)
	}
	if bin == nil {
		t.Fatalf("bin is nil.")
	}

	img, _ = DecodeImage(bytes.NewReader(confBin))
	_, err = EncodePNG(img.GetImg(), 50)
	if err == nil {
		t.Fatalf("err is %v.", err)
	}
}

func TestEncodeGIF(t *testing.T) {
	img, _ := DecodeImage(bytes.NewReader(gifBin))
	if format := img.GetFormat(); format != "gif" {
		t.Fatalf("format is %v, expected png", format)
	}

	bin, err := EncodeGIF(img.GetImg(), -1)
	if err != nil {
		t.Fatalf("err is %v.", err)
	}
	if bin == nil {
		t.Fatalf("bin is nil.")
	}

	img, _ = DecodeImage(bytes.NewReader(confBin))
	_, err = EncodeGIF(img.GetImg(), 50)
	if err == nil {
		t.Fatalf("err is %v.", err)
	}
}

func TestDecodeImage(t *testing.T) {
	img, err := DecodeImage(bytes.NewReader(jpegBin))
	if err != nil {
		t.Log(err)
		t.Fatalf("err is not nil.")
	}
	if img == nil {
		t.Fatalf("can not decode.")
	}

	img, err = DecodeImage(bytes.NewReader(bmpBin))
	if err != nil {
		t.Fatalf("err is not nil. : %v", err)
	}
	if img == nil {
		t.Fatalf("img.%v", img)
	}

	img, err = DecodeImage(bytes.NewReader(pngBin))
	if err != nil {
		t.Log(err)
		t.Fatalf("err is not nil.")
	}
	if img == nil {
		t.Fatalf("can not decode.")
	}

	img, err = DecodeImage(bytes.NewReader(gifBin))
	if err != nil {
		t.Log(err)
		t.Fatalf("err is not nil.")
	}
	if img == nil {
		t.Fatalf("can not decode.")
	}

	img, err = DecodeImage(bytes.NewReader(confBin))
	if err == nil {
		t.Log(err)
		t.Fatalf("err is nil")
	}

	if img == nil {
		t.Fatalf("can not decode.")
	}
}

func TestResizeImage(t *testing.T) {
	img, _ := DecodeImage(bytes.NewReader(confBin))

	resizeImg := ResizeImage(*img.GetImg(), 100, 100, 10000, 10000)
	if resizeImg != nil {
		t.Fatalf("value is not nil.")
	}

	img, _ = DecodeImage(bytes.NewReader(jpegBin))
	ii := *img.GetImg()
	jpegRect := ii.Bounds()

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X*2), uint(jpegRect.Max.Y*2), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X), uint(jpegRect.Max.Y), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X*100000), uint(jpegRect.Max.Y*100000), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X), uint(jpegRect.Max.Y*100000), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X*100000), uint(jpegRect.Max.Y), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X), uint(jpegRect.Max.Y+1000), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X+1000), uint(jpegRect.Max.Y), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X), uint(jpegRect.Max.Y-100), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X-100), uint(jpegRect.Max.Y), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), 0, 0, 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}
}

func TestResizeAndFillImage(t *testing.T) {
	c := color.RGBA{
		R: 0xff,
		G: 0xff,
		B: 0xff,
		A: 0xff,
	}
	img, _ := DecodeImage(bytes.NewReader(confBin))

	fillImg := ResizeAndFillImage(*img.GetImg(), 100, 100, c, 10000, 10000)
	if fillImg != nil {
		t.Fatalf("value is not nil.")
	}

	img, _ = DecodeImage(bytes.NewReader(pngBin))

	fillImg = ResizeAndFillImage(*img.GetImg(), 100, 100, c, 10000, 10000)
	if fillImg == nil {
		t.Fatalf("value is nil.")
	}
	if fillImg.Bounds().Max.X != 100 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}
	if fillImg.Bounds().Max.Y != 100 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}

	fillImg = ResizeAndFillImage(*img.GetImg(), 1000, 100, c, 10000, 10000)
	if fillImg == nil {
		t.Fatalf("value is not nil.")
	}
	if fillImg.Bounds().Max.X != 1000 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}
	if fillImg.Bounds().Max.Y != 100 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}

	fillImg = ResizeAndFillImage(*img.GetImg(), 100, 1000, c, 10000, 10000)
	if fillImg == nil {
		t.Fatalf("value is not nil.")
	}
	if fillImg.Bounds().Max.X != 100 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}
	if fillImg.Bounds().Max.Y != 1000 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}

	fillImg = ResizeAndFillImage(*img.GetImg(), 5000, 5000, c, 10000, 10000)
	if fillImg == nil {
		t.Fatalf("value is not nil.")
	}
	if fillImg.Bounds().Max.X != 5000 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}
	if fillImg.Bounds().Max.Y != 5000 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}

	fillImg = ResizeAndFillImage(*img.GetImg(), 0, 0, c, 10000, 10000)
	if fillImg == nil {
		t.Fatalf("value is not nil.")
	}
	if fillImg.Bounds().Max.X != 512 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}
	if fillImg.Bounds().Max.Y != 512 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}

	fillImg = ResizeAndFillImage(*img.GetImg(), 1000000, 1000000, c, 10000, 10000)
	if fillImg == nil {
		t.Fatalf("value is not nil.")
	}
	if fillImg.Bounds().Max.X != 512 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}
	if fillImg.Bounds().Max.Y != 512 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}
}

func TestCrop(t *testing.T) {
	img, _ := DecodeImage(bytes.NewReader(confBin))

	cropImg := Crop(*img.GetImg(), 100, 100)
	if cropImg != nil {
		t.Fatalf("value is not nil.")
	}

	img, _ = DecodeImage(bytes.NewReader(pngBin))

	cropImg = Crop(*img.GetImg(), 100, 100)
	if cropImg == nil {
		t.Fatalf("value is nil.")
	}
	if cropImg.Bounds().Max.X != 512 {
		t.Fatalf("x is %v.", cropImg.Bounds().Max.X)
	}
	if cropImg.Bounds().Max.Y != 512 {
		t.Fatalf("y is %v.", cropImg.Bounds().Max.Y)
	}

	cropImg = Crop(*img.GetImg(), 1000, 100)
	if cropImg == nil {
		t.Fatalf("value is not nil.")
	}
	if cropImg.Bounds().Max.X != 512 {
		t.Fatalf("x is %v.", cropImg.Bounds().Max.X)
	}
	if cropImg.Bounds().Max.Y != 51 {
		t.Fatalf("y is %v.", cropImg.Bounds().Max.Y)
	}

	cropImg = Crop(*img.GetImg(), 100, 1000)
	if cropImg == nil {
		t.Fatalf("value is not nil.")
	}
	if cropImg.Bounds().Max.X != 51 {
		t.Fatalf("x is %v.", cropImg.Bounds().Max.X)
	}
	if cropImg.Bounds().Max.Y != 512 {
		t.Fatalf("y is %v.", cropImg.Bounds().Max.Y)
	}

	cropImg = Crop(*img.GetImg(), 5000, 5000)
	if cropImg == nil {
		t.Fatalf("value is not nil.")
	}
	if cropImg.Bounds().Max.X != 512 {
		t.Fatalf("x is %v.", cropImg.Bounds().Max.X)
	}
	if cropImg.Bounds().Max.Y != 512 {
		t.Fatalf("y is %v.", cropImg.Bounds().Max.Y)
	}

	cropImg = Crop(*img.GetImg(), 0, 0)
	if cropImg == nil {
		t.Fatalf("value is not nil.")
	}
	if cropImg.Bounds().Max.X != 512 {
		t.Fatalf("x is %v.", cropImg.Bounds().Max.X)
	}
	if cropImg.Bounds().Max.Y != 512 {
		t.Fatalf("y is %v.", cropImg.Bounds().Max.Y)
	}

	cropImg = Crop(*img.GetImg(), 1000000, 1000000)
	if cropImg == nil {
		t.Fatalf("value is not nil.")
	}
	if cropImg.Bounds().Max.X != 512 {
		t.Fatalf("x is %v.", cropImg.Bounds().Max.X)
	}
	if cropImg.Bounds().Max.Y != 512 {
		t.Fatalf("y is %v.", cropImg.Bounds().Max.Y)
	}
}
<commit_msg>Reduce memory usage.<commit_after>package imageprocessor

import (
	"image"
	"image/color"
	"os"
	"testing"
)

var (
	jpgPath  = "../test/img/Lenna.jpg"
	bmpPath  = "../test/img/Lenna.bmp"
	pngPath  = "../test/img/Lenna.png"
	gifPath  = "../test/img/Lenna.gif"
	confPath = "../test/test_conf.json"
)

var (
	jpegBin, _ = os.Open(jpgPath)
	bmpBin, _  = os.Open(bmpPath)
	pngBin, _  = os.Open(pngPath)
	gifBin, _  = os.Open(gifPath)
	confBin, _ = os.Open(confPath)
)

var testRect = image.Rect(0, 0, 100, 100)
var ResizeImage = resizeImage
var ResizeAndFillImage = resizeAndFillImage
var Crop = crop

func TestEncodeJpeg(t *testing.T) {
	img, _ := DecodeImage(jpegBin)
	jpegBin.Seek(0, 0)
	if format := img.GetFormat(); format != "jpeg" {
		t.Fatalf("format is %v, expected jpeg", format)
	}

	bin, err := EncodeJpeg(img.GetImg(), -1)
	if err != nil {
		t.Fatalf("err is %v.", err)
	}
	if bin == nil {
		t.Fatalf("bin is nil.")
	}

	img, _ = DecodeImage(confBin)
	confBin.Seek(0, 0)
	_, err = EncodeJpeg(img.GetImg(), 50)
	if err == nil {
		t.Fatalf("err is %v.", err)
	}
}

func TestEncodePNG(t *testing.T) {
	img, _ := DecodeImage(pngBin)
	pngBin.Seek(0, 0)
	if format := img.GetFormat(); format != "png" {
		t.Fatalf("format is %v, expected png", format)
	}

	bin, err := EncodePNG(img.GetImg(), -1)
	if err != nil {
		t.Fatalf("err is %v.", err)
	}
	if bin == nil {
		t.Fatalf("bin is nil.")
	}

	img, _ = DecodeImage(confBin)
	confBin.Seek(0, 0)
	_, err = EncodePNG(img.GetImg(), 50)
	if err == nil {
		t.Fatalf("err is %v.", err)
	}
}

func TestEncodeGIF(t *testing.T) {
	img, _ := DecodeImage(gifBin)
	gifBin.Seek(0, 0)
	if format := img.GetFormat(); format != "gif" {
		t.Fatalf("format is %v, expected png", format)
	}

	bin, err := EncodeGIF(img.GetImg(), -1)
	if err != nil {
		t.Fatalf("err is %v.", err)
	}
	if bin == nil {
		t.Fatalf("bin is nil.")
	}

	img, _ = DecodeImage(confBin)
	confBin.Seek(0, 0)
	_, err = EncodeGIF(img.GetImg(), 50)
	if err == nil {
		t.Fatalf("err is %v.", err)
	}
}

func TestDecodeImage(t *testing.T) {
	img, err := DecodeImage(jpegBin)
	jpegBin.Seek(0, 0)
	if err != nil {
		t.Log(err)
		t.Fatalf("err is not nil.")
	}
	if img == nil {
		t.Fatalf("can not decode.")
	}

	img, err = DecodeImage(bmpBin)
	bmpBin.Seek(0, 0)
	if err != nil {
		t.Fatalf("err is not nil. : %v", err)
	}
	if img == nil {
		t.Fatalf("img.%v", img)
	}

	img, err = DecodeImage(pngBin)
	pngBin.Seek(0, 0)
	if err != nil {
		t.Log(err)
		t.Fatalf("err is not nil.")
	}
	if img == nil {
		t.Fatalf("can not decode.")
	}

	img, err = DecodeImage(gifBin)
	gifBin.Seek(0, 0)
	if err != nil {
		t.Log(err)
		t.Fatalf("err is not nil.")
	}
	if img == nil {
		t.Fatalf("can not decode.")
	}

	img, err = DecodeImage(confBin)
	confBin.Seek(0, 0)
	if err == nil {
		t.Log(err)
		t.Fatalf("err is nil")
	}

	if img == nil {
		t.Fatalf("can not decode.")
	}
}

func TestResizeImage(t *testing.T) {
	img, _ := DecodeImage(confBin)
	confBin.Seek(0, 0)

	resizeImg := ResizeImage(*img.GetImg(), 100, 100, 10000, 10000)
	if resizeImg != nil {
		t.Fatalf("value is not nil.")
	}

	img, _ = DecodeImage(jpegBin)
	jpegBin.Seek(0, 0)
	ii := *img.GetImg()
	jpegRect := ii.Bounds()

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X*2), uint(jpegRect.Max.Y*2), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X), uint(jpegRect.Max.Y), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X*100000), uint(jpegRect.Max.Y*100000), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X), uint(jpegRect.Max.Y*100000), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X*100000), uint(jpegRect.Max.Y), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X), uint(jpegRect.Max.Y+1000), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X+1000), uint(jpegRect.Max.Y), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X), uint(jpegRect.Max.Y-100), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), uint(jpegRect.Max.X-100), uint(jpegRect.Max.Y), 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}

	resizeImg = ResizeImage(*img.GetImg(), 0, 0, 10000, 10000)
	if resizeImg == nil {
		t.Fatalf("value is nil.")
	}
}

func TestResizeAndFillImage(t *testing.T) {
	c := color.RGBA{
		R: 0xff,
		G: 0xff,
		B: 0xff,
		A: 0xff,
	}
	img, _ := DecodeImage(confBin)
	confBin.Seek(0, 0)

	fillImg := ResizeAndFillImage(*img.GetImg(), 100, 100, c, 10000, 10000)
	if fillImg != nil {
		t.Fatalf("value is not nil.")
	}

	img, _ = DecodeImage(pngBin)
	pngBin.Seek(0, 0)

	fillImg = ResizeAndFillImage(*img.GetImg(), 100, 100, c, 10000, 10000)
	if fillImg == nil {
		t.Fatalf("value is nil.")
	}
	if fillImg.Bounds().Max.X != 100 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}
	if fillImg.Bounds().Max.Y != 100 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}

	fillImg = ResizeAndFillImage(*img.GetImg(), 1000, 100, c, 10000, 10000)
	if fillImg == nil {
		t.Fatalf("value is not nil.")
	}
	if fillImg.Bounds().Max.X != 1000 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}
	if fillImg.Bounds().Max.Y != 100 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}

	fillImg = ResizeAndFillImage(*img.GetImg(), 100, 1000, c, 10000, 10000)
	if fillImg == nil {
		t.Fatalf("value is not nil.")
	}
	if fillImg.Bounds().Max.X != 100 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}
	if fillImg.Bounds().Max.Y != 1000 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}

	fillImg = ResizeAndFillImage(*img.GetImg(), 5000, 5000, c, 10000, 10000)
	if fillImg == nil {
		t.Fatalf("value is not nil.")
	}
	if fillImg.Bounds().Max.X != 5000 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}
	if fillImg.Bounds().Max.Y != 5000 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}

	fillImg = ResizeAndFillImage(*img.GetImg(), 0, 0, c, 10000, 10000)
	if fillImg == nil {
		t.Fatalf("value is not nil.")
	}
	if fillImg.Bounds().Max.X != 512 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}
	if fillImg.Bounds().Max.Y != 512 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}

	fillImg = ResizeAndFillImage(*img.GetImg(), 1000000, 1000000, c, 10000, 10000)
	if fillImg == nil {
		t.Fatalf("value is not nil.")
	}
	if fillImg.Bounds().Max.X != 512 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}
	if fillImg.Bounds().Max.Y != 512 {
		t.Fatalf("x is %v.", fillImg.Bounds().Max.X)
	}
}

func TestCrop(t *testing.T) {
	img, _ := DecodeImage(confBin)
	confBin.Seek(0, 0)

	cropImg := Crop(*img.GetImg(), 100, 100)
	if cropImg != nil {
		t.Fatalf("value is not nil.")
	}

	img, _ = DecodeImage(pngBin)
	pngBin.Seek(0, 0)

	cropImg = Crop(*img.GetImg(), 100, 100)
	if cropImg == nil {
		t.Fatalf("value is nil.")
	}
	if cropImg.Bounds().Max.X != 512 {
		t.Fatalf("x is %v.", cropImg.Bounds().Max.X)
	}
	if cropImg.Bounds().Max.Y != 512 {
		t.Fatalf("y is %v.", cropImg.Bounds().Max.Y)
	}

	cropImg = Crop(*img.GetImg(), 1000, 100)
	if cropImg == nil {
		t.Fatalf("value is not nil.")
	}
	if cropImg.Bounds().Max.X != 512 {
		t.Fatalf("x is %v.", cropImg.Bounds().Max.X)
	}
	if cropImg.Bounds().Max.Y != 51 {
		t.Fatalf("y is %v.", cropImg.Bounds().Max.Y)
	}

	cropImg = Crop(*img.GetImg(), 100, 1000)
	if cropImg == nil {
		t.Fatalf("value is not nil.")
	}
	if cropImg.Bounds().Max.X != 51 {
		t.Fatalf("x is %v.", cropImg.Bounds().Max.X)
	}
	if cropImg.Bounds().Max.Y != 512 {
		t.Fatalf("y is %v.", cropImg.Bounds().Max.Y)
	}

	cropImg = Crop(*img.GetImg(), 5000, 5000)
	if cropImg == nil {
		t.Fatalf("value is not nil.")
	}
	if cropImg.Bounds().Max.X != 512 {
		t.Fatalf("x is %v.", cropImg.Bounds().Max.X)
	}
	if cropImg.Bounds().Max.Y != 512 {
		t.Fatalf("y is %v.", cropImg.Bounds().Max.Y)
	}

	cropImg = Crop(*img.GetImg(), 0, 0)
	if cropImg == nil {
		t.Fatalf("value is not nil.")
	}
	if cropImg.Bounds().Max.X != 512 {
		t.Fatalf("x is %v.", cropImg.Bounds().Max.X)
	}
	if cropImg.Bounds().Max.Y != 512 {
		t.Fatalf("y is %v.", cropImg.Bounds().Max.Y)
	}

	cropImg = Crop(*img.GetImg(), 1000000, 1000000)
	if cropImg == nil {
		t.Fatalf("value is not nil.")
	}
	if cropImg.Bounds().Max.X != 512 {
		t.Fatalf("x is %v.", cropImg.Bounds().Max.X)
	}
	if cropImg.Bounds().Max.Y != 512 {
		t.Fatalf("y is %v.", cropImg.Bounds().Max.Y)
	}
}
<|endoftext|>


<commit_before>package controllers

import (
	"github.com/mrjones/oauth"
	"github.com/revel/revel"

	"encoding/json"
	"fmt"

	"chant/conf/my"
)

// コンシューマの定義とプロバイダの定義を含んだ
// *oauth.Consumerをつくる
var twitter = oauth.NewConsumer(
	// コンシューマの定義
	my.AppTwitterConsumerKey,
	my.AppTwitterConsumerSecret,
	// プロバイダの定義
	oauth.ServiceProvider{
		AuthorizeTokenUrl: "https://api.twitter.com/oauth/authorize",
		RequestTokenUrl:   "https://api.twitter.com/oauth/request_token",
		AccessTokenUrl:    "https://api.twitter.com/oauth/access_token",
	},
)

type Auth struct {
	// embed
	*revel.Controller
}

func getCallbackURL() string {
	host, _ := revel.Config.String("http.host")
	port, _ := revel.Config.String("http.port")
	if port != "" {
		port = ":" + port
	}
	return fmt.Sprintf("http://%s%s/auth/callback", host, port)
}

func (c Auth) Index(oauth_verifier string) revel.Result {

	if _, nameExists := c.Session["screenName"]; nameExists {
		// 既にセッションを持っているのでルームにリダイレクトする
		return c.Redirect(Room.Index)
	}

	// oauth_verifierが無い状態でこのURLを叩いたとき
	// つまり、ユーザの最初のAuthenticateへのアクセスである

	// まずはverifier獲得した状態でリダイレクトするように促す
	// このアプリケーションのコンシューマキーとコンシューマシークレットを用いて
	// 一時的に使えるrequestTokenの取得を試みる
	requestToken, url, err := twitter.GetRequestTokenAndUrl(getCallbackURL())
	if err == nil {
		// 一時的に使えるrequestTokenが取得できたので、サーバ側で一次保存しておく
		c.Session["requestToken"] = requestToken.Token
		c.Session["requestSecret"] = requestToken.Secret
		// あとは、ユーザの問題
		// oauth_verifierを取ってきてもらう
		return c.Redirect(url)
	} else {
		revel.ERROR.Println(
			"そもそもコンシューマキーを用いてリクエストトークン取得できなかったで御座る",
			err,
		)
	}

	// 何が起きてもとりあえずトップへ飛ばす
	return c.Redirect(Application.Index)
}

func (c *Auth) Callback(oauth_verifier string) revel.Result {

	// TODO: oauth_verifierあるとか無いとか。
	// 　　: URL直打ちだったらあり得る

	// RequestTokenの復元
	requestToken := &oauth.RequestToken{
		c.Session["requestToken"],
		c.Session["requestSecret"],
	}
	// 不要になったので捨てる
	delete(c.Session, "requestToken")
	delete(c.Session, "requestSecret")
	// これと、oauth_verifierを用いてaccess_tokenを獲得する
	accessToken, err := twitter.AuthorizeToken(requestToken, oauth_verifier)
	if err == nil {
		// 成功したので、これを用いてユーザ情報を取得する
		resp, _ := twitter.Get(
			//"https://api.twitter.com/1.1/statuses/mentions_timeline.json",
			"https://api.twitter.com/1.1/account/verify_credentials.json",
			map[string]string{},
			accessToken,
		)
		defer resp.Body.Close()
		account := struct {
			Name            string `json:"name"`
			ProfileImageUrl string `json:"profile_image_url"`
			ScreenName      string `json:"screen_name"`
		}{}
		_ = json.NewDecoder(resp.Body).Decode(&account)
		// }}}
		// セッションに格納する
		c.Session["name"] = account.Name
		c.Session["screenName"] = account.ScreenName
		c.Session["profileImageUrl"] = account.ProfileImageUrl
	} else {
		// 失敗したので、エラーを吐く
		revel.ERROR.Println("requestTokenとoauth_verifierを用いてaccessTokenを得たかったけど失敗したの図:\t", err)
	}

	return c.Redirect(Application.Index)
}

func init() {
	// revel.Controller.*が実行されるときに必ず呼べる？
	// twitter.Debug(true)
}
<commit_msg>Use "auth.callback" if exists<commit_after>package controllers

import (
	"github.com/mrjones/oauth"
	"github.com/revel/revel"

	"encoding/json"
	"fmt"

	"chant/conf/my"
)

// コンシューマの定義とプロバイダの定義を含んだ
// *oauth.Consumerをつくる
var twitter = oauth.NewConsumer(
	// コンシューマの定義
	my.AppTwitterConsumerKey,
	my.AppTwitterConsumerSecret,
	// プロバイダの定義
	oauth.ServiceProvider{
		AuthorizeTokenUrl: "https://api.twitter.com/oauth/authorize",
		RequestTokenUrl:   "https://api.twitter.com/oauth/request_token",
		AccessTokenUrl:    "https://api.twitter.com/oauth/access_token",
	},
)

type Auth struct {
	// embed
	*revel.Controller
}

func getCallbackURL() string {
	if callback, ok := revel.Config.String("auth.callback"); ok && callback != "" {
		return fmt.Sprintf("http://%s/auth/callback", callback)
	}
	host, _ := revel.Config.String("http.host")
	port, _ := revel.Config.String("http.port")
	if port != "" {
		port = ":" + port
	}
	return fmt.Sprintf("http://%s%s/auth/callback", host, port)
}

func (c Auth) Index(oauth_verifier string) revel.Result {

	if _, nameExists := c.Session["screenName"]; nameExists {
		// 既にセッションを持っているのでルームにリダイレクトする
		return c.Redirect(Room.Index)
	}

	// oauth_verifierが無い状態でこのURLを叩いたとき
	// つまり、ユーザの最初のAuthenticateへのアクセスである

	// まずはverifier獲得した状態でリダイレクトするように促す
	// このアプリケーションのコンシューマキーとコンシューマシークレットを用いて
	// 一時的に使えるrequestTokenの取得を試みる
	requestToken, url, err := twitter.GetRequestTokenAndUrl(getCallbackURL())
	if err == nil {
		// 一時的に使えるrequestTokenが取得できたので、サーバ側で一次保存しておく
		c.Session["requestToken"] = requestToken.Token
		c.Session["requestSecret"] = requestToken.Secret
		// あとは、ユーザの問題
		// oauth_verifierを取ってきてもらう
		return c.Redirect(url)
	} else {
		revel.ERROR.Println(
			"そもそもコンシューマキーを用いてリクエストトークン取得できなかったで御座る",
			err,
		)
	}

	// 何が起きてもとりあえずトップへ飛ばす
	return c.Redirect(Application.Index)
}

func (c *Auth) Callback(oauth_verifier string) revel.Result {

	// TODO: oauth_verifierあるとか無いとか。
	// 　　: URL直打ちだったらあり得る

	// RequestTokenの復元
	requestToken := &oauth.RequestToken{
		c.Session["requestToken"],
		c.Session["requestSecret"],
	}
	// 不要になったので捨てる
	delete(c.Session, "requestToken")
	delete(c.Session, "requestSecret")
	// これと、oauth_verifierを用いてaccess_tokenを獲得する
	accessToken, err := twitter.AuthorizeToken(requestToken, oauth_verifier)
	if err == nil {
		// 成功したので、これを用いてユーザ情報を取得する
		resp, _ := twitter.Get(
			//"https://api.twitter.com/1.1/statuses/mentions_timeline.json",
			"https://api.twitter.com/1.1/account/verify_credentials.json",
			map[string]string{},
			accessToken,
		)
		defer resp.Body.Close()
		account := struct {
			Name            string `json:"name"`
			ProfileImageUrl string `json:"profile_image_url"`
			ScreenName      string `json:"screen_name"`
		}{}
		_ = json.NewDecoder(resp.Body).Decode(&account)
		// }}}
		// セッションに格納する
		c.Session["name"] = account.Name
		c.Session["screenName"] = account.ScreenName
		c.Session["profileImageUrl"] = account.ProfileImageUrl
	} else {
		// 失敗したので、エラーを吐く
		revel.ERROR.Println("requestTokenとoauth_verifierを用いてaccessTokenを得たかったけど失敗したの図:\t", err)
	}

	return c.Redirect(Application.Index)
}

func init() {
	// revel.Controller.*が実行されるときに必ず呼べる？
	// twitter.Debug(true)
}
<|endoftext|>


<commit_before>package engine

// Location is set of dots
type Location []Dot

// contains returns true if object contains passed dot
func (l Location) Contains(dot Dot) bool {
	if len(l) > 0 {
		for _, d := range l {
			if d.Equals(dot) {
				return true
			}
		}
	}

	return false
}

// Delete deletes dot from object
func (l Location) Delete(dot Dot) Location {
	newLocation := l.Copy()

	if len(l) > 0 {
		for i := range l {
			if l[i].Equals(dot) {
				return append(newLocation[:i], newLocation[i+1:]...)
			}
		}
	}

	return newLocation
}

func (l Location) Add(dot Dot) Location {
	newLocation := l.Copy()
	return append(newLocation, dot)
}

// TODO: Remove this method (?)
// Reverse reverses dot sequence in object
func (l Location) Reverse() Location {
	if len(l) > 0 {
		ro := make(Location, 0, len(l))
		for i := len(l) - 1; i >= 0; i-- {
			ro = append(ro, l[i])
		}

		return ro
	}

	return Location{}
}

func (l Location) Dot(i uint16) Dot {
	return l[i]
}

func (l Location) DotCount() uint16 {
	return uint16(len(l))
}

func (l Location) Empty() bool {
	return len(l) == 0
}

func (l Location) Copy() Location {
	newLocation := make(Location, len(l))
	copy(newLocation, l)

	return newLocation
}

func (l1 Location) Equals(l2 Location) bool {
	if len(l1) == 0 && len(l2) == 0 {
		return true
	}

	if len(l1) != len(l2) {
		return false
	}

	if len(l1.Difference(l2)) > 0 {
		return false
	}

	return true
}

func (l1 Location) EqualsStrict(l2 Location) bool {
	if len(l1) == 0 && len(l2) == 0 {
		return true
	}

	if len(l1) != len(l2) {
		return false
	}

	for i := 0; i < len(l1); i++ {
		if !l1[i].Equals(l2[i]) {
			return false
		}
	}

	return true
}

func (l1 Location) Difference(l2 Location) Location {
	var diff Location

	for i := 0; i < 2; i++ {
		for _, dot1 := range l1 {
			found := false
			for _, dot2 := range l2 {
				if dot1.Equals(dot2) {
					found = true
					break
				}
			}
			if !found {
				diff = append(diff, dot1)
			}
		}
		if i == 0 {
			l1, l2 = l2, l1
		}
	}

	return diff
}

func (l1 Location) Intersection(l2 Location) (intersection Location) {
	low, high := l1, l2
	if len(l1) > len(l2) {
		low = l2
		high = l1
	}

	done := false
	for i, l := range low {
		for j, h := range high {
			f1 := i + 1
			f2 := j + 1
			if l.Equals(h) {
				intersection = append(intersection, h)
				if f1 < len(low) && f2 < len(high) {
					if !low[f1].Equals(high[f2]) {
						done = true
					}
				}
				high = high[:j+copy(high[j:], high[j+1:])]
				break
			}
		}
		if done {
			break
		}
	}
	return
}
<commit_msg>Create to engine.Location method Hash<commit_after>package engine

// Location is set of dots
type Location []Dot

// contains returns true if object contains passed dot
func (l Location) Contains(dot Dot) bool {
	if len(l) > 0 {
		for _, d := range l {
			if d.Equals(dot) {
				return true
			}
		}
	}

	return false
}

// Delete deletes dot from object
func (l Location) Delete(dot Dot) Location {
	newLocation := l.Copy()

	if len(l) > 0 {
		for i := range l {
			if l[i].Equals(dot) {
				return append(newLocation[:i], newLocation[i+1:]...)
			}
		}
	}

	return newLocation
}

func (l Location) Add(dot Dot) Location {
	newLocation := l.Copy()
	return append(newLocation, dot)
}

// TODO: Remove this method (?)
// Reverse reverses dot sequence in object
func (l Location) Reverse() Location {
	if len(l) > 0 {
		ro := make(Location, 0, len(l))
		for i := len(l) - 1; i >= 0; i-- {
			ro = append(ro, l[i])
		}

		return ro
	}

	return Location{}
}

func (l Location) Dot(i uint16) Dot {
	return l[i]
}

func (l Location) DotCount() uint16 {
	return uint16(len(l))
}

func (l Location) Empty() bool {
	return len(l) == 0
}

func (l Location) Copy() Location {
	newLocation := make(Location, len(l))
	copy(newLocation, l)

	return newLocation
}

func (l1 Location) Equals(l2 Location) bool {
	if len(l1) == 0 && len(l2) == 0 {
		return true
	}

	if len(l1) != len(l2) {
		return false
	}

	if len(l1.Difference(l2)) > 0 {
		return false
	}

	return true
}

func (l1 Location) EqualsStrict(l2 Location) bool {
	if len(l1) == 0 && len(l2) == 0 {
		return true
	}

	if len(l1) != len(l2) {
		return false
	}

	for i := 0; i < len(l1); i++ {
		if !l1[i].Equals(l2[i]) {
			return false
		}
	}

	return true
}

func (l1 Location) Difference(l2 Location) Location {
	var diff Location

	for i := 0; i < 2; i++ {
		for _, dot1 := range l1 {
			found := false
			for _, dot2 := range l2 {
				if dot1.Equals(dot2) {
					found = true
					break
				}
			}
			if !found {
				diff = append(diff, dot1)
			}
		}
		if i == 0 {
			l1, l2 = l2, l1
		}
	}

	return diff
}

func (l1 Location) Intersection(l2 Location) (intersection Location) {
	low, high := l1, l2
	if len(l1) > len(l2) {
		low = l2
		high = l1
	}

	done := false
	for i, l := range low {
		for j, h := range high {
			f1 := i + 1
			f2 := j + 1
			if l.Equals(h) {
				intersection = append(intersection, h)
				if f1 < len(low) && f2 < len(high) {
					if !low[f1].Equals(high[f2]) {
						done = true
					}
				}
				high = high[:j+copy(high[j:], high[j+1:])]
				break
			}
		}
		if done {
			break
		}
	}
	return
}

func (l Location) Hash() []uint16 {
	hash := make([]uint16, 0, len(l))
	for _, dot := range l {
		hash = append(hash, dot.Hash())
	}
	return hash
}
<|endoftext|>


<commit_before>package task

import (
	"context"
	"errors"
	"strconv"
	"strings"
	"time"

	"github.com/apache/servicecomb-service-center/pkg/log"
	"github.com/apache/servicecomb-service-center/pkg/util"
	apt "github.com/apache/servicecomb-service-center/server/core"
	pb "github.com/apache/servicecomb-service-center/server/core/proto"
	serviceUtil "github.com/apache/servicecomb-service-center/server/service/util"
)

// ClearNoInstanceService clears services which have no instance
func ClearNoInstanceServices(serviceTTL time.Duration) error {
	services, err := serviceUtil.GetAllServicesAcrossDomainProject(context.Background())
	if err != nil {
		return err
	}
	if len(services) == 0 {
		log.Info("no service found, no need to clear")
		return nil
	}
	timeLimit := time.Now().Add(0 - serviceTTL)
	log.Infof("clear no-instance services created before %s", timeLimit)
	timeLimitStamp := strconv.FormatInt(timeLimit.Unix(), 10)

	for domainProject, svcList := range services {
		if len(svcList) == 0 {
			continue
		}
		ctx, err := ctxFromDomainProject(domainProject)
		if err != nil {
			log.Errorf(err, "get domain project context failed")
			continue
		}
		for _, svc := range svcList {
			if svc == nil {
				continue
			}
			ok, err := shouldClear(ctx, timeLimitStamp, svc)
			if err != nil {
				log.Errorf(err, "check service clear necessity failed")
				continue
			}
			if !ok {
				continue
			}
			//delete this service
			svcCtxStr := "domainProject: " + domainProject + ", " +
				"env: " + svc.Environment + ", " +
				"service: " + util.StringJoin([]string{svc.AppId, svc.ServiceName, svc.Version}, apt.SPLIT)
			delSvcReq := &pb.DeleteServiceRequest{
				ServiceId: svc.ServiceId,
				Force:     true, //force delete
			}
			delSvcResp, err := apt.ServiceAPI.Delete(ctx, delSvcReq)
			if err != nil {
				log.Errorf(err, "clear service failed, %s", svcCtxStr)
				continue
			}
			if delSvcResp.Response.GetCode() != pb.Response_SUCCESS {
				log.Errorf(nil, "clear service failed, %s, %s", delSvcResp.Response.GetMessage(), svcCtxStr)
				continue
			}
			log.Warnf("clear service success, %s", svcCtxStr)
		}
	}
	return nil
}

func ctxFromDomainProject(domainProject string) (ctx context.Context, err error) {
	splitIndex := strings.Index(domainProject, apt.SPLIT)
	if splitIndex == -1 {
		return nil, errors.New("invalid domainProject: " + domainProject)
	}
	domain := domainProject[:splitIndex]
	project := domainProject[splitIndex+1:]
	return util.SetDomainProject(context.Background(), domain, project), nil
}

//check whether a service should be cleared
func shouldClear(ctx context.Context, timeLimitStamp string, svc *pb.MicroService) (bool, error) {
	//ignore a service if it is created after timeLimitStamp
	if svc.Timestamp > timeLimitStamp {
		return false, nil
	}
	getInstsReq := &pb.GetInstancesRequest{
		ConsumerServiceId: svc.ServiceId,
		ProviderServiceId: svc.ServiceId,
	}
	getInstsResp, err := apt.InstanceAPI.GetInstances(ctx, getInstsReq)
	if err != nil {
		return false, err
	}
	if getInstsResp.Response.GetCode() != pb.Response_SUCCESS {
		return false, errors.New("get instance failed: " + getInstsResp.Response.GetMessage())
	}
	//ignore a service if it has instances
	if len(getInstsResp.Instances) > 0 {
		return false, nil
	}
	return true, nil
}
<commit_msg>Update clear_service.go<commit_after>// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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 task

import (
	"context"
	"errors"
	"strconv"
	"strings"
	"time"

	"github.com/apache/servicecomb-service-center/pkg/log"
	"github.com/apache/servicecomb-service-center/pkg/util"
	apt "github.com/apache/servicecomb-service-center/server/core"
	pb "github.com/apache/servicecomb-service-center/server/core/proto"
	serviceUtil "github.com/apache/servicecomb-service-center/server/service/util"
)

// ClearNoInstanceService clears services which have no instance
func ClearNoInstanceServices(serviceTTL time.Duration) error {
	services, err := serviceUtil.GetAllServicesAcrossDomainProject(context.Background())
	if err != nil {
		return err
	}
	if len(services) == 0 {
		log.Info("no service found, no need to clear")
		return nil
	}
	timeLimit := time.Now().Add(0 - serviceTTL)
	log.Infof("clear no-instance services created before %s", timeLimit)
	timeLimitStamp := strconv.FormatInt(timeLimit.Unix(), 10)

	for domainProject, svcList := range services {
		if len(svcList) == 0 {
			continue
		}
		ctx, err := ctxFromDomainProject(domainProject)
		if err != nil {
			log.Errorf(err, "get domain project context failed")
			continue
		}
		for _, svc := range svcList {
			if svc == nil {
				continue
			}
			ok, err := shouldClear(ctx, timeLimitStamp, svc)
			if err != nil {
				log.Errorf(err, "check service clear necessity failed")
				continue
			}
			if !ok {
				continue
			}
			//delete this service
			svcCtxStr := "domainProject: " + domainProject + ", " +
				"env: " + svc.Environment + ", " +
				"service: " + util.StringJoin([]string{svc.AppId, svc.ServiceName, svc.Version}, apt.SPLIT)
			delSvcReq := &pb.DeleteServiceRequest{
				ServiceId: svc.ServiceId,
				Force:     true, //force delete
			}
			delSvcResp, err := apt.ServiceAPI.Delete(ctx, delSvcReq)
			if err != nil {
				log.Errorf(err, "clear service failed, %s", svcCtxStr)
				continue
			}
			if delSvcResp.Response.GetCode() != pb.Response_SUCCESS {
				log.Errorf(nil, "clear service failed, %s, %s", delSvcResp.Response.GetMessage(), svcCtxStr)
				continue
			}
			log.Warnf("clear service success, %s", svcCtxStr)
		}
	}
	return nil
}

func ctxFromDomainProject(domainProject string) (ctx context.Context, err error) {
	splitIndex := strings.Index(domainProject, apt.SPLIT)
	if splitIndex == -1 {
		return nil, errors.New("invalid domainProject: " + domainProject)
	}
	domain := domainProject[:splitIndex]
	project := domainProject[splitIndex+1:]
	return util.SetDomainProject(context.Background(), domain, project), nil
}

//check whether a service should be cleared
func shouldClear(ctx context.Context, timeLimitStamp string, svc *pb.MicroService) (bool, error) {
	//ignore a service if it is created after timeLimitStamp
	if svc.Timestamp > timeLimitStamp {
		return false, nil
	}
	getInstsReq := &pb.GetInstancesRequest{
		ConsumerServiceId: svc.ServiceId,
		ProviderServiceId: svc.ServiceId,
	}
	getInstsResp, err := apt.InstanceAPI.GetInstances(ctx, getInstsReq)
	if err != nil {
		return false, err
	}
	if getInstsResp.Response.GetCode() != pb.Response_SUCCESS {
		return false, errors.New("get instance failed: " + getInstsResp.Response.GetMessage())
	}
	//ignore a service if it has instances
	if len(getInstsResp.Instances) > 0 {
		return false, nil
	}
	return true, nil
}
<|endoftext|>


<commit_before>// Licensed to The Moov Authors under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. The Moov Authors licenses this file to you 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 ach

// Version Number
const Version = "v1.6.2"
<commit_msg>release v1.6.4<commit_after>// Licensed to The Moov Authors under one or more contributor
// license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright
// ownership. The Moov Authors licenses this file to you 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 ach

// Version Number
const Version = "v1.6.4"
<|endoftext|>


<commit_before>package controller

import (
	"bytes"
	"errors"
	"fmt"
	"time"

	"github.com/appscode/log"
	"github.com/ghodss/yaml"
	"github.com/graymeta/stow"
	_ "github.com/graymeta/stow/google"
	_ "github.com/graymeta/stow/s3"
	tapi "github.com/k8sdb/apimachinery/api"
	"github.com/k8sdb/apimachinery/pkg/eventer"
	kapi "k8s.io/kubernetes/pkg/api"
	k8serr "k8s.io/kubernetes/pkg/api/errors"
	kapps "k8s.io/kubernetes/pkg/apis/apps"
	kbatch "k8s.io/kubernetes/pkg/apis/batch"
	"k8s.io/kubernetes/pkg/client/record"
	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/runtime"
)

func (c *Controller) ValidateStorageSpec(spec *tapi.StorageSpec) (*tapi.StorageSpec, error) {
	if spec == nil {
		return nil, nil
	}

	if spec.Class == "" {
		return nil, fmt.Errorf(`Object 'Class' is missing in '%v'`, *spec)
	}

	if _, err := c.Client.Storage().StorageClasses().Get(spec.Class); err != nil {
		if k8serr.IsNotFound(err) {
			return nil, fmt.Errorf(`Spec.Storage.Class "%v" not found`, spec.Class)
		}
		return nil, err
	}

	if len(spec.AccessModes) == 0 {
		spec.AccessModes = []kapi.PersistentVolumeAccessMode{
			kapi.ReadWriteOnce,
		}
		log.Infof(`Using "%v" as AccessModes in "%v"`, kapi.ReadWriteOnce, *spec)
	}

	if val, found := spec.Resources.Requests[kapi.ResourceStorage]; found {
		if val.Value() <= 0 {
			return nil, errors.New("Invalid ResourceStorage request")
		}
	} else {
		return nil, errors.New("Missing ResourceStorage request")
	}

	return spec, nil
}

func (c *Controller) ValidateBackupSchedule(spec *tapi.BackupScheduleSpec) error {
	if spec == nil {
		return nil
	}
	// CronExpression can't be empty
	if spec.CronExpression == "" {
		return errors.New("Invalid cron expression")
	}

	return c.ValidateSnapshotSpec(spec.SnapshotSpec)
}

func (c *Controller) ValidateSnapshotSpec(spec tapi.SnapshotSpec) error {
	// BucketName can't be empty
	bucketName := spec.BucketName
	if bucketName == "" {
		return fmt.Errorf(`Object 'BucketName' is missing in '%v'`, spec)
	}

	// Need to provide Storage credential secret
	storageSecret := spec.StorageSecret
	if storageSecret == nil {
		return fmt.Errorf(`Object 'StorageSecret' is missing in '%v'`, spec)
	}

	// Credential SecretName  can't be empty
	storageSecretName := storageSecret.SecretName
	if storageSecretName == "" {
		return fmt.Errorf(`Object 'SecretName' is missing in '%v'`, *spec.StorageSecret)
	}
	return nil
}

const (
	keyProvider = "provider"
	keyConfig   = "config"
)

func (c *Controller) CheckBucketAccess(snapshotSpec tapi.SnapshotSpec, namespace string) error {
	secret, err := c.Client.Core().Secrets(namespace).Get(snapshotSpec.StorageSecret.SecretName)
	if err != nil {
		return err
	}

	provider := secret.Data[keyProvider]
	if provider == nil {
		return errors.New("Missing provider key")
	}
	configData := secret.Data[keyConfig]
	if configData == nil {
		return errors.New("Missing config key")
	}

	var config stow.ConfigMap
	if err := yaml.Unmarshal(configData, &config); err != nil {
		return err
	}

	loc, err := stow.Dial(string(provider), config)
	if err != nil {
		return err
	}

	container, err := loc.Container(snapshotSpec.BucketName)
	if err != nil {
		return err
	}

	r := bytes.NewReader([]byte("CheckBucketAccess"))
	item, err := container.Put(".k8sdb", r, r.Size(), nil)
	if err != nil {
		return err
	}

	if err := container.RemoveItem(item.ID()); err != nil {
		return err
	}
	return nil
}

func (c *Controller) CreateGoverningServiceAccount(name, namespace string) error {
	var err error
	if _, err = c.Client.Core().ServiceAccounts(namespace).Get(name); err == nil {
		return nil
	}
	if !k8serr.IsNotFound(err) {
		return err
	}

	serviceAccount := &kapi.ServiceAccount{
		ObjectMeta: kapi.ObjectMeta{
			Name: name,
		},
	}
	_, err = c.Client.Core().ServiceAccounts(namespace).Create(serviceAccount)
	return err
}

func (c *Controller) CheckStatefulSetPodStatus(statefulSet *kapps.StatefulSet, checkDuration time.Duration) error {
	podName := fmt.Sprintf("%v-%v", statefulSet.Name, 0)

	podReady := false
	then := time.Now()
	now := time.Now()
	for now.Sub(then) < checkDuration {
		pod, err := c.Client.Core().Pods(statefulSet.Namespace).Get(podName)
		if err != nil {
			if k8serr.IsNotFound(err) {
				_, err := c.Client.Apps().StatefulSets(statefulSet.Namespace).Get(statefulSet.Name)
				if k8serr.IsNotFound(err) {
					break
				}

				time.Sleep(time.Second * 10)
				now = time.Now()
				continue
			} else {
				return err
			}
		}
		log.Debugf("Pod Phase: %v", pod.Status.Phase)

		// If job is success
		if pod.Status.Phase == kapi.PodRunning {
			podReady = true
			break
		}

		time.Sleep(time.Minute)
		now = time.Now()
	}
	if !podReady {
		return errors.New("Database fails to be Ready")
	}
	return nil
}

func (c *Controller) DeletePersistentVolumeClaims(namespace string, selector labels.Selector) error {
	pvcList, err := c.Client.Core().PersistentVolumeClaims(namespace).List(
		kapi.ListOptions{
			LabelSelector: selector,
		},
	)
	if err != nil {
		return err
	}

	for _, pvc := range pvcList.Items {
		if err := c.Client.Core().PersistentVolumeClaims(pvc.Namespace).Delete(pvc.Name, nil); err != nil {
			return err
		}
	}
	return nil
}

func (c *Controller) DeleteSnapshotData(dbSnapshot *tapi.DatabaseSnapshot) error {
	secret, err := c.Client.Core().Secrets(dbSnapshot.Namespace).Get(dbSnapshot.Spec.StorageSecret.SecretName)
	if err != nil {
		return err
	}

	provider := secret.Data[keyProvider]
	if provider == nil {
		return errors.New("Missing provider key")
	}
	configData := secret.Data[keyConfig]
	if configData == nil {
		return errors.New("Missing config key")
	}

	var config stow.ConfigMap
	if err := yaml.Unmarshal(configData, &config); err != nil {
		return err
	}

	loc, err := stow.Dial(string(provider), config)
	if err != nil {
		return err
	}

	container, err := loc.Container(dbSnapshot.Spec.BucketName)
	if err != nil {
		return err
	}

	prefix := fmt.Sprintf("%v/%v/%v/%v", DatabaseNamePrefix, dbSnapshot.Namespace, dbSnapshot.Spec.DatabaseName, dbSnapshot.Name)
	cursor := stow.CursorStart
	for {
		items, next, err := container.Items(prefix, cursor, 50)
		if err != nil {
			return err
		}
		for _, item := range items {
			if err := container.RemoveItem(item.ID()); err != nil {
				return err
			}
		}
		cursor = next
		if stow.IsCursorEnd(cursor) {
			break
		}
	}

	return nil
}

func (c *Controller) DeleteDatabaseSnapshots(namespace string, selector labels.Selector) error {
	dbSnapshotList, err := c.ExtClient.DatabaseSnapshots(namespace).List(
		kapi.ListOptions{
			LabelSelector: selector,
		},
	)
	if err != nil {
		return err
	}

	for _, dbsnapshot := range dbSnapshotList.Items {
		if err := c.ExtClient.DatabaseSnapshots(dbsnapshot.Namespace).Delete(dbsnapshot.Name); err != nil {
			return err
		}
	}
	return nil
}

func (c *Controller) CheckDatabaseRestoreJob(
	job *kbatch.Job,
	runtimeObj runtime.Object,
	recorder record.EventRecorder,
	checkDuration time.Duration,
) bool {
	var jobSuccess bool = false
	var err error

	then := time.Now()
	now := time.Now()
	for now.Sub(then) < checkDuration {
		log.Debugln("Checking for Job ", job.Name)
		job, err = c.Client.Batch().Jobs(job.Namespace).Get(job.Name)
		if err != nil {
			recorder.Eventf(
				runtimeObj,
				kapi.EventTypeWarning,
				eventer.EventReasonFailedToList,
				"Failed to get Job. Reason: %v",
				err,
			)
			log.Errorln(err)
			return jobSuccess
		}
		log.Debugf("Pods Statuses:	%d Running / %d Succeeded / %d Failed",
			job.Status.Active, job.Status.Succeeded, job.Status.Failed)
		// If job is success
		if job.Status.Succeeded > 0 {
			jobSuccess = true
			break
		} else if job.Status.Failed > 0 {
			break
		}

		time.Sleep(time.Minute)
		now = time.Now()
	}

	podList, err := c.Client.Core().Pods(job.Namespace).List(
		kapi.ListOptions{
			LabelSelector: labels.SelectorFromSet(job.Spec.Selector.MatchLabels),
		},
	)
	if err != nil {
		recorder.Eventf(
			runtimeObj,
			kapi.EventTypeWarning,
			eventer.EventReasonFailedToList,
			"Failed to list Pods. Reason: %v",
			err,
		)
		log.Errorln(err)
		return jobSuccess
	}

	for _, pod := range podList.Items {
		if err := c.Client.Core().Pods(pod.Namespace).Delete(pod.Name, nil); err != nil {
			recorder.Eventf(
				runtimeObj,
				kapi.EventTypeWarning,
				eventer.EventReasonFailedToDelete,
				"Failed to delete Pod. Reason: %v",
				err,
			)
			log.Errorln(err)
		}
	}

	for _, volume := range job.Spec.Template.Spec.Volumes {
		claim := volume.PersistentVolumeClaim
		if claim != nil {
			err := c.Client.Core().PersistentVolumeClaims(job.Namespace).Delete(claim.ClaimName, nil)
			if err != nil {
				recorder.Eventf(
					runtimeObj,
					kapi.EventTypeWarning,
					eventer.EventReasonFailedToDelete,
					"Failed to delete PersistentVolumeClaim. Reason: %v",
					err,
				)
				log.Errorln(err)
			}
		}
	}

	if err := c.Client.Batch().Jobs(job.Namespace).Delete(job.Name, nil); err != nil {
		recorder.Eventf(
			runtimeObj,
			kapi.EventTypeWarning,
			eventer.EventReasonFailedToDelete,
			"Failed to delete Job. Reason: %v",
			err,
		)
		log.Errorln(err)
	}

	return jobSuccess
}
<commit_msg>Do not need ServiceAccount (#49)<commit_after>package controller

import (
	"bytes"
	"errors"
	"fmt"
	"time"

	"github.com/appscode/log"
	"github.com/ghodss/yaml"
	"github.com/graymeta/stow"
	_ "github.com/graymeta/stow/google"
	_ "github.com/graymeta/stow/s3"
	tapi "github.com/k8sdb/apimachinery/api"
	"github.com/k8sdb/apimachinery/pkg/eventer"
	kapi "k8s.io/kubernetes/pkg/api"
	k8serr "k8s.io/kubernetes/pkg/api/errors"
	kapps "k8s.io/kubernetes/pkg/apis/apps"
	kbatch "k8s.io/kubernetes/pkg/apis/batch"
	"k8s.io/kubernetes/pkg/client/record"
	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/runtime"
)

func (c *Controller) ValidateStorageSpec(spec *tapi.StorageSpec) (*tapi.StorageSpec, error) {
	if spec == nil {
		return nil, nil
	}

	if spec.Class == "" {
		return nil, fmt.Errorf(`Object 'Class' is missing in '%v'`, *spec)
	}

	if _, err := c.Client.Storage().StorageClasses().Get(spec.Class); err != nil {
		if k8serr.IsNotFound(err) {
			return nil, fmt.Errorf(`Spec.Storage.Class "%v" not found`, spec.Class)
		}
		return nil, err
	}

	if len(spec.AccessModes) == 0 {
		spec.AccessModes = []kapi.PersistentVolumeAccessMode{
			kapi.ReadWriteOnce,
		}
		log.Infof(`Using "%v" as AccessModes in "%v"`, kapi.ReadWriteOnce, *spec)
	}

	if val, found := spec.Resources.Requests[kapi.ResourceStorage]; found {
		if val.Value() <= 0 {
			return nil, errors.New("Invalid ResourceStorage request")
		}
	} else {
		return nil, errors.New("Missing ResourceStorage request")
	}

	return spec, nil
}

func (c *Controller) ValidateBackupSchedule(spec *tapi.BackupScheduleSpec) error {
	if spec == nil {
		return nil
	}
	// CronExpression can't be empty
	if spec.CronExpression == "" {
		return errors.New("Invalid cron expression")
	}

	return c.ValidateSnapshotSpec(spec.SnapshotSpec)
}

func (c *Controller) ValidateSnapshotSpec(spec tapi.SnapshotSpec) error {
	// BucketName can't be empty
	bucketName := spec.BucketName
	if bucketName == "" {
		return fmt.Errorf(`Object 'BucketName' is missing in '%v'`, spec)
	}

	// Need to provide Storage credential secret
	storageSecret := spec.StorageSecret
	if storageSecret == nil {
		return fmt.Errorf(`Object 'StorageSecret' is missing in '%v'`, spec)
	}

	// Credential SecretName  can't be empty
	storageSecretName := storageSecret.SecretName
	if storageSecretName == "" {
		return fmt.Errorf(`Object 'SecretName' is missing in '%v'`, *spec.StorageSecret)
	}
	return nil
}

const (
	keyProvider = "provider"
	keyConfig   = "config"
)

func (c *Controller) CheckBucketAccess(snapshotSpec tapi.SnapshotSpec, namespace string) error {
	secret, err := c.Client.Core().Secrets(namespace).Get(snapshotSpec.StorageSecret.SecretName)
	if err != nil {
		return err
	}

	provider := secret.Data[keyProvider]
	if provider == nil {
		return errors.New("Missing provider key")
	}
	configData := secret.Data[keyConfig]
	if configData == nil {
		return errors.New("Missing config key")
	}

	var config stow.ConfigMap
	if err := yaml.Unmarshal(configData, &config); err != nil {
		return err
	}

	loc, err := stow.Dial(string(provider), config)
	if err != nil {
		return err
	}

	container, err := loc.Container(snapshotSpec.BucketName)
	if err != nil {
		return err
	}

	r := bytes.NewReader([]byte("CheckBucketAccess"))
	item, err := container.Put(".k8sdb", r, r.Size(), nil)
	if err != nil {
		return err
	}

	if err := container.RemoveItem(item.ID()); err != nil {
		return err
	}
	return nil
}

func (c *Controller) CheckStatefulSetPodStatus(statefulSet *kapps.StatefulSet, checkDuration time.Duration) error {
	podName := fmt.Sprintf("%v-%v", statefulSet.Name, 0)

	podReady := false
	then := time.Now()
	now := time.Now()
	for now.Sub(then) < checkDuration {
		pod, err := c.Client.Core().Pods(statefulSet.Namespace).Get(podName)
		if err != nil {
			if k8serr.IsNotFound(err) {
				_, err := c.Client.Apps().StatefulSets(statefulSet.Namespace).Get(statefulSet.Name)
				if k8serr.IsNotFound(err) {
					break
				}

				time.Sleep(time.Second * 10)
				now = time.Now()
				continue
			} else {
				return err
			}
		}
		log.Debugf("Pod Phase: %v", pod.Status.Phase)

		// If job is success
		if pod.Status.Phase == kapi.PodRunning {
			podReady = true
			break
		}

		time.Sleep(time.Minute)
		now = time.Now()
	}
	if !podReady {
		return errors.New("Database fails to be Ready")
	}
	return nil
}

func (c *Controller) DeletePersistentVolumeClaims(namespace string, selector labels.Selector) error {
	pvcList, err := c.Client.Core().PersistentVolumeClaims(namespace).List(
		kapi.ListOptions{
			LabelSelector: selector,
		},
	)
	if err != nil {
		return err
	}

	for _, pvc := range pvcList.Items {
		if err := c.Client.Core().PersistentVolumeClaims(pvc.Namespace).Delete(pvc.Name, nil); err != nil {
			return err
		}
	}
	return nil
}

func (c *Controller) DeleteSnapshotData(dbSnapshot *tapi.DatabaseSnapshot) error {
	secret, err := c.Client.Core().Secrets(dbSnapshot.Namespace).Get(dbSnapshot.Spec.StorageSecret.SecretName)
	if err != nil {
		return err
	}

	provider := secret.Data[keyProvider]
	if provider == nil {
		return errors.New("Missing provider key")
	}
	configData := secret.Data[keyConfig]
	if configData == nil {
		return errors.New("Missing config key")
	}

	var config stow.ConfigMap
	if err := yaml.Unmarshal(configData, &config); err != nil {
		return err
	}

	loc, err := stow.Dial(string(provider), config)
	if err != nil {
		return err
	}

	container, err := loc.Container(dbSnapshot.Spec.BucketName)
	if err != nil {
		return err
	}

	prefix := fmt.Sprintf("%v/%v/%v/%v", DatabaseNamePrefix, dbSnapshot.Namespace, dbSnapshot.Spec.DatabaseName, dbSnapshot.Name)
	cursor := stow.CursorStart
	for {
		items, next, err := container.Items(prefix, cursor, 50)
		if err != nil {
			return err
		}
		for _, item := range items {
			if err := container.RemoveItem(item.ID()); err != nil {
				return err
			}
		}
		cursor = next
		if stow.IsCursorEnd(cursor) {
			break
		}
	}

	return nil
}

func (c *Controller) DeleteDatabaseSnapshots(namespace string, selector labels.Selector) error {
	dbSnapshotList, err := c.ExtClient.DatabaseSnapshots(namespace).List(
		kapi.ListOptions{
			LabelSelector: selector,
		},
	)
	if err != nil {
		return err
	}

	for _, dbsnapshot := range dbSnapshotList.Items {
		if err := c.ExtClient.DatabaseSnapshots(dbsnapshot.Namespace).Delete(dbsnapshot.Name); err != nil {
			return err
		}
	}
	return nil
}

func (c *Controller) CheckDatabaseRestoreJob(
	job *kbatch.Job,
	runtimeObj runtime.Object,
	recorder record.EventRecorder,
	checkDuration time.Duration,
) bool {
	var jobSuccess bool = false
	var err error

	then := time.Now()
	now := time.Now()
	for now.Sub(then) < checkDuration {
		log.Debugln("Checking for Job ", job.Name)
		job, err = c.Client.Batch().Jobs(job.Namespace).Get(job.Name)
		if err != nil {
			recorder.Eventf(
				runtimeObj,
				kapi.EventTypeWarning,
				eventer.EventReasonFailedToList,
				"Failed to get Job. Reason: %v",
				err,
			)
			log.Errorln(err)
			return jobSuccess
		}
		log.Debugf("Pods Statuses:	%d Running / %d Succeeded / %d Failed",
			job.Status.Active, job.Status.Succeeded, job.Status.Failed)
		// If job is success
		if job.Status.Succeeded > 0 {
			jobSuccess = true
			break
		} else if job.Status.Failed > 0 {
			break
		}

		time.Sleep(time.Minute)
		now = time.Now()
	}

	podList, err := c.Client.Core().Pods(job.Namespace).List(
		kapi.ListOptions{
			LabelSelector: labels.SelectorFromSet(job.Spec.Selector.MatchLabels),
		},
	)
	if err != nil {
		recorder.Eventf(
			runtimeObj,
			kapi.EventTypeWarning,
			eventer.EventReasonFailedToList,
			"Failed to list Pods. Reason: %v",
			err,
		)
		log.Errorln(err)
		return jobSuccess
	}

	for _, pod := range podList.Items {
		if err := c.Client.Core().Pods(pod.Namespace).Delete(pod.Name, nil); err != nil {
			recorder.Eventf(
				runtimeObj,
				kapi.EventTypeWarning,
				eventer.EventReasonFailedToDelete,
				"Failed to delete Pod. Reason: %v",
				err,
			)
			log.Errorln(err)
		}
	}

	for _, volume := range job.Spec.Template.Spec.Volumes {
		claim := volume.PersistentVolumeClaim
		if claim != nil {
			err := c.Client.Core().PersistentVolumeClaims(job.Namespace).Delete(claim.ClaimName, nil)
			if err != nil {
				recorder.Eventf(
					runtimeObj,
					kapi.EventTypeWarning,
					eventer.EventReasonFailedToDelete,
					"Failed to delete PersistentVolumeClaim. Reason: %v",
					err,
				)
				log.Errorln(err)
			}
		}
	}

	if err := c.Client.Batch().Jobs(job.Namespace).Delete(job.Name, nil); err != nil {
		recorder.Eventf(
			runtimeObj,
			kapi.EventTypeWarning,
			eventer.EventReasonFailedToDelete,
			"Failed to delete Job. Reason: %v",
			err,
		)
		log.Errorln(err)
	}

	return jobSuccess
}
<|endoftext|>


<commit_before>// Copyright © 2017 Circonus, Inc. <support@circonus.com>
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//

package config

// ParseListen parses and fixes listen spec
import (
	"net"
	"regexp"
	"strings"

	"github.com/circonus-labs/circonus-agent/internal/config/defaults"
	"github.com/pkg/errors"
)

func ParseListen(spec string) (*net.TCPAddr, error) {
	// empty, default
	if spec == "" {
		spec = defaults.Listen
	}
	// only a port, prefix with colon
	if ok, _ := regexp.MatchString(`^[0-9]+$`, spec); ok {
		spec = ":" + spec
	}
	// ipv4 w/o port, add default
	if strings.Contains(spec, ".") && !strings.Contains(spec, ":") {
		spec += defaults.Listen
	}
	// ipv6 w/o port, add default
	if ok, _ := regexp.MatchString(`^\[[a-f0-9:]+\]$`, spec); ok {
		spec += defaults.Listen
	}

	host, port, err := net.SplitHostPort(spec)
	if err != nil {
		return nil, errors.Wrap(err, "parsing listen")
	}

	addr, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(host, port))
	if err != nil {
		return nil, errors.Wrap(err, "resolving listen")
	}

	return addr, nil
}
<commit_msg>doc: comment ParseListen<commit_after>// Copyright © 2017 Circonus, Inc. <support@circonus.com>
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//

package config

// ParseListen parses and fixes listen spec
import (
	"net"
	"regexp"
	"strings"

	"github.com/circonus-labs/circonus-agent/internal/config/defaults"
	"github.com/pkg/errors"
)

// ParseListen verifies and parses a listen address spec
func ParseListen(spec string) (*net.TCPAddr, error) {
	// empty, default
	if spec == "" {
		spec = defaults.Listen
	}
	// only a port, prefix with colon
	if ok, _ := regexp.MatchString(`^[0-9]+$`, spec); ok {
		spec = ":" + spec
	}
	// ipv4 w/o port, add default
	if strings.Contains(spec, ".") && !strings.Contains(spec, ":") {
		spec += defaults.Listen
	}
	// ipv6 w/o port, add default
	if ok, _ := regexp.MatchString(`^\[[a-f0-9:]+\]$`, spec); ok {
		spec += defaults.Listen
	}

	host, port, err := net.SplitHostPort(spec)
	if err != nil {
		return nil, errors.Wrap(err, "parsing listen")
	}

	addr, err := net.ResolveTCPAddr("tcp", net.JoinHostPort(host, port))
	if err != nil {
		return nil, errors.Wrap(err, "resolving listen")
	}

	return addr, nil
}
<|endoftext|>


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

package gcsx_test

import (
	"testing"

	"golang.org/x/net/context"

	"github.com/googlecloudplatform/gcsfuse/internal/gcsx"
	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/gcsfake"
	. "github.com/jacobsa/ogletest"
	"github.com/jacobsa/timeutil"
)

func TestPrefixBucket(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

type PrefixBucketTest struct {
	ctx     context.Context
	prefix  string
	wrapped gcs.Bucket
	bucket  gcs.Bucket
}

var _ SetUpInterface = &PrefixBucketTest{}

func init() { RegisterTestSuite(&PrefixBucketTest{}) }

func (t *PrefixBucketTest) SetUp(ti *TestInfo) {
	var err error

	t.ctx = ti.Ctx
	t.prefix = "foo_"
	t.wrapped = gcsfake.NewFakeBucket(timeutil.RealClock(), "some_bucket")

	t.bucket, err = gcsx.NewPrefixBucket(t.prefix, t.wrapped)
	AssertEq(nil, err)
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *PrefixBucketTest) Name() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) NewReader() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) CreateObject() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) CopyObject() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) ComposeObject() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) StatObject() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) ListObjects() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) UpdateObject() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) DeleteObject() {
	AddFailure("TODO")
}
<commit_msg>PrefixBucketTest.Name<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package gcsx_test

import (
	"testing"

	"golang.org/x/net/context"

	"github.com/googlecloudplatform/gcsfuse/internal/gcsx"
	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/gcsfake"
	. "github.com/jacobsa/ogletest"
	"github.com/jacobsa/timeutil"
)

func TestPrefixBucket(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

type PrefixBucketTest struct {
	ctx     context.Context
	prefix  string
	wrapped gcs.Bucket
	bucket  gcs.Bucket
}

var _ SetUpInterface = &PrefixBucketTest{}

func init() { RegisterTestSuite(&PrefixBucketTest{}) }

func (t *PrefixBucketTest) SetUp(ti *TestInfo) {
	var err error

	t.ctx = ti.Ctx
	t.prefix = "foo_"
	t.wrapped = gcsfake.NewFakeBucket(timeutil.RealClock(), "some_bucket")

	t.bucket, err = gcsx.NewPrefixBucket(t.prefix, t.wrapped)
	AssertEq(nil, err)
}

////////////////////////////////////////////////////////////////////////
// Tests
////////////////////////////////////////////////////////////////////////

func (t *PrefixBucketTest) Name() {
	ExpectEq(t.wrapped.Name(), t.bucket.Name())
}

func (t *PrefixBucketTest) NewReader() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) CreateObject() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) CopyObject() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) ComposeObject() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) StatObject() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) ListObjects() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) UpdateObject() {
	AddFailure("TODO")
}

func (t *PrefixBucketTest) DeleteObject() {
	AddFailure("TODO")
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/fatih/goset"
	"sync"
)

type KiteDependency struct {
	r map[string]*goset.Set
	sync.RWMutex
}

func NewDependency() *KiteDependency {
	return &KiteDependency{
		r: make(map[string]*goset.Set),
	}
}

// Add relationsips to kite
func (k *KiteDependency) Add(source, target string) {
	if target == "" || source == "" {
		return
	}

	k.RLock()
	s := k.r[source]
	k.RUnlock()

	if s == nil {
		s = goset.New()
	}

	k.Lock()
	s.Add(target)
	k.r[source] = s
	k.Unlock()
}

func (k *KiteDependency) Remove(source string) {
	if source == "" {
		return
	}

	k.RLock()
	s := k.r[source]
	k.RUnlock()

	if s == nil {
		s = goset.New()
	}

	k.Lock()
	s.Clear()
	k.r[source] = s
	k.Unlock()
}

func (k *KiteDependency) Has(source string) bool {
	if source == "" {
		return false
	}

	k.RLock()
	s, ok := k.r[source]
	k.RUnlock()
	if !ok {
		return false
	}

	if s == nil {
		return false
	}

	return true
}

// ListRelationship returns a slice of kite names that depends on "source"
// It returns an empty slice if the kite doesn't have any relationships.
func (k *KiteDependency) List(source string) []string {
	k.RLock()
	defer k.RUnlock()
	s, ok := k.r[source]
	if !ok {
		return make([]string, 0)
	}

	return s.StringSlice()
}
<commit_msg>kites/dependencies: simplify our dependency package<commit_after>package main

import (
	"github.com/fatih/goset"
	"sync"
)

type KiteDependency struct {
	r map[string]*goset.Set
	sync.Mutex
}

func NewDependency() *KiteDependency {
	return &KiteDependency{
		r: make(map[string]*goset.Set),
	}
}

// Add relationsips to kite
func (k *KiteDependency) Add(source, target string) {
	if target == "" || source == "" {
		return
	}

	k.Lock()
	defer k.Unlock()

	if k.r[source] == nil {
		k.r[source] = goset.New()
	}

	k.r[source].Add(target)
}

func (k *KiteDependency) Remove(source string) {
	if source == "" {
		return
	}

	k.Lock()
	defer k.Unlock()

	if k.r[source] == nil {
		return
	}

	k.r[source].Clear()
}

func (k *KiteDependency) Has(source string) bool {
	if source == "" {
		return false
	}
	k.Lock()
	defer k.Unlock()

	s, ok := k.r[source]
	if !ok {
		return false
	}

	if s == nil {
		return false
	}

	return true
}

// ListRelationship returns a slice of kite names that depends on "source"
// It returns an empty slice if the kite doesn't have any relationships.
func (k *KiteDependency) List(source string) []string {
	k.Lock()
	defer k.Unlock()

	s, ok := k.r[source]
	if !ok {
		return make([]string, 0)
	}

	return s.StringSlice()
}
<|endoftext|>