<commit_before>// Copyright 2014-2015 The DevMine 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 src

import (
	"fmt"
	"reflect"
)

type SwitchStmt struct {
	StmtName    string        `json:"statement_name"`
	Init        Expr          `json:"initialization,omitempty"`
	Cond        Expr          `json:"condition"` // TODO rename with a more appropriate name
	CaseClauses []*CaseClause `json:"case_clauses,omitempty"`
	Default     []Stmt        `json:"default,omitempty"`
}

type CaseClause struct {
	Conds []Expr `json:"conditions,omitempty"`
	Body  []Stmt `json:"body,omitempty"`
}

func newSwitchStmt(m map[string]interface{}) (*SwitchStmt, error) {
	var err error
	errPrefix := "src/switch_stmt"
	switchstmt := SwitchStmt{}

	if typ, err := extractStringValue("statement_name", errPrefix, m); err != nil {
		// XXX It is not possible to add debug info on this error because it is
		// required that this error be en "errNotExist".
		return nil, errNotExist
	} else if typ != SwitchStmtName {
		return nil, fmt.Errorf("invalid type: expected 'SwitchStmt', found '%s'", typ)
	}

	switchstmt.StmtName = SwitchStmtName

	initMap, err := extractMapValue("initialization", errPrefix, m)
	if err != nil && isExist(err) {
		return nil, addDebugInfo(err)
	} else if err == nil {
		if switchstmt.Cond, err = newStmt(initMap); err != nil {
			return nil, addDebugInfo(err)
		}
	}

	condMap, err := extractMapValue("condition", errPrefix, m)
	if err != nil {
		return nil, addDebugInfo(err)
	}

	if switchstmt.Cond, err = newExpr(condMap); err != nil {
		return nil, addDebugInfo(err)
	}

	if switchstmt.CaseClauses, err = newCaseClausesSlice("case_clauses", errPrefix, m); err != nil && isExist(err) {
		return nil, addDebugInfo(err)
	}

	if switchstmt.Default, err = newStmtsSlice("default", errPrefix, m); err != nil && isExist(err) {
		return nil, addDebugInfo(err)
	}

	return &switchstmt, nil
}

func newCaseClause(m map[string]interface{}) (*CaseClause, error) {
	var err error
	errPrefix := "src/case_clause"
	caseclause := CaseClause{}

	if caseclause.Conds, err = newExprsSlice("conditions", errPrefix, m); err != nil && isExist(err) {
		return nil, addDebugInfo(err)
	}

	if caseclause.Body, err = newStmtsSlice("body", errPrefix, m); err != nil && isExist(err) {
		return nil, addDebugInfo(err)
	}

	return &caseclause, nil
}

func newCaseClausesSlice(key, errPrefix string, m map[string]interface{}) ([]*CaseClause, error) {
	var err error
	var s *reflect.Value

	if s, err = reflectSliceValue(key, errPrefix, m); err != nil {
		// XXX It is not possible to add debug info on this error because it is
		// required that this error be en "errNotExist".
		return nil, err
	}

	ccs := make([]*CaseClause, s.Len(), s.Len())
	for i := 0; i < s.Len(); i++ {
		cc := s.Index(i).Interface()
		if cc == nil {
			continue
		}

		switch cc.(type) {
		case map[string]interface{}:
			if ccs[i], err = newCaseClause(cc.(map[string]interface{})); err != nil {
				return nil, addDebugInfo(err)
			}
		default:
			return nil, addDebugInfo(fmt.Errorf(
				"%s: '%s' must be a map[string]interface{}, found %v",
				errPrefix, key, reflect.TypeOf(cc)))
		}
	}

	return ccs, nil
}
<commit_msg>src: make Cond field of switch case optional<commit_after>// Copyright 2014-2015 The DevMine 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 src

import (
	"fmt"
	"reflect"
)

type SwitchStmt struct {
	StmtName    string        `json:"statement_name"`
	Init        Expr          `json:"initialization,omitempty"`
	Cond        Expr          `json:"condition,omitempty"` // TODO rename with a more appropriate name
	CaseClauses []*CaseClause `json:"case_clauses,omitempty"`
	Default     []Stmt        `json:"default,omitempty"`
}

type CaseClause struct {
	Conds []Expr `json:"conditions,omitempty"`
	Body  []Stmt `json:"body,omitempty"`
}

func newSwitchStmt(m map[string]interface{}) (*SwitchStmt, error) {
	var err error
	errPrefix := "src/switch_stmt"
	switchstmt := SwitchStmt{}

	if typ, err := extractStringValue("statement_name", errPrefix, m); err != nil {
		// XXX It is not possible to add debug info on this error because it is
		// required that this error be en "errNotExist".
		return nil, errNotExist
	} else if typ != SwitchStmtName {
		return nil, fmt.Errorf("invalid type: expected 'SwitchStmt', found '%s'", typ)
	}

	switchstmt.StmtName = SwitchStmtName

	initMap, err := extractMapValue("initialization", errPrefix, m)
	if err != nil && isExist(err) {
		return nil, addDebugInfo(err)
	} else if err == nil {
		if switchstmt.Cond, err = newStmt(initMap); err != nil {
			return nil, addDebugInfo(err)
		}
	}

	condMap, err := extractMapValue("condition", errPrefix, m)
	if err != nil {
		return nil, addDebugInfo(err)
	}

	if switchstmt.Cond, err = newExpr(condMap); err != nil && isExist(err) {
		return nil, addDebugInfo(err)
	}

	if switchstmt.CaseClauses, err = newCaseClausesSlice("case_clauses", errPrefix, m); err != nil && isExist(err) {
		return nil, addDebugInfo(err)
	}

	if switchstmt.Default, err = newStmtsSlice("default", errPrefix, m); err != nil && isExist(err) {
		return nil, addDebugInfo(err)
	}

	return &switchstmt, nil
}

func newCaseClause(m map[string]interface{}) (*CaseClause, error) {
	var err error
	errPrefix := "src/case_clause"
	caseclause := CaseClause{}

	if caseclause.Conds, err = newExprsSlice("conditions", errPrefix, m); err != nil && isExist(err) {
		return nil, addDebugInfo(err)
	}

	if caseclause.Body, err = newStmtsSlice("body", errPrefix, m); err != nil && isExist(err) {
		return nil, addDebugInfo(err)
	}

	return &caseclause, nil
}

func newCaseClausesSlice(key, errPrefix string, m map[string]interface{}) ([]*CaseClause, error) {
	var err error
	var s *reflect.Value

	if s, err = reflectSliceValue(key, errPrefix, m); err != nil {
		// XXX It is not possible to add debug info on this error because it is
		// required that this error be en "errNotExist".
		return nil, err
	}

	ccs := make([]*CaseClause, s.Len(), s.Len())
	for i := 0; i < s.Len(); i++ {
		cc := s.Index(i).Interface()
		if cc == nil {
			continue
		}

		switch cc.(type) {
		case map[string]interface{}:
			if ccs[i], err = newCaseClause(cc.(map[string]interface{})); err != nil {
				return nil, addDebugInfo(err)
			}
		default:
			return nil, addDebugInfo(fmt.Errorf(
				"%s: '%s' must be a map[string]interface{}, found %v",
				errPrefix, key, reflect.TypeOf(cc)))
		}
	}

	return ccs, nil
}
<|endoftext|>


<commit_before>package main

type StagePrototype struct {
	prototype             *Unit
	prototypePhase        int
	prototypeCooldownTime InstanceTime

	iron            *Unit
	ironInitialized bool
	ironLeavingTime *InstanceTime

	silver            *Unit
	silverInitialized bool
	silverLeavingTime *InstanceTime
}

func NewStagePrototype() Stage {
	return &StagePrototype{}
}

func (s *StagePrototype) Initialize(op Operator) error {
	id, err := op.Join(UnitGroupAI, "P-0", NewClassStagePrototype())
	if err != nil {
		return err
	}
	s.prototype = op.Units().Find(id)
	s.prototypeCooldownTime = op.Clock().Now()
	return nil
}

func (s *StagePrototype) OnTick(op Operator) {
	s.syncMinion(op)
	s.actPrototype(op)
	s.actIron(op)
	s.actSilver(op)
}

func (s *StagePrototype) syncMinion(op Operator) {
	op.Units().EachFriend(s.prototype, func(u *Unit) {
		switch u.ClassName() {
		case ClassName("Iron"):
			s.iron = u
		case ClassName("Silver"):
			s.silver = u
		default:

		}
	})

	if s.ironLeavingTime == nil && s.iron != nil && s.iron.IsDead() {
		s.ironLeavingTime = new(InstanceTime)
		*s.ironLeavingTime = op.Clock().Add(10 * Second)
	}

	if s.ironLeavingTime != nil && op.Clock().After(*s.ironLeavingTime) {
		op.Leave(s.iron.ID())
		s.iron = nil
		s.ironInitialized = false
		s.ironLeavingTime = nil
	}

	if s.silverLeavingTime == nil && s.silver != nil && s.silver.IsDead() {
		s.silverLeavingTime = new(InstanceTime)
		*s.silverLeavingTime = op.Clock().Add(10 * Second)
	}

	if s.silverLeavingTime != nil && op.Clock().After(*s.silverLeavingTime) {
		op.Leave(s.silver.ID())
		s.silver = nil
		s.silverInitialized = false
		s.silverLeavingTime = nil
	}
}

func (s *StagePrototype) actPrototype(op Operator) {
	switch {
	case op.Clock().Before(s.prototypeCooldownTime):
		return
	case s.isActivating(op, s.prototype):
		return
	case s.prototype.Health() == s.prototype.HealthMax():
		return
	case s.prototype.Health() > s.prototype.HealthMax()*0.5:
		if s.prototypePhase != 1 {
			s.prototypePhase = 1
			op.Cooldown(s.prototype, s.prototype.Ability("Attack"))
			op.Cooldown(s.prototype, s.prototype.Ability("Falcon"))
			op.Cooldown(s.prototype, s.prototype.Ability("Shark"))
			op.Cooldown(s.prototype, s.prototype.Ability("Iron"))
		}
		s.actPrototypePhase1(op)
	default:
		if s.prototypePhase != 2 {
			s.prototypePhase = 2
			op.Cooldown(s.prototype, s.prototype.Ability("Attack"))
			op.Cooldown(s.prototype, s.prototype.Ability("Ray"))
			op.Cooldown(s.prototype, s.prototype.Ability("Bell"))
			op.Cooldown(s.prototype, s.prototype.Ability("Silver"))
		}
		s.actPrototypePhase2(op)
	}
}

func (s *StagePrototype) actPrototypePhase1(op Operator) {
	o := s.maxThreatEnemy(op)
	if o == nil {
		return
	}
	if s.iron == nil {
		op.Activating(s.prototype, nil, s.prototype.Ability("Iron"))
	}
	op.Activating(s.prototype, o, s.prototype.Ability("Shark"))
	op.Activating(s.prototype, o, s.prototype.Ability("Falcon"))
	op.Activating(s.prototype, o, s.prototype.Ability("Attack"))
	s.prototypeCooldownTime = op.Clock().Add(3 * Second)
}

func (s *StagePrototype) actPrototypePhase2(op Operator) {
	o := s.maxThreatEnemy(op)
	if o == nil {
		return
	}
	if s.silver == nil {
		op.Activating(s.prototype, nil, s.prototype.Ability("Silver"))
	}
	if s.iron == nil {
		op.Activating(s.prototype, nil, s.prototype.Ability("Iron"))
	}
	op.Activating(s.prototype, nil, s.prototype.Ability("Bell"))
	op.Activating(s.prototype, o, s.prototype.Ability("Ray"))
	op.Activating(s.prototype, o, s.prototype.Ability("Shark"))
	op.Activating(s.prototype, o, s.prototype.Ability("Falcon"))
	op.Activating(s.prototype, o, s.prototype.Ability("Attack"))
	s.prototypeCooldownTime = op.Clock().Add(2 * Second)
}

func (s *StagePrototype) actIron(op Operator) {
	if s.iron == nil {
		return
	}
	if !s.ironInitialized {
		op.Cooldown(s.iron, s.iron.Ability("Silence"))
		op.Cooldown(s.iron, s.iron.Ability("Iron"))
		s.ironInitialized = true
		return
	}
	var o *Unit
	op.Units().EachEnemy(s.iron, func(u *Unit) {
		if o == nil || u.ClassName() == "Healer" {
			o = u
		}
	})
	op.Activating(s.iron, o, s.iron.Ability("Silence"))
	op.Activating(s.iron, o, s.iron.Ability("Iron"))
}

func (s *StagePrototype) actSilver(op Operator) {
	if s.silver == nil {
		return
	}
	if !s.silverInitialized {
		op.Cooldown(s.silver, s.iron.Ability("Stun"))
		op.Cooldown(s.silver, s.iron.Ability("Silver"))
		s.silverInitialized = true
		return
	}
	var o *Unit
	op.Units().EachEnemy(s.iron, func(u *Unit) {
		if o == nil || u.ClassName() == "Tank" {
			o = u
		}
	})
	op.Activating(s.silver, o, s.silver.Ability("Stun"))
	op.Activating(s.silver, o, s.silver.Ability("Silver"))
}

func (s *StagePrototype) isActivating(op Operator, u *Unit) bool {
	return op.Handlers().BindSubject(u).Some(func(h Handler) bool {
		switch h.(type) {
		case *Activating:
			return true
		}
		return false
	})
}

func (s *StagePrototype) maxThreatEnemy(op Operator) *Unit {
	var u *Unit
	var threat Statistic
	op.Handlers().BindObject(s.prototype).Each(func(h Handler) {
		switch h := h.(type) {
		case *Threat:
			if h.Subject().IsDead() {
				return
			}
			if u == nil || h.threat > threat {
				u = h.Subject()
				threat = h.threat
			}
		}
	})
	return u
}

func NewClassStagePrototype() (class *Class) {
	var attack, falcon, shark, iron, ray, bell, silver, dandelion, tidalBore, diamond, pastorale, vines, waveCrest, morningLull, jadeite Ability
	class = &Class{
		Name:                 "Prototype",
		Health:               40000,
		HealthRegeneration:   0,
		Mana:                 1000,
		ManaRegeneration:     0,
		Armor:                DefaultArmor,
		MagicResistance:      DefaultMagicResistance,
		CriticalStrikeChance: DefaultCriticalStrikeChance,
		CriticalStrikeFactor: DefaultCriticalStrikeFactor,
		DamageThreatFactor:   DefaultDamageThreatFactor,
		HealingThreatFactor:  DefaultHealingThreatFactor,
		Abilities:            []*Ability{&attack, &falcon, &shark, &iron, &ray, &bell, &silver, &dandelion, &tidalBore, &diamond, &pastorale, &vines, &waveCrest, &morningLull, &jadeite},
	}
	attack = Ability{
		Name:               "Attack",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 0 * Second,
		CooldownDuration:   4 * Second,
		DisableTypes: []DisableType{
			DisableTypeStun,
		},
		Perform: func(op Operator, s Subject, o *Unit) {
			baseDamage := 100 + 100*(1-s.Subject().Health()/s.Subject().HealthMax())
			op.PhysicalDamage(s, o, baseDamage).Perform()
		},
	}
	falcon = Ability{
		Name:               "Falcon",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 1 * Second,
		CooldownDuration:   8 * Second,
		DisableTypes: []DisableType{
			DisableTypeStun,
		},
		Perform: func(op Operator, s Subject, o *Unit) {
			baseDamage := Statistic(160)
			op.PhysicalDamage(s, o, baseDamage).Perform()
		},
	}
	shark = Ability{
		Name:               "Shark",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 1 * Second,
		CooldownDuration:   12 * Second,
		DisableTypes: []DisableType{
			DisableTypeStun,
		},
		Perform: func(op Operator, s Subject, o *Unit) {
			baseDamage := Statistic(310)
			op.PhysicalDamage(s, o, baseDamage).Perform()
		},
	}
	iron = Ability{
		Name:               "Iron",
		TargetType:         TargetTypeNone,
		ActivationDuration: 1 * Second,
		CooldownDuration:   30 * Second,
		DisableTypes:       []DisableType{},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.Join(s.Subject().Group(), "Iron-PX1", NewClassStageIron())
		},
	}
	ray = Ability{
		Name:               "Ray",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 1 * Second,
		CooldownDuration:   20 * Second,
		DisableTypes: []DisableType{
			DisableTypeSilence,
		},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.MagicDamage(s, o, 100).Perform()
			if o.IsDead() {
				return
			}
			op.DoT(op.MagicDamage(s, o, 35), 10*Second, ray.Name)
		},
	}
	bell = Ability{
		Name:               "Bell",
		TargetType:         TargetTypeNone,
		ActivationDuration: 1 * Second,
		CooldownDuration:   30 * Second,
		DisableTypes: []DisableType{
			DisableTypeSilence,
		},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.Units().EachEnemy(s.Subject(), func(enemy *Unit) {
				if enemy.IsDead() {
					return
				}
				op.MagicDamage(s, enemy, 180).Perform()
			})
		},
	}
	silver = Ability{
		Name:               "Silver",
		TargetType:         TargetTypeNone,
		ActivationDuration: 1 * Second,
		CooldownDuration:   40 * Second,
		DisableTypes:       []DisableType{},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.Join(s.Subject().Group(), "Silver-PX2", NewClassStageSilver())
		},
	}
	return
}

func NewClassStageIron() (class *Class) {
	var silence, iron Ability
	class = &Class{
		Name:                 "Iron",
		Health:               500,
		HealthRegeneration:   50,
		Mana:                 100,
		ManaRegeneration:     0,
		Armor:                DefaultArmor,
		MagicResistance:      1000,
		CriticalStrikeChance: DefaultCriticalStrikeChance,
		CriticalStrikeFactor: DefaultCriticalStrikeFactor,
		DamageThreatFactor:   DefaultDamageThreatFactor,
		HealingThreatFactor:  DefaultHealingThreatFactor,
		Abilities:            []*Ability{&silence, &iron},
	}
	silence = Ability{
		Name:               "Silence",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 1 * Second,
		CooldownDuration:   8 * Second,
		DisableTypes:       []DisableType{},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.Disable(o, DisableTypeSilence, 3*Second)
		},
	}
	iron = Ability{
		Name:               "Iron",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 1 * Second,
		CooldownDuration:   5 * Second,
		DisableTypes:       []DisableType{},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.MagicDamage(s, o, 120).Perform()
		},
	}
	return class
}

func NewClassStageSilver() (class *Class) {
	var stun, silver Ability
	class = &Class{
		Name:                 "Silver",
		Health:               1000,
		HealthRegeneration:   100,
		Mana:                 100,
		ManaRegeneration:     0,
		Armor:                1000,
		MagicResistance:      DefaultMagicResistance,
		CriticalStrikeChance: DefaultCriticalStrikeChance,
		CriticalStrikeFactor: DefaultCriticalStrikeFactor,
		DamageThreatFactor:   DefaultDamageThreatFactor,
		HealingThreatFactor:  DefaultHealingThreatFactor,
		Abilities:            []*Ability{&stun, &silver},
	}
	stun = Ability{
		Name:               "Stun",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 1 * Second,
		CooldownDuration:   8 * Second,
		DisableTypes:       []DisableType{},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.Disable(o, DisableTypeStun, 3*Second)
		},
	}
	silver = Ability{
		Name:               "Iron",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 1 * Second,
		CooldownDuration:   5 * Second,
		DisableTypes:       []DisableType{},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.MagicDamage(s, o, 270).Perform()
		},
	}
	return class
}
<commit_msg>Fix bugs<commit_after>package main

type StagePrototype struct {
	prototype             *Unit
	prototypePhase        int
	prototypeCooldownTime InstanceTime

	iron            *Unit
	ironInitialized bool
	ironLeavingTime *InstanceTime

	silver            *Unit
	silverInitialized bool
	silverLeavingTime *InstanceTime
}

func NewStagePrototype() Stage {
	return &StagePrototype{}
}

func (s *StagePrototype) Initialize(op Operator) error {
	id, err := op.Join(UnitGroupAI, "P-0", NewClassStagePrototype())
	if err != nil {
		return err
	}
	s.prototype = op.Units().Find(id)
	s.prototypeCooldownTime = op.Clock().Now()
	return nil
}

func (s *StagePrototype) OnTick(op Operator) {
	s.syncMinion(op)
	s.actPrototype(op)
	s.actIron(op)
	s.actSilver(op)
}

func (s *StagePrototype) syncMinion(op Operator) {
	op.Units().EachFriend(s.prototype, func(u *Unit) {
		switch u.ClassName() {
		case ClassName("Iron"):
			s.iron = u
		case ClassName("Silver"):
			s.silver = u
		default:

		}
	})

	if s.ironLeavingTime == nil && s.iron != nil && s.iron.IsDead() {
		s.ironLeavingTime = new(InstanceTime)
		*s.ironLeavingTime = op.Clock().Add(10 * Second)
	}

	if s.ironLeavingTime != nil && op.Clock().After(*s.ironLeavingTime) {
		op.Leave(s.iron.ID())
		s.iron = nil
		s.ironInitialized = false
		s.ironLeavingTime = nil
	}

	if s.silverLeavingTime == nil && s.silver != nil && s.silver.IsDead() {
		s.silverLeavingTime = new(InstanceTime)
		*s.silverLeavingTime = op.Clock().Add(10 * Second)
	}

	if s.silverLeavingTime != nil && op.Clock().After(*s.silverLeavingTime) {
		op.Leave(s.silver.ID())
		s.silver = nil
		s.silverInitialized = false
		s.silverLeavingTime = nil
	}
}

func (s *StagePrototype) actPrototype(op Operator) {
	switch {
	case op.Clock().Before(s.prototypeCooldownTime):
		return
	case s.isActivating(op, s.prototype):
		return
	case s.prototype.Health() == s.prototype.HealthMax():
		return
	case s.prototype.Health() > s.prototype.HealthMax()*0.5:
		if s.prototypePhase != 1 {
			s.prototypePhase = 1
			op.Cooldown(s.prototype, s.prototype.Ability("Attack"))
			op.Cooldown(s.prototype, s.prototype.Ability("Falcon"))
			op.Cooldown(s.prototype, s.prototype.Ability("Shark"))
			op.Cooldown(s.prototype, s.prototype.Ability("Iron"))
		}
		s.actPrototypePhase1(op)
	default:
		if s.prototypePhase != 2 {
			s.prototypePhase = 2
			op.Cooldown(s.prototype, s.prototype.Ability("Attack"))
			op.Cooldown(s.prototype, s.prototype.Ability("Ray"))
			op.Cooldown(s.prototype, s.prototype.Ability("Bell"))
			op.Cooldown(s.prototype, s.prototype.Ability("Silver"))
		}
		s.actPrototypePhase2(op)
	}
}

func (s *StagePrototype) actPrototypePhase1(op Operator) {
	o := s.maxThreatEnemy(op)
	if o == nil {
		return
	}
	if s.iron == nil {
		op.Activating(s.prototype, nil, s.prototype.Ability("Iron"))
	}
	op.Activating(s.prototype, o, s.prototype.Ability("Shark"))
	op.Activating(s.prototype, o, s.prototype.Ability("Falcon"))
	op.Activating(s.prototype, o, s.prototype.Ability("Attack"))
	s.prototypeCooldownTime = op.Clock().Add(3 * Second)
}

func (s *StagePrototype) actPrototypePhase2(op Operator) {
	o := s.maxThreatEnemy(op)
	if o == nil {
		return
	}
	if s.silver == nil {
		op.Activating(s.prototype, nil, s.prototype.Ability("Silver"))
	}
	if s.iron == nil {
		op.Activating(s.prototype, nil, s.prototype.Ability("Iron"))
	}
	op.Activating(s.prototype, nil, s.prototype.Ability("Bell"))
	op.Activating(s.prototype, o, s.prototype.Ability("Ray"))
	op.Activating(s.prototype, o, s.prototype.Ability("Shark"))
	op.Activating(s.prototype, o, s.prototype.Ability("Falcon"))
	op.Activating(s.prototype, o, s.prototype.Ability("Attack"))
	s.prototypeCooldownTime = op.Clock().Add(2 * Second)
}

func (s *StagePrototype) actIron(op Operator) {
	if s.iron == nil {
		return
	}
	if !s.ironInitialized {
		op.Cooldown(s.iron, s.iron.Ability("Silence"))
		op.Cooldown(s.iron, s.iron.Ability("Iron"))
		s.ironInitialized = true
		return
	}
	var o *Unit
	op.Units().EachEnemy(s.iron, func(u *Unit) {
		if o == nil || u.ClassName() == "Healer" {
			o = u
		}
	})
	op.Activating(s.iron, o, s.iron.Ability("Silence"))
	op.Activating(s.iron, o, s.iron.Ability("Iron"))
}

func (s *StagePrototype) actSilver(op Operator) {
	if s.silver == nil {
		return
	}
	if !s.silverInitialized {
		op.Cooldown(s.silver, s.silver.Ability("Stun"))
		op.Cooldown(s.silver, s.silver.Ability("Silver"))
		s.silverInitialized = true
		return
	}
	var o *Unit
	op.Units().EachEnemy(s.silver, func(u *Unit) {
		if o == nil || u.ClassName() == "Tank" {
			o = u
		}
	})
	op.Activating(s.silver, o, s.silver.Ability("Stun"))
	op.Activating(s.silver, o, s.silver.Ability("Silver"))
}

func (s *StagePrototype) isActivating(op Operator, u *Unit) bool {
	return op.Handlers().BindSubject(u).Some(func(h Handler) bool {
		switch h.(type) {
		case *Activating:
			return true
		}
		return false
	})
}

func (s *StagePrototype) maxThreatEnemy(op Operator) *Unit {
	var u *Unit
	var threat Statistic
	op.Handlers().BindObject(s.prototype).Each(func(h Handler) {
		switch h := h.(type) {
		case *Threat:
			if h.Subject().IsDead() {
				return
			}
			if u == nil || h.threat > threat {
				u = h.Subject()
				threat = h.threat
			}
		}
	})
	return u
}

func NewClassStagePrototype() (class *Class) {
	var attack, falcon, shark, iron, ray, bell, silver, dandelion, tidalBore, diamond, pastorale, vines, waveCrest, morningLull, jadeite Ability
	class = &Class{
		Name:                 "Prototype",
		Health:               40000,
		HealthRegeneration:   0,
		Mana:                 1000,
		ManaRegeneration:     0,
		Armor:                DefaultArmor,
		MagicResistance:      DefaultMagicResistance,
		CriticalStrikeChance: DefaultCriticalStrikeChance,
		CriticalStrikeFactor: DefaultCriticalStrikeFactor,
		DamageThreatFactor:   DefaultDamageThreatFactor,
		HealingThreatFactor:  DefaultHealingThreatFactor,
		Abilities:            []*Ability{&attack, &falcon, &shark, &iron, &ray, &bell, &silver, &dandelion, &tidalBore, &diamond, &pastorale, &vines, &waveCrest, &morningLull, &jadeite},
	}
	attack = Ability{
		Name:               "Attack",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 0 * Second,
		CooldownDuration:   4 * Second,
		DisableTypes: []DisableType{
			DisableTypeStun,
		},
		Perform: func(op Operator, s Subject, o *Unit) {
			baseDamage := 100 + 100*(1-s.Subject().Health()/s.Subject().HealthMax())
			op.PhysicalDamage(s, o, baseDamage).Perform()
		},
	}
	falcon = Ability{
		Name:               "Falcon",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 1 * Second,
		CooldownDuration:   8 * Second,
		DisableTypes: []DisableType{
			DisableTypeStun,
		},
		Perform: func(op Operator, s Subject, o *Unit) {
			baseDamage := Statistic(160)
			op.PhysicalDamage(s, o, baseDamage).Perform()
		},
	}
	shark = Ability{
		Name:               "Shark",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 1 * Second,
		CooldownDuration:   12 * Second,
		DisableTypes: []DisableType{
			DisableTypeStun,
		},
		Perform: func(op Operator, s Subject, o *Unit) {
			baseDamage := Statistic(310)
			op.PhysicalDamage(s, o, baseDamage).Perform()
		},
	}
	iron = Ability{
		Name:               "Iron",
		TargetType:         TargetTypeNone,
		ActivationDuration: 1 * Second,
		CooldownDuration:   30 * Second,
		DisableTypes:       []DisableType{},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.Join(s.Subject().Group(), "Iron-PX1", NewClassStageIron())
		},
	}
	ray = Ability{
		Name:               "Ray",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 1 * Second,
		CooldownDuration:   20 * Second,
		DisableTypes: []DisableType{
			DisableTypeSilence,
		},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.MagicDamage(s, o, 100).Perform()
			if o.IsDead() {
				return
			}
			op.DoT(op.MagicDamage(s, o, 35), 10*Second, ray.Name)
		},
	}
	bell = Ability{
		Name:               "Bell",
		TargetType:         TargetTypeNone,
		ActivationDuration: 1 * Second,
		CooldownDuration:   30 * Second,
		DisableTypes: []DisableType{
			DisableTypeSilence,
		},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.Units().EachEnemy(s.Subject(), func(enemy *Unit) {
				if enemy.IsDead() {
					return
				}
				op.MagicDamage(s, enemy, 180).Perform()
			})
		},
	}
	silver = Ability{
		Name:               "Silver",
		TargetType:         TargetTypeNone,
		ActivationDuration: 1 * Second,
		CooldownDuration:   40 * Second,
		DisableTypes:       []DisableType{},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.Join(s.Subject().Group(), "Silver-PX2", NewClassStageSilver())
		},
	}
	return
}

func NewClassStageIron() (class *Class) {
	var silence, iron Ability
	class = &Class{
		Name:                 "Iron",
		Health:               500,
		HealthRegeneration:   50,
		Mana:                 100,
		ManaRegeneration:     0,
		Armor:                DefaultArmor,
		MagicResistance:      1000,
		CriticalStrikeChance: DefaultCriticalStrikeChance,
		CriticalStrikeFactor: DefaultCriticalStrikeFactor,
		DamageThreatFactor:   DefaultDamageThreatFactor,
		HealingThreatFactor:  DefaultHealingThreatFactor,
		Abilities:            []*Ability{&silence, &iron},
	}
	silence = Ability{
		Name:               "Silence",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 1 * Second,
		CooldownDuration:   8 * Second,
		DisableTypes:       []DisableType{},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.Disable(o, DisableTypeSilence, 3*Second)
		},
	}
	iron = Ability{
		Name:               "Iron",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 1 * Second,
		CooldownDuration:   5 * Second,
		DisableTypes:       []DisableType{},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.MagicDamage(s, o, 120).Perform()
		},
	}
	return class
}

func NewClassStageSilver() (class *Class) {
	var stun, silver Ability
	class = &Class{
		Name:                 "Silver",
		Health:               1000,
		HealthRegeneration:   100,
		Mana:                 100,
		ManaRegeneration:     0,
		Armor:                1000,
		MagicResistance:      DefaultMagicResistance,
		CriticalStrikeChance: DefaultCriticalStrikeChance,
		CriticalStrikeFactor: DefaultCriticalStrikeFactor,
		DamageThreatFactor:   DefaultDamageThreatFactor,
		HealingThreatFactor:  DefaultHealingThreatFactor,
		Abilities:            []*Ability{&stun, &silver},
	}
	stun = Ability{
		Name:               "Stun",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 1 * Second,
		CooldownDuration:   8 * Second,
		DisableTypes:       []DisableType{},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.Disable(o, DisableTypeStun, 3*Second)
		},
	}
	silver = Ability{
		Name:               "Silver",
		TargetType:         TargetTypeEnemy,
		ActivationDuration: 1 * Second,
		CooldownDuration:   5 * Second,
		DisableTypes:       []DisableType{},
		Perform: func(op Operator, s Subject, o *Unit) {
			op.MagicDamage(s, o, 270).Perform()
		},
	}
	return class
}
<|endoftext|>


<commit_before>// generated by go-import-subtree -- DO NOT EDIT
package main

import _ "github.com/taskcluster/taskcluster-worker/engines/enginetest"
import _ "github.com/taskcluster/taskcluster-worker/engines/mock"
import _ "github.com/taskcluster/taskcluster-worker/engines/osxnative"
import _ "github.com/taskcluster/taskcluster-worker/engines/qemu"
import _ "github.com/taskcluster/taskcluster-worker/plugins/artifacts"
import _ "github.com/taskcluster/taskcluster-worker/plugins/env"
import _ "github.com/taskcluster/taskcluster-worker/plugins/interactive"
import _ "github.com/taskcluster/taskcluster-worker/plugins/livelog"
import _ "github.com/taskcluster/taskcluster-worker/plugins/plugintest"
import _ "github.com/taskcluster/taskcluster-worker/plugins/success"
import _ "github.com/taskcluster/taskcluster-worker/commands/daemon"
import _ "github.com/taskcluster/taskcluster-worker/commands/help"
import _ "github.com/taskcluster/taskcluster-worker/commands/qemu-build"
import _ "github.com/taskcluster/taskcluster-worker/commands/qemu-guest-tools"
import _ "github.com/taskcluster/taskcluster-worker/commands/qemu-run"
import _ "github.com/taskcluster/taskcluster-worker/commands/schema"
import _ "github.com/taskcluster/taskcluster-worker/commands/shell"
import _ "github.com/taskcluster/taskcluster-worker/commands/work"
import _ "github.com/taskcluster/taskcluster-worker/config/configtest"
import _ "github.com/taskcluster/taskcluster-worker/config/env"
import _ "github.com/taskcluster/taskcluster-worker/config/packet"
import _ "github.com/taskcluster/taskcluster-worker/config/secrets"
<commit_msg>ran make generate again<commit_after>// generated by go-import-subtree -- DO NOT EDIT
package main

import _ "github.com/taskcluster/taskcluster-worker/engines/enginetest"
import _ "github.com/taskcluster/taskcluster-worker/engines/mock"
import _ "github.com/taskcluster/taskcluster-worker/engines/osxnative"
import _ "github.com/taskcluster/taskcluster-worker/engines/qemu"
import _ "github.com/taskcluster/taskcluster-worker/engines/script"
import _ "github.com/taskcluster/taskcluster-worker/plugins/artifacts"
import _ "github.com/taskcluster/taskcluster-worker/plugins/env"
import _ "github.com/taskcluster/taskcluster-worker/plugins/interactive"
import _ "github.com/taskcluster/taskcluster-worker/plugins/livelog"
import _ "github.com/taskcluster/taskcluster-worker/plugins/plugintest"
import _ "github.com/taskcluster/taskcluster-worker/plugins/success"
import _ "github.com/taskcluster/taskcluster-worker/commands/daemon"
import _ "github.com/taskcluster/taskcluster-worker/commands/help"
import _ "github.com/taskcluster/taskcluster-worker/commands/qemu-build"
import _ "github.com/taskcluster/taskcluster-worker/commands/qemu-guest-tools"
import _ "github.com/taskcluster/taskcluster-worker/commands/qemu-run"
import _ "github.com/taskcluster/taskcluster-worker/commands/schema"
import _ "github.com/taskcluster/taskcluster-worker/commands/shell"
import _ "github.com/taskcluster/taskcluster-worker/commands/work"
import _ "github.com/taskcluster/taskcluster-worker/config/configtest"
import _ "github.com/taskcluster/taskcluster-worker/config/env"
import _ "github.com/taskcluster/taskcluster-worker/config/packet"
import _ "github.com/taskcluster/taskcluster-worker/config/secrets"
<|endoftext|>


<commit_before>// Copyright 2015-2016 Sevki <s@sevki.org>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package cc // import "sevki.org/build/targets/cc"

import (
	"crypto/sha1"
	"fmt"
	"io"
	"strings"

	"sevki.org/build/util"

	"path/filepath"

	"sevki.org/build"
)

type CLib struct {
	Name            string        `cxx_library:"name" cc_library:"name"`
	Sources         []string      `cxx_library:"srcs" cc_library:"srcs" build:"path"`
	Dependencies    []string      `cxx_library:"deps" cc_library:"deps"`
	Includes        Includes      `cxx_library:"headers" cc_library:"includes" build:"path"`
	Headers         []string      `cxx_library:"exported_headers" cc_library:"hdrs" build:"path"`
	CompilerOptions CompilerFlags `cxx_library:"compiler_flags" cc_library:"copts"`
	LinkerOptions   []string      `cxx_library:"linker_flags" cc_library:"linkopts"`
	LinkStatic      bool          `cxx_library:"linkstatic" cc_library:"linkstatic"`
	AlwaysLink      bool          `cxx_library:"alwayslink" cc_library:"alwayslink"`
}

func (cl *CLib) Hash() []byte {
	h := sha1.New()

	io.WriteString(h, CCVersion)
	io.WriteString(h, cl.Name)
	util.HashFiles(h, cl.Includes)
	io.WriteString(h, "clib")
	util.HashFiles(h, []string(cl.Sources))
	util.HashStrings(h, cl.CompilerOptions)
	util.HashStrings(h, cl.LinkerOptions)
	if cl.LinkStatic {
		io.WriteString(h, "static")
	}
	return h.Sum(nil)
}

func (cl *CLib) Build(c *build.Context) error {
	params := []string{"-c"}
	params = append(params, cl.CompilerOptions...)
	params = append(params, cl.LinkerOptions...)
	params = append(params, cl.Sources...)
	params = append(params, cl.Includes.Includes()...)

	if err := c.Exec(Compiler(), CCENV, params); err != nil {
		return fmt.Errorf(err.Error())
	}

	libName := fmt.Sprintf("%s.a", cl.Name)
	params = []string{"-rs", libName}
	params = append(params, cl.LinkerOptions...)
	// This is done under the assumption that each src file put in this thing
	// here will comeout as a .o file
	for _, f := range cl.Sources {
		_, filename := filepath.Split(f)
		params = append(params, fmt.Sprintf("%s.o", filename[:strings.LastIndex(filename, ".")]))
	}

	if err := c.Exec(Archiver(), CCENV, params); err != nil {
		return fmt.Errorf(err.Error())
	}

	return nil
}
func (cl *CLib) Installs() map[string]string {
	exports := make(map[string]string)
	libName := fmt.Sprintf("%s.a", cl.Name)
	if cl.AlwaysLink {
		exports[libName] = libName
	} else {
		exports[filepath.Join("lib", libName)] = libName
	}
	return exports
}
func (cl *CLib) GetName() string {
	return cl.Name
}

func (cl *CLib) GetDependencies() []string {
	return cl.Dependencies
}
<commit_msg>targets/cc: switch order of includes<commit_after>// Copyright 2015-2016 Sevki <s@sevki.org>. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package cc // import "sevki.org/build/targets/cc"

import (
	"crypto/sha1"
	"fmt"
	"io"
	"strings"

	"sevki.org/build/util"

	"path/filepath"

	"sevki.org/build"
)

type CLib struct {
	Name            string        `cxx_library:"name" cc_library:"name"`
	Sources         []string      `cxx_library:"srcs" cc_library:"srcs" build:"path"`
	Dependencies    []string      `cxx_library:"deps" cc_library:"deps"`
	Includes        Includes      `cxx_library:"headers" cc_library:"includes" build:"path"`
	Headers         []string      `cxx_library:"exported_headers" cc_library:"hdrs" build:"path"`
	CompilerOptions CompilerFlags `cxx_library:"compiler_flags" cc_library:"copts"`
	LinkerOptions   []string      `cxx_library:"linker_flags" cc_library:"linkopts"`
	LinkStatic      bool          `cxx_library:"linkstatic" cc_library:"linkstatic"`
	AlwaysLink      bool          `cxx_library:"alwayslink" cc_library:"alwayslink"`
}

func (cl *CLib) Hash() []byte {
	h := sha1.New()

	io.WriteString(h, CCVersion)
	io.WriteString(h, cl.Name)
	util.HashFiles(h, cl.Includes)
	io.WriteString(h, "clib")
	util.HashFiles(h, []string(cl.Sources))
	util.HashStrings(h, cl.CompilerOptions)
	util.HashStrings(h, cl.LinkerOptions)
	if cl.LinkStatic {
		io.WriteString(h, "static")
	}
	return h.Sum(nil)
}

func (cl *CLib) Build(c *build.Context) error {
	params := []string{"-c"}
	params = append(params, cl.CompilerOptions...)
	params = append(params, cl.LinkerOptions...)
	params = append(params, cl.Includes.Includes()...)
	params = append(params, cl.Sources...)

	if err := c.Exec(Compiler(), CCENV, params); err != nil {
		return fmt.Errorf(err.Error())
	}

	libName := fmt.Sprintf("%s.a", cl.Name)
	params = []string{"-rs", libName}
	params = append(params, cl.LinkerOptions...)
	// This is done under the assumption that each src file put in this thing
	// here will comeout as a .o file
	for _, f := range cl.Sources {
		_, filename := filepath.Split(f)
		params = append(params, fmt.Sprintf("%s.o", filename[:strings.LastIndex(filename, ".")]))
	}

	if err := c.Exec(Archiver(), CCENV, params); err != nil {
		return fmt.Errorf(err.Error())
	}

	return nil
}
func (cl *CLib) Installs() map[string]string {
	exports := make(map[string]string)
	libName := fmt.Sprintf("%s.a", cl.Name)
	if cl.AlwaysLink {
		exports[libName] = libName
	} else {
		exports[filepath.Join("lib", libName)] = libName
	}
	return exports
}
func (cl *CLib) GetName() string {
	return cl.Name
}

func (cl *CLib) GetDependencies() []string {
	return cl.Dependencies
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gorilla/mux"
)

var port = ""
var router = mux.NewRouter()

func main() {
	port = getPort()
	printCredits()

	router.HandleFunc("/pull", handleGetJSON)
	router.HandleFunc("/connected", handleGetPluginConnected)
	// for plugin to upload/download data using websocket
	router.HandleFunc("/pushws", handlePluginWS)
	// for browser to send input to plugin
	router.HandleFunc("/input", handlePostInput)
	router.HandleFunc("/dummy", handleGetDummyJSON)
	router.HandleFunc("/", handleIndex)

	http.Handle("/", router)
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
	http.Handle("/skins/", http.StripPrefix("/skins/", http.FileServer(http.Dir("skins"))))
	log.Println("Listening on port " + port)
	http.ListenAndServe(":"+port, nil)
}

func printCredits() {
	fmt.Println("VStats web server by libertylocked")
	fmt.Println("To pull the JSON, use /pull handle")
	fmt.Println("See README for details")
	fmt.Println()
}
<commit_msg>Specify HTTP methods<commit_after>package main

import (
	"fmt"
	"log"
	"net/http"

	"github.com/gorilla/mux"
)

var port = ""

func main() {
	port = getPort()
	printCredits()

	http.Handle("/", getHandlers())
	http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static"))))
	http.Handle("/skins/", http.StripPrefix("/skins/", http.FileServer(http.Dir("skins"))))
	log.Println("Listening on port " + port)
	http.ListenAndServe(":"+port, nil)
}

func getHandlers() *mux.Router {
	router := mux.NewRouter()
	router.HandleFunc("/pull", handleGetJSON).Methods("GET")
	router.HandleFunc("/connected", handleGetPluginConnected).Methods("GET")
	// for plugin to upload/download data using websocket
	router.HandleFunc("/pushws", handlePluginWS)
	// for browser to send input to plugin
	router.HandleFunc("/input", handlePostInput).Methods("POST")
	router.HandleFunc("/dummy", handleGetDummyJSON).Methods("GET")
	router.HandleFunc("/", handleIndex).Methods("GET")
	return router
}

func printCredits() {
	fmt.Println("VStats web server by libertylocked")
	fmt.Println("To pull the JSON, use /pull handle")
	fmt.Println("See README for details")
	fmt.Println()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"math/rand"
	"net/http"
	_ "net/http/pprof"
	"runtime"
	"sync"
	"sync/atomic"
	"time"

	"github.com/dustin/go-humanize"
	"github.com/getlantern/golog"
	"github.com/getlantern/tdb"
)

var (
	log = golog.LoggerFor("tdbdemo")
)

func main() {
	go func() {
		log.Error(http.ListenAndServe("localhost:4000", nil))
	}()

	numReporters := 5000
	uniquesPerReporter := 1000
	uniquesPerPeriod := 100
	valuesPerPeriod := 5000
	reportingPeriods := 100000
	resolution := 5 * time.Minute
	retainPeriods := 24
	retentionPeriod := time.Duration(retainPeriods) * resolution
	targetPointsPerSecond := 200000
	numWriters := 4
	targetPointsPerSecondPerWriter := targetPointsPerSecond / numWriters
	targetDeltaFor1000Points := 1000 * time.Second / time.Duration(targetPointsPerSecondPerWriter)
	log.Debugf("Target delta for 1000 points: %v", targetDeltaFor1000Points)

	db, err := tdb.NewDB(&tdb.DBOpts{
		Dir:                  "/tmp/tdbdemo",
		RocksDBStatsInterval: 60 * time.Second,
	})
	if err != nil {
		log.Fatal(err)
	}
	err = db.CreateTable(&tdb.TableOpts{
		Name:             "test",
		RetentionPeriod:  retentionPeriod,
		MaxMemStoreBytes: 250 * 1024 * 1024,
		MaxFlushLatency:  1 * time.Minute,
		SQL: fmt.Sprintf(`
SELECT
	SUM(i) AS i,
	SUM(ii) AS ii,
	AVG(ii) / AVG(i) AS iii
FROM inbound
GROUP BY period(%v)`, resolution),
	})
	if err != nil {
		log.Fatal(err)
	}

	inserts := int64(0)
	start := time.Now()

	report := func() {
		delta := time.Now().Sub(start)
		start = time.Now()
		i := atomic.SwapInt64(&inserts, 0)
		var ms runtime.MemStats
		runtime.ReadMemStats(&ms)
		preGC := float64(ms.HeapAlloc) / 1024.0 / 1024.0
		runtime.GC()
		runtime.ReadMemStats(&ms)
		postGC := float64(ms.HeapAlloc) / 1024.0 / 1024.0
		fmt.Printf(`
%s inserts at %s inserts per second
%v
HeapAlloc pre/post GC %f/%f MiB
`,
			humanize.Comma(i), humanize.Comma(i/int64(delta.Seconds())),
			db.PrintTableStats("test"),
			preGC, postGC)
	}

	go func() {
		for {
			tk := time.NewTicker(30 * time.Second)
			for range tk.C {
				report()
			}
		}
	}()

	go func() {
		for {
			tk := time.NewTicker(1 * time.Minute)
			for range tk.C {
				log.Debug("Running query")
				now := db.Now("test")
				q, err := db.SQLQuery(`
SELECT SUM(ii) AS the_count
FROM test
GROUP BY period(168h)
`)
				if err != nil {
					log.Errorf("Unable to build query: %v", err)
					continue
				}
				start := time.Now()
				result, err := q.Run()
				delta := time.Now().Sub(start)
				if err != nil {
					log.Errorf("Unable to run query: %v", err)
					continue
				}
				count := float64(0)
				if len(result.Entries) != 1 {
					log.Fatalf("Unexpected result entries: %d", len(result.Entries))
				}
				count = result.Entries[0].Value("the_count", 0)
				fmt.Printf("\nQuery at %v returned %v in %v\n", now, humanize.Comma(int64(count)), delta)
			}
		}
	}()

	var wg sync.WaitGroup
	wg.Add(numWriters)
	for _w := 0; _w < numWriters; _w++ {
		go func() {
			defer wg.Done()
			c := 0
			start := time.Now()
			for i := 0; i < reportingPeriods; i++ {
				ts := time.Now()
				uniques := make([]int, 0, uniquesPerPeriod)
				for u := 0; u < uniquesPerPeriod; u++ {
					uniques = append(uniques, rand.Intn(uniquesPerReporter))
				}
				for r := 0; r < numReporters/numWriters; r++ {
					for v := 0; v < valuesPerPeriod; v++ {
						p := &tdb.Point{
							Ts: ts,
							Dims: map[string]interface{}{
								"r": rand.Intn(numReporters),
								"u": uniques[rand.Intn(uniquesPerPeriod)],
								"b": rand.Float64() > 0.99,
								"x": 1,
							},
							Vals: map[string]float64{
								"i":  float64(rand.Intn(100000)),
								"ii": 1,
							},
						}
						ierr := db.Insert("inbound", p)
						if ierr != nil {
							log.Errorf("Unable to insert: %v", err)
							return
						}
						atomic.AddInt64(&inserts, 1)
						c++

						// Control rate
						if c > 0 && c%1000 == 0 {
							delta := time.Now().Sub(start)
							if delta < targetDeltaFor1000Points {
								time.Sleep(targetDeltaFor1000Points - delta)
							}
							start = time.Now()
						}
					}
				}
				fmt.Print(".")
			}
		}()
	}

	wg.Wait()
	report()
}
<commit_msg>tdbdemo uses strings now<commit_after>package main

import (
	"fmt"
	"math/rand"
	"net/http"
	_ "net/http/pprof"
	"runtime"
	"sync"
	"sync/atomic"
	"time"

	"github.com/dustin/go-humanize"
	"github.com/getlantern/golog"
	"github.com/getlantern/tdb"
	"github.com/jmcvetta/randutil"
)

var (
	log = golog.LoggerFor("tdbdemo")
)

func main() {
	go func() {
		log.Error(http.ListenAndServe("localhost:4000", nil))
	}()

	numReporters := 5000
	uniquesPerReporter := 1000
	uniquesPerPeriod := 100
	valuesPerPeriod := 5000
	reportingPeriods := 100000
	resolution := 5 * time.Minute
	retainPeriods := 24
	retentionPeriod := time.Duration(retainPeriods) * resolution
	targetPointsPerSecond := 200000
	numWriters := 4
	targetPointsPerSecondPerWriter := targetPointsPerSecond / numWriters
	targetDeltaFor1000Points := 1000 * time.Second / time.Duration(targetPointsPerSecondPerWriter)
	log.Debugf("Target delta for 1000 points: %v", targetDeltaFor1000Points)

	reporters := make([]string, 0)
	for i := 0; i < numReporters; i++ {
		reporter, _ := randutil.AlphaStringRange(15, 25)
		reporters = append(reporters, reporter)
	}
	uniques := make([]string, 0)
	for i := 0; i < uniquesPerReporter; i++ {
		unique, _ := randutil.AlphaStringRange(150, 250)
		uniques = append(uniques, unique)
	}

	db, err := tdb.NewDB(&tdb.DBOpts{
		Dir:                  "/tmp/tdbdemo",
		RocksDBStatsInterval: 60 * time.Second,
	})
	if err != nil {
		log.Fatal(err)
	}
	err = db.CreateTable(&tdb.TableOpts{
		Name:             "test",
		RetentionPeriod:  retentionPeriod,
		MaxMemStoreBytes: 250 * 1024 * 1024,
		MaxFlushLatency:  1 * time.Minute,
		SQL: fmt.Sprintf(`
SELECT
	SUM(i) AS i,
	SUM(ii) AS ii,
	AVG(ii) / AVG(i) AS iii
FROM inbound
GROUP BY period(%v)`, resolution),
	})
	if err != nil {
		log.Fatal(err)
	}

	inserts := int64(0)
	start := time.Now()

	report := func() {
		delta := time.Now().Sub(start)
		start = time.Now()
		i := atomic.SwapInt64(&inserts, 0)
		var ms runtime.MemStats
		runtime.ReadMemStats(&ms)
		preGC := float64(ms.HeapAlloc) / 1024.0 / 1024.0
		runtime.GC()
		runtime.ReadMemStats(&ms)
		postGC := float64(ms.HeapAlloc) / 1024.0 / 1024.0
		fmt.Printf(`
%s inserts at %s inserts per second
%v
HeapAlloc pre/post GC %f/%f MiB
`,
			humanize.Comma(i), humanize.Comma(i/int64(delta.Seconds())),
			db.PrintTableStats("test"),
			preGC, postGC)
	}

	go func() {
		for {
			tk := time.NewTicker(30 * time.Second)
			for range tk.C {
				report()
			}
		}
	}()

	go func() {
		for {
			tk := time.NewTicker(1 * time.Minute)
			for range tk.C {
				log.Debug("Running query")
				now := db.Now("test")
				q, err := db.SQLQuery(`
SELECT SUM(ii) AS the_count
FROM test
GROUP BY period(168h)
`)
				if err != nil {
					log.Errorf("Unable to build query: %v", err)
					continue
				}
				start := time.Now()
				result, err := q.Run()
				delta := time.Now().Sub(start)
				if err != nil {
					log.Errorf("Unable to run query: %v", err)
					continue
				}
				count := float64(0)
				if len(result.Entries) != 1 {
					log.Fatalf("Unexpected result entries: %d", len(result.Entries))
				}
				count = result.Entries[0].Value("the_count", 0)
				fmt.Printf("\nQuery at %v returned %v in %v\n", now, humanize.Comma(int64(count)), delta)
			}
		}
	}()

	var wg sync.WaitGroup
	wg.Add(numWriters)
	for _w := 0; _w < numWriters; _w++ {
		go func() {
			defer wg.Done()
			c := 0
			start := time.Now()
			for i := 0; i < reportingPeriods; i++ {
				ts := time.Now()
				uqs := make([]int, 0, uniquesPerPeriod)
				for u := 0; u < uniquesPerPeriod; u++ {
					uqs = append(uqs, rand.Intn(uniquesPerReporter))
				}
				for r := 0; r < numReporters/numWriters; r++ {
					for v := 0; v < valuesPerPeriod; v++ {
						p := &tdb.Point{
							Ts: ts,
							Dims: map[string]interface{}{
								"r": reporters[rand.Intn(len(reporters))],
								"u": uniques[uqs[rand.Intn(uniquesPerPeriod)]],
								"b": rand.Float64() > 0.99,
								"x": 1,
							},
							Vals: map[string]float64{
								"i":  float64(rand.Intn(100000)),
								"ii": 1,
							},
						}
						ierr := db.Insert("inbound", p)
						if ierr != nil {
							log.Errorf("Unable to insert: %v", err)
							return
						}
						atomic.AddInt64(&inserts, 1)
						c++

						// Control rate
						if c > 0 && c%1000 == 0 {
							delta := time.Now().Sub(start)
							if delta < targetDeltaFor1000Points {
								time.Sleep(targetDeltaFor1000Points - delta)
							}
							start = time.Now()
						}
					}
				}
				fmt.Print(".")
			}
		}()
	}

	wg.Wait()
	report()
}
<|endoftext|>


<commit_before>package terraform

import (
	"bytes"
	"encoding/gob"
	"errors"
	"fmt"
	"io"
	"sort"
	"sync"

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

// State keeps track of a snapshot state-of-the-world that Terraform
// can use to keep track of what real world resources it is actually
// managing.
type State struct {
	Outputs   map[string]string
	Resources map[string]*ResourceState
	Tainted   map[string]struct{}

	once sync.Once
}

func (s *State) init() {
	s.once.Do(func() {
		if s.Resources == nil {
			s.Resources = make(map[string]*ResourceState)
		}

		if s.Tainted == nil {
			s.Tainted = make(map[string]struct{})
		}
	})
}

func (s *State) deepcopy() *State {
	result := new(State)
	result.init()
	if s != nil {
		for k, v := range s.Resources {
			result.Resources[k] = v
		}
		for k, v := range s.Tainted {
			result.Tainted[k] = v
		}
	}

	return result
}

// prune is a helper that removes any empty IDs from the state
// and cleans it up in general.
func (s *State) prune() {
	for k, v := range s.Resources {
		if v.ID == "" {
			delete(s.Resources, k)
		}
	}
}

// Orphans returns a list of keys of resources that are in the State
// but aren't present in the configuration itself. Hence, these keys
// represent the state of resources that are orphans.
func (s *State) Orphans(c *config.Config) []string {
	keys := make(map[string]struct{})
	for k, _ := range s.Resources {
		keys[k] = struct{}{}
	}

	for _, r := range c.Resources {
		delete(keys, r.Id())

		// Mark all the counts as not orphans.
		for i := 0; i < r.Count; i++ {
			delete(keys, fmt.Sprintf("%s.%d", r.Id(), i))
		}
	}

	result := make([]string, 0, len(keys))
	for k, _ := range keys {
		result = append(result, k)
	}

	return result
}

func (s *State) String() string {
	if len(s.Resources) == 0 {
		return "<no state>"
	}

	var buf bytes.Buffer

	names := make([]string, 0, len(s.Resources))
	for name, _ := range s.Resources {
		names = append(names, name)
	}
	sort.Strings(names)

	for _, k := range names {
		rs := s.Resources[k]
		id := rs.ID
		if id == "" {
			id = "<not created>"
		}

		taintStr := ""
		if _, ok := s.Tainted[k]; ok {
			taintStr = " (tainted)"
		}

		buf.WriteString(fmt.Sprintf("%s:%s\n", k, taintStr))
		buf.WriteString(fmt.Sprintf("  ID = %s\n", id))

		attrKeys := make([]string, 0, len(rs.Attributes))
		for ak, _ := range rs.Attributes {
			if ak == "id" {
				continue
			}

			attrKeys = append(attrKeys, ak)
		}
		sort.Strings(attrKeys)

		for _, ak := range attrKeys {
			av := rs.Attributes[ak]
			buf.WriteString(fmt.Sprintf("  %s = %s\n", ak, av))
		}

		if len(rs.Dependencies) > 0 {
			buf.WriteString(fmt.Sprintf("\n  Dependencies:\n"))
			for _, dep := range rs.Dependencies {
				buf.WriteString(fmt.Sprintf("    %s\n", dep.ID))
			}
		}
	}

	if len(s.Outputs) > 0 {
		buf.WriteString("\nOutputs:\n\n")

		ks := make([]string, 0, len(s.Outputs))
		for k, _ := range s.Outputs {
			ks = append(ks, k)
		}
		sort.Strings(ks)

		for _, k := range ks {
			v := s.Outputs[k]
			buf.WriteString(fmt.Sprintf("%s = %s\n", k, v))
		}
	}

	return buf.String()
}

// sensitiveState is used to store sensitive state information
// that should not be serialized. This is only used temporarily
// and is restored into the state.
type sensitiveState struct {
	ConnInfo map[string]map[string]string

	once sync.Once
}

func (s *sensitiveState) init() {
	s.once.Do(func() {
		s.ConnInfo = make(map[string]map[string]string)
	})
}

// The format byte is prefixed into the state file format so that we have
// the ability in the future to change the file format if we want for any
// reason.
const stateFormatMagic = "tfstate"
const stateFormatVersion byte = 1

// ReadState reads a state structure out of a reader in the format that
// was written by WriteState.
func ReadState(src io.Reader) (*State, error) {
	var result *State
	var err error
	n := 0

	// Verify the magic bytes
	magic := make([]byte, len(stateFormatMagic))
	for n < len(magic) {
		n, err = src.Read(magic[n:])
		if err != nil {
			return nil, fmt.Errorf("error while reading magic bytes: %s", err)
		}
	}
	if string(magic) != stateFormatMagic {
		return nil, fmt.Errorf("not a valid state file")
	}

	// Verify the version is something we can read
	var formatByte [1]byte
	n, err = src.Read(formatByte[:])
	if err != nil {
		return nil, err
	}
	if n != len(formatByte) {
		return nil, errors.New("failed to read state version byte")
	}

	if formatByte[0] != stateFormatVersion {
		return nil, fmt.Errorf("unknown state file version: %d", formatByte[0])
	}

	// Decode
	dec := gob.NewDecoder(src)
	if err := dec.Decode(&result); err != nil {
		return nil, err
	}

	return result, nil
}

// WriteState writes a state somewhere in a binary format.
func WriteState(d *State, dst io.Writer) error {
	// Write the magic bytes so we can determine the file format later
	n, err := dst.Write([]byte(stateFormatMagic))
	if err != nil {
		return err
	}
	if n != len(stateFormatMagic) {
		return errors.New("failed to write state format magic bytes")
	}

	// Write a version byte so we can iterate on version at some point
	n, err = dst.Write([]byte{stateFormatVersion})
	if err != nil {
		return err
	}
	if n != 1 {
		return errors.New("failed to write state version byte")
	}

	// Prevent sensitive information from being serialized
	sensitive := &sensitiveState{}
	sensitive.init()
	for name, r := range d.Resources {
		if r.ConnInfo != nil {
			sensitive.ConnInfo[name] = r.ConnInfo
			r.ConnInfo = nil
		}
	}

	// Serialize the state
	err = gob.NewEncoder(dst).Encode(d)

	// Restore the state
	for name, info := range sensitive.ConnInfo {
		d.Resources[name].ConnInfo = info
	}

	return err
}

// ResourceState holds the state of a resource that is used so that
// a provider can find and manage an existing resource as well as for
// storing attributes that are uesd to populate variables of child
// resources.
//
// Attributes has attributes about the created resource that are
// queryable in interpolation: "${type.id.attr}"
//
// Extra is just extra data that a provider can return that we store
// for later, but is not exposed in any way to the user.
type ResourceState struct {
	// This is filled in and managed by Terraform, and is the resource
	// type itself such as "mycloud_instance". If a resource provider sets
	// this value, it won't be persisted.
	Type string

	// The attributes below are all meant to be filled in by the
	// resource providers themselves. Documentation for each are above
	// each element.

	// A unique ID for this resource. This is opaque to Terraform
	// and is only meant as a lookup mechanism for the providers.
	ID string

	// Attributes are basic information about the resource. Any keys here
	// are accessible in variable format within Terraform configurations:
	// ${resourcetype.name.attribute}.
	Attributes map[string]string

	// ConnInfo is used for the providers to export information which is
	// used to connect to the resource for provisioning. For example,
	// this could contain SSH or WinRM credentials.
	ConnInfo map[string]string

	// Extra information that the provider can store about a resource.
	// This data is opaque, never shown to the user, and is sent back to
	// the provider as-is for whatever purpose appropriate.
	Extra map[string]interface{}

	// Dependencies are a list of things that this resource relies on
	// existing to remain intact. For example: an AWS instance might
	// depend on a subnet (which itself might depend on a VPC, and so
	// on).
	//
	// Terraform uses this information to build valid destruction
	// orders and to warn the user if they're destroying a resource that
	// another resource depends on.
	//
	// Things can be put into this list that may not be managed by
	// Terraform. If Terraform doesn't find a matching ID in the
	// overall state, then it assumes it isn't managed and doesn't
	// worry about it.
	Dependencies []ResourceDependency
}

// MergeDiff takes a ResourceDiff and merges the attributes into
// this resource state in order to generate a new state. This new
// state can be used to provide updated attribute lookups for
// variable interpolation.
//
// If the diff attribute requires computing the value, and hence
// won't be available until apply, the value is replaced with the
// computeID.
func (s *ResourceState) MergeDiff(d *ResourceDiff) *ResourceState {
	var result ResourceState
	if s != nil {
		result = *s
	}

	result.Attributes = make(map[string]string)
	if s != nil {
		for k, v := range s.Attributes {
			result.Attributes[k] = v
		}
	}
	if d != nil {
		for k, diff := range d.Attributes {
			if diff.NewRemoved {
				delete(result.Attributes, k)
				continue
			}
			if diff.NewComputed {
				result.Attributes[k] = config.UnknownVariableValue
				continue
			}

			result.Attributes[k] = diff.New
		}
	}

	return &result
}

// ResourceDependency maps a resource to another resource that it
// depends on to remain intact and uncorrupted.
type ResourceDependency struct {
	// ID of the resource that we depend on. This ID should map
	// directly to another ResourceState's ID.
	ID string
}
<commit_msg>terraform: GoString for *ResourceState<commit_after>package terraform

import (
	"bytes"
	"encoding/gob"
	"errors"
	"fmt"
	"io"
	"sort"
	"sync"

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

// State keeps track of a snapshot state-of-the-world that Terraform
// can use to keep track of what real world resources it is actually
// managing.
type State struct {
	Outputs   map[string]string
	Resources map[string]*ResourceState
	Tainted   map[string]struct{}

	once sync.Once
}

func (s *State) init() {
	s.once.Do(func() {
		if s.Resources == nil {
			s.Resources = make(map[string]*ResourceState)
		}

		if s.Tainted == nil {
			s.Tainted = make(map[string]struct{})
		}
	})
}

func (s *State) deepcopy() *State {
	result := new(State)
	result.init()
	if s != nil {
		for k, v := range s.Resources {
			result.Resources[k] = v
		}
		for k, v := range s.Tainted {
			result.Tainted[k] = v
		}
	}

	return result
}

// prune is a helper that removes any empty IDs from the state
// and cleans it up in general.
func (s *State) prune() {
	for k, v := range s.Resources {
		if v.ID == "" {
			delete(s.Resources, k)
		}
	}
}

// Orphans returns a list of keys of resources that are in the State
// but aren't present in the configuration itself. Hence, these keys
// represent the state of resources that are orphans.
func (s *State) Orphans(c *config.Config) []string {
	keys := make(map[string]struct{})
	for k, _ := range s.Resources {
		keys[k] = struct{}{}
	}

	for _, r := range c.Resources {
		delete(keys, r.Id())

		// Mark all the counts as not orphans.
		for i := 0; i < r.Count; i++ {
			delete(keys, fmt.Sprintf("%s.%d", r.Id(), i))
		}
	}

	result := make([]string, 0, len(keys))
	for k, _ := range keys {
		result = append(result, k)
	}

	return result
}

func (s *State) String() string {
	if len(s.Resources) == 0 {
		return "<no state>"
	}

	var buf bytes.Buffer

	names := make([]string, 0, len(s.Resources))
	for name, _ := range s.Resources {
		names = append(names, name)
	}
	sort.Strings(names)

	for _, k := range names {
		rs := s.Resources[k]
		id := rs.ID
		if id == "" {
			id = "<not created>"
		}

		taintStr := ""
		if _, ok := s.Tainted[k]; ok {
			taintStr = " (tainted)"
		}

		buf.WriteString(fmt.Sprintf("%s:%s\n", k, taintStr))
		buf.WriteString(fmt.Sprintf("  ID = %s\n", id))

		attrKeys := make([]string, 0, len(rs.Attributes))
		for ak, _ := range rs.Attributes {
			if ak == "id" {
				continue
			}

			attrKeys = append(attrKeys, ak)
		}
		sort.Strings(attrKeys)

		for _, ak := range attrKeys {
			av := rs.Attributes[ak]
			buf.WriteString(fmt.Sprintf("  %s = %s\n", ak, av))
		}

		if len(rs.Dependencies) > 0 {
			buf.WriteString(fmt.Sprintf("\n  Dependencies:\n"))
			for _, dep := range rs.Dependencies {
				buf.WriteString(fmt.Sprintf("    %s\n", dep.ID))
			}
		}
	}

	if len(s.Outputs) > 0 {
		buf.WriteString("\nOutputs:\n\n")

		ks := make([]string, 0, len(s.Outputs))
		for k, _ := range s.Outputs {
			ks = append(ks, k)
		}
		sort.Strings(ks)

		for _, k := range ks {
			v := s.Outputs[k]
			buf.WriteString(fmt.Sprintf("%s = %s\n", k, v))
		}
	}

	return buf.String()
}

// sensitiveState is used to store sensitive state information
// that should not be serialized. This is only used temporarily
// and is restored into the state.
type sensitiveState struct {
	ConnInfo map[string]map[string]string

	once sync.Once
}

func (s *sensitiveState) init() {
	s.once.Do(func() {
		s.ConnInfo = make(map[string]map[string]string)
	})
}

// The format byte is prefixed into the state file format so that we have
// the ability in the future to change the file format if we want for any
// reason.
const stateFormatMagic = "tfstate"
const stateFormatVersion byte = 1

// ReadState reads a state structure out of a reader in the format that
// was written by WriteState.
func ReadState(src io.Reader) (*State, error) {
	var result *State
	var err error
	n := 0

	// Verify the magic bytes
	magic := make([]byte, len(stateFormatMagic))
	for n < len(magic) {
		n, err = src.Read(magic[n:])
		if err != nil {
			return nil, fmt.Errorf("error while reading magic bytes: %s", err)
		}
	}
	if string(magic) != stateFormatMagic {
		return nil, fmt.Errorf("not a valid state file")
	}

	// Verify the version is something we can read
	var formatByte [1]byte
	n, err = src.Read(formatByte[:])
	if err != nil {
		return nil, err
	}
	if n != len(formatByte) {
		return nil, errors.New("failed to read state version byte")
	}

	if formatByte[0] != stateFormatVersion {
		return nil, fmt.Errorf("unknown state file version: %d", formatByte[0])
	}

	// Decode
	dec := gob.NewDecoder(src)
	if err := dec.Decode(&result); err != nil {
		return nil, err
	}

	return result, nil
}

// WriteState writes a state somewhere in a binary format.
func WriteState(d *State, dst io.Writer) error {
	// Write the magic bytes so we can determine the file format later
	n, err := dst.Write([]byte(stateFormatMagic))
	if err != nil {
		return err
	}
	if n != len(stateFormatMagic) {
		return errors.New("failed to write state format magic bytes")
	}

	// Write a version byte so we can iterate on version at some point
	n, err = dst.Write([]byte{stateFormatVersion})
	if err != nil {
		return err
	}
	if n != 1 {
		return errors.New("failed to write state version byte")
	}

	// Prevent sensitive information from being serialized
	sensitive := &sensitiveState{}
	sensitive.init()
	for name, r := range d.Resources {
		if r.ConnInfo != nil {
			sensitive.ConnInfo[name] = r.ConnInfo
			r.ConnInfo = nil
		}
	}

	// Serialize the state
	err = gob.NewEncoder(dst).Encode(d)

	// Restore the state
	for name, info := range sensitive.ConnInfo {
		d.Resources[name].ConnInfo = info
	}

	return err
}

// ResourceState holds the state of a resource that is used so that
// a provider can find and manage an existing resource as well as for
// storing attributes that are uesd to populate variables of child
// resources.
//
// Attributes has attributes about the created resource that are
// queryable in interpolation: "${type.id.attr}"
//
// Extra is just extra data that a provider can return that we store
// for later, but is not exposed in any way to the user.
type ResourceState struct {
	// This is filled in and managed by Terraform, and is the resource
	// type itself such as "mycloud_instance". If a resource provider sets
	// this value, it won't be persisted.
	Type string

	// The attributes below are all meant to be filled in by the
	// resource providers themselves. Documentation for each are above
	// each element.

	// A unique ID for this resource. This is opaque to Terraform
	// and is only meant as a lookup mechanism for the providers.
	ID string

	// Attributes are basic information about the resource. Any keys here
	// are accessible in variable format within Terraform configurations:
	// ${resourcetype.name.attribute}.
	Attributes map[string]string

	// ConnInfo is used for the providers to export information which is
	// used to connect to the resource for provisioning. For example,
	// this could contain SSH or WinRM credentials.
	ConnInfo map[string]string

	// Extra information that the provider can store about a resource.
	// This data is opaque, never shown to the user, and is sent back to
	// the provider as-is for whatever purpose appropriate.
	Extra map[string]interface{}

	// Dependencies are a list of things that this resource relies on
	// existing to remain intact. For example: an AWS instance might
	// depend on a subnet (which itself might depend on a VPC, and so
	// on).
	//
	// Terraform uses this information to build valid destruction
	// orders and to warn the user if they're destroying a resource that
	// another resource depends on.
	//
	// Things can be put into this list that may not be managed by
	// Terraform. If Terraform doesn't find a matching ID in the
	// overall state, then it assumes it isn't managed and doesn't
	// worry about it.
	Dependencies []ResourceDependency
}

// MergeDiff takes a ResourceDiff and merges the attributes into
// this resource state in order to generate a new state. This new
// state can be used to provide updated attribute lookups for
// variable interpolation.
//
// If the diff attribute requires computing the value, and hence
// won't be available until apply, the value is replaced with the
// computeID.
func (s *ResourceState) MergeDiff(d *ResourceDiff) *ResourceState {
	var result ResourceState
	if s != nil {
		result = *s
	}

	result.Attributes = make(map[string]string)
	if s != nil {
		for k, v := range s.Attributes {
			result.Attributes[k] = v
		}
	}
	if d != nil {
		for k, diff := range d.Attributes {
			if diff.NewRemoved {
				delete(result.Attributes, k)
				continue
			}
			if diff.NewComputed {
				result.Attributes[k] = config.UnknownVariableValue
				continue
			}

			result.Attributes[k] = diff.New
		}
	}

	return &result
}

func (s *ResourceState) GoString() string {
	return fmt.Sprintf("*%#v", *s)
}

// ResourceDependency maps a resource to another resource that it
// depends on to remain intact and uncorrupted.
type ResourceDependency struct {
	// ID of the resource that we depend on. This ID should map
	// directly to another ResourceState's ID.
	ID string
}
<|endoftext|>


<commit_before>package hdfs

import (
	"fmt"
	. "github.com/eaciit/hdc/hdfs"
	"os"
	"testing"
	"time"
)

func killApp(code int) {
	os.Exit(code)
}

var h *WebHdfs
var e error

func TestConnect(t *testing.T) {
	h, e = NewWebHdfs(NewHdfsConfig("http://192.168.0.223:50070", "hdfs"))
	if e != nil {
		t.Fatalf(e.Error())
		defer killApp(1000)
	}
	h.Config.TimeOut = 2 * time.Millisecond
	h.Config.PoolSize = 100
}

func TestDelete(t *testing.T) {
	if es := h.Delete(true, "/user/ariefdarmawan"); es != nil {
		t.Errorf("%s", func() string {
			s := ""
			for k, e := range es {
				s += fmt.Sprintf("%s = %s", k, e.Error())
			}
			return s
		}())
	}
}

func TestCreateDir(t *testing.T) {
	es := h.MakeDirs([]string{"/user/ariefdarmawan/inbox", "/user/ariefdarmawan/temp", "/user/ariefdarmawan/outbox"}, "")
	if es != nil {
		for k, v := range es {
			t.Error(fmt.Sprintf("Error when create %v : %v \n", k, v))
		}
	}
}

func TestChangeOwner(t *testing.T) {
	if e = h.SetOwner("/user/ariefdarmawan", "ariefdarmawan", ""); e != nil {
		t.Error(e.Error())
	}
}

/*
	fmt.Println(">>>> TEST COPY DIR <<<<")
	e, es = h.PutDir("/Users/ariefdarmawan/Temp/ECFZ/TempVisa/JSON", "/user/ariefdarmawan/inbox/ecfz/json")
	if es != nil {
		for k, v := range es {
			t.Error(fmt.Sprintf("Error when create %v : %v \n", k, v))
		}
	}
*/

func TestPutFile(t *testing.T) {
	e = h.Put("d://test.txt", "/user/ariefdarmawan/inbox/test.txt", "", nil)
	if e != nil {
		t.Error(e.Error())
	}
}

func TestGetStatus(t *testing.T) {
	hdata, e := h.List("/user/ariefdarmawan")
	if e != nil {
		t.Error(e.Error())
	} else {
		fmt.Printf("Data Processed :\n%v\n", len(hdata.FileStatuses.FileStatus))
	}
}
<commit_msg>update<commit_after>package hdfs

import (
	"fmt"
	. "github.com/eaciit/hdc/hdfs"
	"log"
	"os"
	"testing"
	"time"
)

func killApp(code int) {
	os.Exit(code)
}

var h *WebHdfs
var e error

func TestConnect(t *testing.T) {
	h, e = NewWebHdfs(NewHdfsConfig("http://192.168.0.223:50070", "hdfs"))
	if e != nil {
		t.Fatalf(e.Error())
		defer killApp(1000)
	}
	h.Config.TimeOut = 2 * time.Millisecond
	h.Config.PoolSize = 100
}

func TestList(t *testing.T) {
	list, err := h.List("/")
	if err != nil {
		t.Fatal(err.Error())
		defer killApp(1000)
	}
	log.Println(list)
}

func TestDelete(t *testing.T) {
	if es := h.Delete(true, "/user/ariefdarmawan"); es != nil {
		t.Errorf("%s", func() string {
			s := ""
			for k, e := range es {
				s += fmt.Sprintf("%s = %s", k, e.Error())
			}
			return s
		}())
	}
}

func TestCreateDir(t *testing.T) {
	es := h.MakeDirs([]string{"/user/ariefdarmawan/inbox", "/user/ariefdarmawan/temp", "/user/ariefdarmawan/outbox"}, "")
	if es != nil {
		for k, v := range es {
			t.Error(fmt.Sprintf("Error when create %v : %v \n", k, v))
		}
	}
}

func TestChangeOwner(t *testing.T) {
	if e = h.SetOwner("/user/ariefdarmawan", "ariefdarmawan", ""); e != nil {
		t.Error(e.Error())
	}
}

/*
	fmt.Println(">>>> TEST COPY DIR <<<<")
	e, es = h.PutDir("/Users/ariefdarmawan/Temp/ECFZ/TempVisa/JSON", "/user/ariefdarmawan/inbox/ecfz/json")
	if es != nil {
		for k, v := range es {
			t.Error(fmt.Sprintf("Error when create %v : %v \n", k, v))
		}
	}
*/

func TestPutFile(t *testing.T) {
	e = h.Put("d://test.txt", "/user/ariefdarmawan/inbox/test.txt", "", nil)
	if e != nil {
		t.Error(e.Error())
	}
}

func TestGetStatus(t *testing.T) {
	hdata, e := h.List("/user/ariefdarmawan")
	if e != nil {
		t.Error(e.Error())
	} else {
		fmt.Printf("Data Processed :\n%v\n", len(hdata.FileStatuses.FileStatus))
	}
}
<|endoftext|>


<commit_before>// Copyright 2012 Apcera Inc. All rights reserved.

package test

import (
	"encoding/json"
	"net"
	"regexp"
	"testing"
	"time"

	"github.com/apcera/gnatsd/server"
)

var s *natsServer

func TestStartup(t *testing.T) {
	s = startServer(t, server.DEFAULT_PORT, "")
}

type sendFun func(string)
type expectFun func(*regexp.Regexp) []byte

// Closure version for easier reading
func sendCommand(t *testing.T, c net.Conn) sendFun {
	return func(op string) {
		sendProto(t, c, op)
	}
}

// Closure version for easier reading
func expectCommand(t *testing.T, c net.Conn) expectFun {
	return func(re *regexp.Regexp)([]byte) {
		return expectResult(t, c, re)
	}
}

// Send the protocol command to the server.
func sendProto(t *testing.T, c net.Conn, op string) {
	n, err := c.Write([]byte(op))
	if err != nil {
		t.Fatalf("Error writing command to conn: %v\n", err)
	}
	if n != len(op) {
		t.Fatalf("Partial write: %d vs %d\n", n, len(op))
	}
}

// Reuse expect buffer
var expBuf = make([]byte, 32768)

// Test result from server against regexp
func expectResult(t *testing.T, c net.Conn, re *regexp.Regexp) []byte {
	// Wait for commands to be processed and results queued for read
	time.Sleep(50 * time.Millisecond)
	c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
	defer c.SetReadDeadline(time.Time{})

	n, err := c.Read(expBuf)
	if err != nil {
		t.Fatalf("Error reading from conn: %v\n", err)
	}
	buf := expBuf[:n]
	if !re.Match(buf) {
		t.Fatalf("Response did not match expected: '%s' vs '%s'\n", buf, re)
	}
	return buf
}

// This will check that we got what we expected.
func checkMsg(t *testing.T, m [][]byte, subject, sid, reply, len, msg string) {
	if string(m[SUB_INDEX]) != subject {
		t.Fatalf("Did not get correct subject: expected '%s' got '%s'\n", subject, m[SUB_INDEX])
	}
	if string(m[SID_INDEX]) != sid {
		t.Fatalf("Did not get correct sid: exepected '%s' got '%s'\n", sid, m[SID_INDEX])
	}
	if string(m[REPLY_INDEX]) != reply {
		t.Fatalf("Did not get correct reply: exepected '%s' got '%s'\n", reply, m[REPLY_INDEX])
	}
	if string(m[LEN_INDEX]) != len {
		t.Fatalf("Did not get correct msg length: expected '%s' got '%s'\n", len, m[LEN_INDEX])
	}
	if string(m[MSG_INDEX]) != msg {
		t.Fatalf("Did not get correct msg: expected '%s' got '%s'\n", msg, m[MSG_INDEX])
	}
}

// Closure for expectMsgs
func expectMsgsCommand(t *testing.T, ef expectFun) func(int) [][][]byte {
	return func(expected int) [][][]byte {
		buf := ef(msgRe)
		matches := msgRe.FindAllSubmatch(buf, -1)
		if len(matches) != expected {
			t.Fatalf("Did not get correct # msgs: %d vs %d\n", len(matches), expected)
		}
		return matches
	}
}

var infoRe = regexp.MustCompile(`\AINFO\s+([^\r\n]+)\r\n`)
var pongRe = regexp.MustCompile(`\APONG\r\n`)
var msgRe  = regexp.MustCompile(`(?:(?:MSG\s+([^\s]+)\s+([^\s]+)\s+(([^\s]+)[^\S\r\n]+)?(\d+)\r\n([^\\r\\n]*?)\r\n)+?)`)

const (
	SUB_INDEX   = 1
	SID_INDEX   = 2
	REPLY_INDEX = 4
	LEN_INDEX   = 5
	MSG_INDEX   = 6
)

func doDefaultConnect(t *testing.T, c net.Conn) {
	// Basic Connect
	sendProto(t, c, "CONNECT {\"verbose\":false,\"pedantic\":false,\"ssl_required\":false}\r\n")
	buf := expectResult(t, c, infoRe)
	js := infoRe.FindAllSubmatch(buf, 1)[0][1]
	var sinfo server.Info
	err := json.Unmarshal(js, &sinfo)
	if err != nil {
		t.Fatalf("Could not unmarshal INFO json: %v\n", err)
	}
}

func setupConn(t *testing.T, c net.Conn) (sendFun, expectFun) {
	doDefaultConnect(t, c)
	send := sendCommand(t, c)
	expect := expectCommand(t, c)
	return send, expect
}

func TestProtoBasics(t *testing.T) {
	c := createClientConn(t, "localhost", server.DEFAULT_PORT)
	send, expect := setupConn(t, c)
	expectMsgs := expectMsgsCommand(t, expect)
	defer c.Close()

	// Ping
	send("PING\r\n")
	expect(pongRe)

	// Single Msg
	send("SUB foo 1\r\nPUB foo 5\r\nhello\r\n")
	matches := expectMsgs(1)
	checkMsg(t, matches[0], "foo", "1", "", "5", "hello")

	// 2 Messages
	send("SUB * 2\r\nPUB foo 2\r\nok\r\n")
	matches = expectMsgs(2)
	checkMsg(t, matches[0], "foo", "1", "", "2", "ok")
	checkMsg(t, matches[1], "foo", "2", "", "2", "ok")
}

func TestUnsubMax(t *testing.T) {
	c := createClientConn(t, "localhost", server.DEFAULT_PORT)
	send, expect := setupConn(t, c)
	expectMsgs := expectMsgsCommand(t, expect)
	defer c.Close()

	send("SUB foo 22\r\n")
	send("UNSUB 22 2\r\n")
	for i := 0; i < 100; i++ {
		send("PUB foo 2\r\nok\r\n")
	}
	matches := expectMsgs(2)
	checkMsg(t, matches[0], "foo", "22", "", "2", "ok")
	checkMsg(t, matches[1], "foo", "22", "", "2", "ok")
}

func TestQueueSub(t *testing.T) {
	c := createClientConn(t, "localhost", server.DEFAULT_PORT)
	send, expect := setupConn(t, c)
	expectMsgs := expectMsgsCommand(t, expect)
	defer c.Close()

	sent := 100
	send("SUB foo qgroup1 22\r\n")
	send("SUB foo qgroup1 32\r\n")
	for i := 0; i < sent; i++ {
		send("PUB foo 2\r\nok\r\n")
	}
	matches := expectMsgs(sent)
	sids := make(map[string]int)
	for _, m := range matches {
		sids[string(m[SID_INDEX])]++
	}
	if len(sids) != 2 {
		t.Fatalf("Expected only 2 sids, got %d\n", len(sids))
	}
	for k, c := range sids {
		if c < 35 {
			t.Fatalf("Expected ~50 (+-15) msgs for '%s', got %d\n", k, c)
		}
	}
}

func TestStopServer(t *testing.T) {
	s.stopServer()
}
<commit_msg>Make support funcs work with benchmark also<commit_after>// Copyright 2012 Apcera Inc. All rights reserved.

package test

import (
	"encoding/json"
	"net"
	"regexp"
	"testing"
	"time"

	"github.com/apcera/gnatsd/server"
)

var s *natsServer

func TestStartup(t *testing.T) {
	s = startServer(t, server.DEFAULT_PORT, "")
}

type sendFun func(string)
type expectFun func(*regexp.Regexp) []byte

// Closure version for easier reading
func sendCommand(t tLogger, c net.Conn) sendFun {
	return func(op string) {
		sendProto(t, c, op)
	}
}

// Closure version for easier reading
func expectCommand(t tLogger, c net.Conn) expectFun {
	return func(re *regexp.Regexp)([]byte) {
		return expectResult(t, c, re)
	}
}

// Send the protocol command to the server.
func sendProto(t tLogger, c net.Conn, op string) {
	n, err := c.Write([]byte(op))
	if err != nil {
		t.Fatalf("Error writing command to conn: %v\n", err)
	}
	if n != len(op) {
		t.Fatalf("Partial write: %d vs %d\n", n, len(op))
	}
}

// Reuse expect buffer
var expBuf = make([]byte, 32768)

// Test result from server against regexp
func expectResult(t tLogger, c net.Conn, re *regexp.Regexp) []byte {
	// Wait for commands to be processed and results queued for read
	time.Sleep(50 * time.Millisecond)
	c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
	defer c.SetReadDeadline(time.Time{})

	n, err := c.Read(expBuf)
	if err != nil {
		t.Fatalf("Error reading from conn: %v\n", err)
	}
	buf := expBuf[:n]
	if !re.Match(buf) {
		t.Fatalf("Response did not match expected: '%s' vs '%s'\n", buf, re)
	}
	return buf
}

// This will check that we got what we expected.
func checkMsg(t tLogger, m [][]byte, subject, sid, reply, len, msg string) {
	if string(m[SUB_INDEX]) != subject {
		t.Fatalf("Did not get correct subject: expected '%s' got '%s'\n", subject, m[SUB_INDEX])
	}
	if string(m[SID_INDEX]) != sid {
		t.Fatalf("Did not get correct sid: exepected '%s' got '%s'\n", sid, m[SID_INDEX])
	}
	if string(m[REPLY_INDEX]) != reply {
		t.Fatalf("Did not get correct reply: exepected '%s' got '%s'\n", reply, m[REPLY_INDEX])
	}
	if string(m[LEN_INDEX]) != len {
		t.Fatalf("Did not get correct msg length: expected '%s' got '%s'\n", len, m[LEN_INDEX])
	}
	if string(m[MSG_INDEX]) != msg {
		t.Fatalf("Did not get correct msg: expected '%s' got '%s'\n", msg, m[MSG_INDEX])
	}
}

// Closure for expectMsgs
func expectMsgsCommand(t tLogger, ef expectFun) func(int) [][][]byte {
	return func(expected int) [][][]byte {
		buf := ef(msgRe)
		matches := msgRe.FindAllSubmatch(buf, -1)
		if len(matches) != expected {
			t.Fatalf("Did not get correct # msgs: %d vs %d\n", len(matches), expected)
		}
		return matches
	}
}

var infoRe = regexp.MustCompile(`\AINFO\s+([^\r\n]+)\r\n`)
var pongRe = regexp.MustCompile(`\APONG\r\n`)
var msgRe  = regexp.MustCompile(`(?:(?:MSG\s+([^\s]+)\s+([^\s]+)\s+(([^\s]+)[^\S\r\n]+)?(\d+)\r\n([^\\r\\n]*?)\r\n)+?)`)

const (
	SUB_INDEX   = 1
	SID_INDEX   = 2
	REPLY_INDEX = 4
	LEN_INDEX   = 5
	MSG_INDEX   = 6
)

func doDefaultConnect(t tLogger, c net.Conn) {
	// Basic Connect
	sendProto(t, c, "CONNECT {\"verbose\":false,\"pedantic\":false,\"ssl_required\":false}\r\n")
	buf := expectResult(t, c, infoRe)
	js := infoRe.FindAllSubmatch(buf, 1)[0][1]
	var sinfo server.Info
	err := json.Unmarshal(js, &sinfo)
	if err != nil {
		t.Fatalf("Could not unmarshal INFO json: %v\n", err)
	}
}

func setupConn(t tLogger, c net.Conn) (sendFun, expectFun) {
	doDefaultConnect(t, c)
	send := sendCommand(t, c)
	expect := expectCommand(t, c)
	return send, expect
}

func TestProtoBasics(t *testing.T) {
	c := createClientConn(t, "localhost", server.DEFAULT_PORT)
	send, expect := setupConn(t, c)
	expectMsgs := expectMsgsCommand(t, expect)
	defer c.Close()

	// Ping
	send("PING\r\n")
	expect(pongRe)

	// Single Msg
	send("SUB foo 1\r\nPUB foo 5\r\nhello\r\n")
	matches := expectMsgs(1)
	checkMsg(t, matches[0], "foo", "1", "", "5", "hello")

	// 2 Messages
	send("SUB * 2\r\nPUB foo 2\r\nok\r\n")
	matches = expectMsgs(2)
	checkMsg(t, matches[0], "foo", "1", "", "2", "ok")
	checkMsg(t, matches[1], "foo", "2", "", "2", "ok")
}

func TestUnsubMax(t *testing.T) {
	c := createClientConn(t, "localhost", server.DEFAULT_PORT)
	send, expect := setupConn(t, c)
	expectMsgs := expectMsgsCommand(t, expect)
	defer c.Close()

	send("SUB foo 22\r\n")
	send("UNSUB 22 2\r\n")
	for i := 0; i < 100; i++ {
		send("PUB foo 2\r\nok\r\n")
	}
	matches := expectMsgs(2)
	checkMsg(t, matches[0], "foo", "22", "", "2", "ok")
	checkMsg(t, matches[1], "foo", "22", "", "2", "ok")
}

func TestQueueSub(t *testing.T) {
	c := createClientConn(t, "localhost", server.DEFAULT_PORT)
	send, expect := setupConn(t, c)
	expectMsgs := expectMsgsCommand(t, expect)
	defer c.Close()

	sent := 100
	send("SUB foo qgroup1 22\r\n")
	send("SUB foo qgroup1 32\r\n")
	for i := 0; i < sent; i++ {
		send("PUB foo 2\r\nok\r\n")
	}
	matches := expectMsgs(sent)
	sids := make(map[string]int)
	for _, m := range matches {
		sids[string(m[SID_INDEX])]++
	}
	if len(sids) != 2 {
		t.Fatalf("Expected only 2 sids, got %d\n", len(sids))
	}
	for k, c := range sids {
		if c < 35 {
			t.Fatalf("Expected ~50 (+-15) msgs for '%s', got %d\n", k, c)
		}
	}
}

func TestStopServer(t *testing.T) {
	s.stopServer()
}
<|endoftext|>


<commit_before>package helper

import (
	"errors"
	"math/big"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core"
	"github.com/ethereum/go-ethereum/core/state"
	"github.com/ethereum/go-ethereum/core/vm"
	"github.com/ethereum/go-ethereum/crypto"
)

type Env struct {
	depth        int
	state        *state.StateDB
	skipTransfer bool
	initial      bool
	Gas          *big.Int

	origin common.Address
	//parent   common.Hash
	coinbase common.Address

	number     *big.Int
	time       int64
	difficulty *big.Int
	gasLimit   *big.Int

	logs state.Logs

	vmTest bool
}

func NewEnv(state *state.StateDB) *Env {
	return &Env{
		state: state,
	}
}

func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env {
	env := NewEnv(state)

	env.origin = common.HexToAddress(exeValues["caller"])
	//env.parent = common.Hex2Bytes(envValues["previousHash"])
	env.coinbase = common.HexToAddress(envValues["currentCoinbase"])
	env.number = common.Big(envValues["currentNumber"])
	env.time = common.Big(envValues["currentTimestamp"]).Int64()
	env.difficulty = common.Big(envValues["currentDifficulty"])
	env.gasLimit = common.Big(envValues["currentGasLimit"])
	env.Gas = new(big.Int)

	return env
}

func (self *Env) Origin() common.Address { return self.origin }
func (self *Env) BlockNumber() *big.Int  { return self.number }

//func (self *Env) PrevHash() []byte      { return self.parent }
func (self *Env) Coinbase() common.Address { return self.coinbase }
func (self *Env) Time() int64              { return self.time }
func (self *Env) Difficulty() *big.Int     { return self.difficulty }
func (self *Env) State() *state.StateDB    { return self.state }
func (self *Env) GasLimit() *big.Int       { return self.gasLimit }
func (self *Env) VmType() vm.Type          { return vm.StdVmTy }
func (self *Env) GetHash(n uint64) common.Hash {
	return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String())))
}
func (self *Env) AddLog(log *state.Log) {
	self.state.AddLog(log)
}
func (self *Env) Depth() int     { return self.depth }
func (self *Env) SetDepth(i int) { self.depth = i }
func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error {
	if self.skipTransfer {
		// ugly hack
		if self.initial {
			self.initial = false
			return nil
		}

		if from.Balance().Cmp(amount) < 0 {
			return errors.New("Insufficient balance in account")
		}

		return nil
	}
	return vm.Transfer(from, to, amount)
}

func (self *Env) vm(addr *common.Address, data []byte, gas, price, value *big.Int) *core.Execution {
	exec := core.NewExecution(self, addr, data, gas, price, value)

	return exec
}

func (self *Env) Call(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
	if self.vmTest && self.depth > 0 {
		caller.ReturnGas(gas, price)

		return nil, nil
	}
	exe := self.vm(&addr, data, gas, price, value)
	ret, err := exe.Call(addr, caller)
	self.Gas = exe.Gas

	return ret, err

}
func (self *Env) CallCode(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
	if self.vmTest && self.depth > 0 {
		caller.ReturnGas(gas, price)

		return nil, nil
	}

	caddr := caller.Address()
	exe := self.vm(&caddr, data, gas, price, value)
	return exe.Call(addr, caller)
}

func (self *Env) Create(caller vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
	exe := self.vm(nil, data, gas, price, value)
	if self.vmTest {
		caller.ReturnGas(gas, price)

		nonce := self.state.GetNonce(caller.Address())
		obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce))

		return nil, nil, obj
	} else {
		return exe.Create(caller)
	}
}

func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) {
	var (
		to    = common.HexToAddress(exec["address"])
		from  = common.HexToAddress(exec["caller"])
		data  = FromHex(exec["data"])
		gas   = common.Big(exec["gas"])
		price = common.Big(exec["gasPrice"])
		value = common.Big(exec["value"])
	)
	// Reset the pre-compiled contracts for VM tests.
	vm.Precompiled = make(map[string]*vm.PrecompiledAccount)

	caller := state.GetOrNewStateObject(from)

	vmenv := NewEnvFromMap(state, env, exec)
	vmenv.vmTest = true
	vmenv.skipTransfer = true
	vmenv.initial = true
	ret, err := vmenv.Call(caller, to, data, gas, price, value)

	return ret, vmenv.state.Logs(), vmenv.Gas, err
}

func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) {
	var (
		keyPair, _ = crypto.NewKeyPairFromSec([]byte(common.Hex2Bytes(tx["secretKey"])))
		data       = FromHex(tx["data"])
		gas        = common.Big(tx["gasLimit"])
		price      = common.Big(tx["gasPrice"])
		value      = common.Big(tx["value"])
		nonce      = common.Big(tx["nonce"]).Uint64()
		caddr      = common.HexToAddress(env["currentCoinbase"])
	)

	var to *common.Address
	if len(tx["to"]) > 2 {
		t := common.HexToAddress(tx["to"])
		to = &t
	}
	// Set pre compiled contracts
	vm.Precompiled = vm.PrecompiledContracts()

	snapshot := statedb.Copy()
	coinbase := statedb.GetOrNewStateObject(caddr)
	coinbase.SetGasPool(common.Big(env["currentGasLimit"]))

	message := NewMessage(common.BytesToAddress(keyPair.Address()), to, data, value, gas, price, nonce)
	vmenv := NewEnvFromMap(statedb, env, tx)
	vmenv.origin = common.BytesToAddress(keyPair.Address())
	ret, _, err := core.ApplyMessage(vmenv, message, coinbase)
	if core.IsNonceErr(err) || core.IsInvalidTxErr(err) {
		statedb.Set(snapshot)
	}
	statedb.Update()

	return ret, vmenv.state.Logs(), vmenv.Gas, err
}

type Message struct {
	from              common.Address
	to                *common.Address
	value, gas, price *big.Int
	data              []byte
	nonce             uint64
}

func NewMessage(from common.Address, to *common.Address, data []byte, value, gas, price *big.Int, nonce uint64) Message {
	return Message{from, to, value, gas, price, data, nonce}
}

func (self Message) Hash() []byte                  { return nil }
func (self Message) From() (common.Address, error) { return self.from, nil }
func (self Message) To() *common.Address           { return self.to }
func (self Message) GasPrice() *big.Int            { return self.price }
func (self Message) Gas() *big.Int                 { return self.gas }
func (self Message) Value() *big.Int               { return self.value }
func (self Message) Nonce() uint64                 { return self.nonce }
func (self Message) Data() []byte                  { return self.data }
<commit_msg>tests: check gas limit error<commit_after>package helper

import (
	"errors"
	"math/big"

	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/core"
	"github.com/ethereum/go-ethereum/core/state"
	"github.com/ethereum/go-ethereum/core/vm"
	"github.com/ethereum/go-ethereum/crypto"
)

type Env struct {
	depth        int
	state        *state.StateDB
	skipTransfer bool
	initial      bool
	Gas          *big.Int

	origin common.Address
	//parent   common.Hash
	coinbase common.Address

	number     *big.Int
	time       int64
	difficulty *big.Int
	gasLimit   *big.Int

	logs state.Logs

	vmTest bool
}

func NewEnv(state *state.StateDB) *Env {
	return &Env{
		state: state,
	}
}

func NewEnvFromMap(state *state.StateDB, envValues map[string]string, exeValues map[string]string) *Env {
	env := NewEnv(state)

	env.origin = common.HexToAddress(exeValues["caller"])
	//env.parent = common.Hex2Bytes(envValues["previousHash"])
	env.coinbase = common.HexToAddress(envValues["currentCoinbase"])
	env.number = common.Big(envValues["currentNumber"])
	env.time = common.Big(envValues["currentTimestamp"]).Int64()
	env.difficulty = common.Big(envValues["currentDifficulty"])
	env.gasLimit = common.Big(envValues["currentGasLimit"])
	env.Gas = new(big.Int)

	return env
}

func (self *Env) Origin() common.Address { return self.origin }
func (self *Env) BlockNumber() *big.Int  { return self.number }

//func (self *Env) PrevHash() []byte      { return self.parent }
func (self *Env) Coinbase() common.Address { return self.coinbase }
func (self *Env) Time() int64              { return self.time }
func (self *Env) Difficulty() *big.Int     { return self.difficulty }
func (self *Env) State() *state.StateDB    { return self.state }
func (self *Env) GasLimit() *big.Int       { return self.gasLimit }
func (self *Env) VmType() vm.Type          { return vm.StdVmTy }
func (self *Env) GetHash(n uint64) common.Hash {
	return common.BytesToHash(crypto.Sha3([]byte(big.NewInt(int64(n)).String())))
}
func (self *Env) AddLog(log *state.Log) {
	self.state.AddLog(log)
}
func (self *Env) Depth() int     { return self.depth }
func (self *Env) SetDepth(i int) { self.depth = i }
func (self *Env) Transfer(from, to vm.Account, amount *big.Int) error {
	if self.skipTransfer {
		// ugly hack
		if self.initial {
			self.initial = false
			return nil
		}

		if from.Balance().Cmp(amount) < 0 {
			return errors.New("Insufficient balance in account")
		}

		return nil
	}
	return vm.Transfer(from, to, amount)
}

func (self *Env) vm(addr *common.Address, data []byte, gas, price, value *big.Int) *core.Execution {
	exec := core.NewExecution(self, addr, data, gas, price, value)

	return exec
}

func (self *Env) Call(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
	if self.vmTest && self.depth > 0 {
		caller.ReturnGas(gas, price)

		return nil, nil
	}
	exe := self.vm(&addr, data, gas, price, value)
	ret, err := exe.Call(addr, caller)
	self.Gas = exe.Gas

	return ret, err

}
func (self *Env) CallCode(caller vm.ContextRef, addr common.Address, data []byte, gas, price, value *big.Int) ([]byte, error) {
	if self.vmTest && self.depth > 0 {
		caller.ReturnGas(gas, price)

		return nil, nil
	}

	caddr := caller.Address()
	exe := self.vm(&caddr, data, gas, price, value)
	return exe.Call(addr, caller)
}

func (self *Env) Create(caller vm.ContextRef, data []byte, gas, price, value *big.Int) ([]byte, error, vm.ContextRef) {
	exe := self.vm(nil, data, gas, price, value)
	if self.vmTest {
		caller.ReturnGas(gas, price)

		nonce := self.state.GetNonce(caller.Address())
		obj := self.state.GetOrNewStateObject(crypto.CreateAddress(caller.Address(), nonce))

		return nil, nil, obj
	} else {
		return exe.Create(caller)
	}
}

func RunVm(state *state.StateDB, env, exec map[string]string) ([]byte, state.Logs, *big.Int, error) {
	var (
		to    = common.HexToAddress(exec["address"])
		from  = common.HexToAddress(exec["caller"])
		data  = FromHex(exec["data"])
		gas   = common.Big(exec["gas"])
		price = common.Big(exec["gasPrice"])
		value = common.Big(exec["value"])
	)
	// Reset the pre-compiled contracts for VM tests.
	vm.Precompiled = make(map[string]*vm.PrecompiledAccount)

	caller := state.GetOrNewStateObject(from)

	vmenv := NewEnvFromMap(state, env, exec)
	vmenv.vmTest = true
	vmenv.skipTransfer = true
	vmenv.initial = true
	ret, err := vmenv.Call(caller, to, data, gas, price, value)

	return ret, vmenv.state.Logs(), vmenv.Gas, err
}

func RunState(statedb *state.StateDB, env, tx map[string]string) ([]byte, state.Logs, *big.Int, error) {
	var (
		keyPair, _ = crypto.NewKeyPairFromSec([]byte(common.Hex2Bytes(tx["secretKey"])))
		data       = FromHex(tx["data"])
		gas        = common.Big(tx["gasLimit"])
		price      = common.Big(tx["gasPrice"])
		value      = common.Big(tx["value"])
		nonce      = common.Big(tx["nonce"]).Uint64()
		caddr      = common.HexToAddress(env["currentCoinbase"])
	)

	var to *common.Address
	if len(tx["to"]) > 2 {
		t := common.HexToAddress(tx["to"])
		to = &t
	}
	// Set pre compiled contracts
	vm.Precompiled = vm.PrecompiledContracts()

	snapshot := statedb.Copy()
	coinbase := statedb.GetOrNewStateObject(caddr)
	coinbase.SetGasPool(common.Big(env["currentGasLimit"]))

	message := NewMessage(common.BytesToAddress(keyPair.Address()), to, data, value, gas, price, nonce)
	vmenv := NewEnvFromMap(statedb, env, tx)
	vmenv.origin = common.BytesToAddress(keyPair.Address())
	ret, _, err := core.ApplyMessage(vmenv, message, coinbase)
	if core.IsNonceErr(err) || core.IsInvalidTxErr(err) || state.IsGasLimitErr(err) {
		statedb.Set(snapshot)
	}
	statedb.Update()

	return ret, vmenv.state.Logs(), vmenv.Gas, err
}

type Message struct {
	from              common.Address
	to                *common.Address
	value, gas, price *big.Int
	data              []byte
	nonce             uint64
}

func NewMessage(from common.Address, to *common.Address, data []byte, value, gas, price *big.Int, nonce uint64) Message {
	return Message{from, to, value, gas, price, data, nonce}
}

func (self Message) Hash() []byte                  { return nil }
func (self Message) From() (common.Address, error) { return self.from, nil }
func (self Message) To() *common.Address           { return self.to }
func (self Message) GasPrice() *big.Int            { return self.price }
func (self Message) Gas() *big.Int                 { return self.gas }
func (self Message) Value() *big.Int               { return self.value }
func (self Message) Nonce() uint64                 { return self.nonce }
func (self Message) Data() []byte                  { return self.data }
<|endoftext|>