<commit_before>package server

import (
	"strings"

	"github.com/tidwall/geojson"
)

type BinaryOp byte

const (
	NOOP BinaryOp = iota
	AND
	OR
	tokenAND    = "and"
	tokenOR     = "or"
	tokenNOT    = "not"
	tokenLParen = "("
	tokenRParen = ")"
)

// areaExpression is either an object or operator+children
type areaExpression struct {
	negate bool
	obj geojson.Object
	op BinaryOp
	children children
}

type children []*areaExpression

func (e *areaExpression) String() (res string) {
	if e.obj != nil {
		res = e.obj.String()
	} else {
		var chStrings []string
		for _, c := range e.children {
			chStrings = append(chStrings, c.String())
		}
		switch e.op {
		case NOOP:
			res = "empty operator"
		case AND:
			res = "(" + strings.Join(chStrings, " "+tokenAND+" ") + ")"
		case OR:
			res = "(" + strings.Join(chStrings, " "+tokenOR+" ") + ")"
		default:
			res = "unknown operator"
		}
	}
	if e.negate {
		res = tokenNOT + " " + res
	}
	return
}

// Return boolean value modulo negate field of the expression.
func (e *areaExpression) maybeNegate(val bool) bool {
	if e.negate {
		return !val
	}
	return val
}

// Methods for testing an areaExpression against the spatial object
func (e *areaExpression) rawIntersects(o geojson.Object) bool {
	if e.obj != nil {
		return e.obj.Intersects(o)
	}
	switch e.op {
	case AND:
		for _, c := range e.children {
			if !c.Intersects(o) {
				return false
			}
		}
		return true
	case OR:
		for _, c := range e.children {
			if c.Intersects(o) {
				return true
			}
		}
		return false
	}
	return false
}

func (e *areaExpression) rawContains(o geojson.Object) bool {
	if e.obj != nil {
		return e.obj.Contains(o)
	}
	switch e.op {
	case AND:
		for _, c:= range e.children {
			if !c.Contains(o) {
				return false
			}
		}
		return true
	case OR:
		for _, c:= range e.children {
			if c.Contains(o) {
				return true
			}
		}
		return false
	}
	return false
}

func (e *areaExpression) rawWithin(o geojson.Object) bool {
	if e.obj != nil {
		return e.obj.Within(o)
	}
	switch e.op {
	case AND:
		for _, c:= range e.children {
			if !c.Within(o) {
				return false
			}
		}
		return true
	case OR:
		for _, c:= range e.children {
			if c.Within(o) {
				return true
			}
		}
		return false
	}
	return false
}

func (e *areaExpression) Intersects(o geojson.Object) bool {
	return e.maybeNegate(e.rawIntersects(o))
}

func (e *areaExpression) Contains(o geojson.Object) bool {
	return e.maybeNegate(e.rawContains(o))
}

func (e *areaExpression) Within(o geojson.Object) bool {
	return e.maybeNegate(e.rawWithin(o))
}

// Methods for testing an areaExpression against another areaExpression
func (e *areaExpression) rawIntersectsExpr(oe *areaExpression) bool {
	if oe.negate {
		e2 := &areaExpression{negate:!e.negate, obj:e.obj, op: e.op, children:e.children}
		oe2 := &areaExpression{negate:false, obj:oe.obj, op:oe.op, children:oe.children}
		return e2.rawIntersectsExpr(oe2)
	}
	if oe.obj != nil {
		return e.Intersects(oe.obj)
	}
	switch oe.op {
	case AND:
		for _, c := range oe.children {
			if !e.rawIntersectsExpr(c) {
				return false
			}
		}
		return true
	case OR:
		for _, c := range oe.children {
			if e.rawIntersectsExpr(c) {
				return true
			}
		}
		return false
	}
	return false
}

func (e *areaExpression) rawWithinExpr(oe *areaExpression) bool {
	if oe.negate {
		e2 := &areaExpression{negate:!e.negate, obj:e.obj, op: e.op, children:e.children}
		oe2 := &areaExpression{negate:false, obj:oe.obj, op:oe.op, children:oe.children}
		return e2.rawWithinExpr(oe2)
	}
	if oe.obj != nil {
		return e.Within(oe.obj)
	}
	switch oe.op {
	case AND:
		for _, c:= range oe.children {
			if !e.rawWithinExpr(c) {
				return false
			}
		}
		return true
	case OR:
		for _, c:= range oe.children {
			if e.rawWithinExpr(c) {
				return true
			}
		}
		return false
	}
	return false
}

func (e *areaExpression) rawContainsExpr(oe *areaExpression) bool {
	if oe.negate {
		e2 := &areaExpression{negate:!e.negate, obj:e.obj, op: e.op, children:e.children}
		oe2 := &areaExpression{negate:false, obj:oe.obj, op:oe.op, children:oe.children}
		return e2.rawContainsExpr(oe2)
	}
	if oe.obj != nil {
		return e.Contains(oe.obj)
	}
	switch oe.op {
	case AND:
		for _, c:= range oe.children {
			if !e.rawContainsExpr(c) {
				return false
			}
		}
		return true
	case OR:
		for _, c:= range oe.children {
			if e.rawContainsExpr(c) {
				return true
			}
		}
		return false
	}
	return false
}

func (e *areaExpression) IntersectsExpr(oe *areaExpression) bool {
	return e.maybeNegate(e.rawIntersectsExpr(oe))
}

func (e *areaExpression) WithinExpr(oe *areaExpression) bool {
	return e.maybeNegate(e.rawWithinExpr(oe))
}

func (e *areaExpression) ContainsExpr(oe *areaExpression) bool {
	return e.maybeNegate(e.rawContainsExpr(oe))
}
<commit_msg>Fix one case in expression/expression tests<commit_after>package server

import (
	"strings"

	"github.com/tidwall/geojson"
)

type BinaryOp byte

const (
	NOOP BinaryOp = iota
	AND
	OR
	tokenAND    = "and"
	tokenOR     = "or"
	tokenNOT    = "not"
	tokenLParen = "("
	tokenRParen = ")"
)

// areaExpression is either an object or operator+children
type areaExpression struct {
	negate bool
	obj geojson.Object
	op BinaryOp
	children children
}

type children []*areaExpression

func (e *areaExpression) String() (res string) {
	if e.obj != nil {
		res = e.obj.String()
	} else {
		var chStrings []string
		for _, c := range e.children {
			chStrings = append(chStrings, c.String())
		}
		switch e.op {
		case NOOP:
			res = "empty operator"
		case AND:
			res = "(" + strings.Join(chStrings, " "+tokenAND+" ") + ")"
		case OR:
			res = "(" + strings.Join(chStrings, " "+tokenOR+" ") + ")"
		default:
			res = "unknown operator"
		}
	}
	if e.negate {
		res = tokenNOT + " " + res
	}
	return
}

// Return boolean value modulo negate field of the expression.
func (e *areaExpression) maybeNegate(val bool) bool {
	if e.negate {
		return !val
	}
	return val
}

// Methods for testing an areaExpression against the spatial object
func (e *areaExpression) rawIntersects(o geojson.Object) bool {
	if e.obj != nil {
		return e.obj.Intersects(o)
	}
	switch e.op {
	case AND:
		for _, c := range e.children {
			if !c.Intersects(o) {
				return false
			}
		}
		return true
	case OR:
		for _, c := range e.children {
			if c.Intersects(o) {
				return true
			}
		}
		return false
	}
	return false
}

func (e *areaExpression) rawContains(o geojson.Object) bool {
	if e.obj != nil {
		return e.obj.Contains(o)
	}
	switch e.op {
	case AND:
		for _, c:= range e.children {
			if !c.Contains(o) {
				return false
			}
		}
		return true
	case OR:
		for _, c:= range e.children {
			if c.Contains(o) {
				return true
			}
		}
		return false
	}
	return false
}

func (e *areaExpression) rawWithin(o geojson.Object) bool {
	if e.obj != nil {
		return e.obj.Within(o)
	}
	switch e.op {
	case AND:
		for _, c:= range e.children {
			if !c.Within(o) {
				return false
			}
		}
		return true
	case OR:
		for _, c:= range e.children {
			if c.Within(o) {
				return true
			}
		}
		return false
	}
	return false
}

func (e *areaExpression) Intersects(o geojson.Object) bool {
	return e.maybeNegate(e.rawIntersects(o))
}

func (e *areaExpression) Contains(o geojson.Object) bool {
	return e.maybeNegate(e.rawContains(o))
}

func (e *areaExpression) Within(o geojson.Object) bool {
	return e.maybeNegate(e.rawWithin(o))
}

// Methods for testing an areaExpression against another areaExpression
func (e *areaExpression) rawIntersectsExpr(oe *areaExpression) bool {
	if oe.negate {
		e2 := &areaExpression{negate:!e.negate, obj:e.obj, op: e.op, children:e.children}
		oe2 := &areaExpression{negate:false, obj:oe.obj, op:oe.op, children:oe.children}
		return e2.IntersectsExpr(oe2)
	}
	if oe.obj != nil {
		return e.rawIntersects(oe.obj)
	}
	switch oe.op {
	case AND:
		for _, c := range oe.children {
			if !e.rawIntersectsExpr(c) {
				return false
			}
		}
		return true
	case OR:
		for _, c := range oe.children {
			if e.rawIntersectsExpr(c) {
				return true
			}
		}
		return false
	}
	return false
}

func (e *areaExpression) rawWithinExpr(oe *areaExpression) bool {
	if oe.negate {
		e2 := &areaExpression{negate:!e.negate, obj:e.obj, op: e.op, children:e.children}
		oe2 := &areaExpression{negate:false, obj:oe.obj, op:oe.op, children:oe.children}
		return e2.WithinExpr(oe2)
	}
	if oe.obj != nil {
		return e.rawWithin(oe.obj)
	}
	switch oe.op {
	case AND:
		for _, c:= range oe.children {
			if !e.rawWithinExpr(c) {
				return false
			}
		}
		return true
	case OR:
		for _, c:= range oe.children {
			if e.rawWithinExpr(c) {
				return true
			}
		}
		return false
	}
	return false
}

func (e *areaExpression) rawContainsExpr(oe *areaExpression) bool {
	if oe.negate {
		e2 := &areaExpression{negate:!e.negate, obj:e.obj, op: e.op, children:e.children}
		oe2 := &areaExpression{negate:false, obj:oe.obj, op:oe.op, children:oe.children}
		return e2.ContainsExpr(oe2)
	}
	if oe.obj != nil {
		return e.rawContains(oe.obj)
	}
	switch oe.op {
	case AND:
		for _, c:= range oe.children {
			if !e.rawContainsExpr(c) {
				return false
			}
		}
		return true
	case OR:
		for _, c:= range oe.children {
			if e.rawContainsExpr(c) {
				return true
			}
		}
		return false
	}
	return false
}

func (e *areaExpression) IntersectsExpr(oe *areaExpression) bool {
	return e.maybeNegate(e.rawIntersectsExpr(oe))
}

func (e *areaExpression) WithinExpr(oe *areaExpression) bool {
	return e.maybeNegate(e.rawWithinExpr(oe))
}

func (e *areaExpression) ContainsExpr(oe *areaExpression) bool {
	return e.maybeNegate(e.rawContainsExpr(oe))
}
<|endoftext|>


<commit_before>// Copyright 2014 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.

package storetesting

import (
	"encoding/json"
	"io"
	"net/http"
	"net/http/httptest"
	"reflect"
	"strings"

	jc "github.com/juju/testing/checkers"
	gc "launchpad.net/gocheck"
)

// AssertJSONCall asserts that when the given handler is called with
// the given method, URL, and body, the result has the expected
// status code and body.
func AssertJSONCall(
	c *gc.C,
	handler http.Handler,
	method string,
	urlStr string,
	body string,
	expectCode int,
	expectBody interface{},
) {
	rec := DoRequest(c, handler, method, urlStr, body)
	c.Assert(rec.Code, gc.Equals, expectCode, gc.Commentf("body: %s", rec.Body.Bytes()))
	if expectBody == nil {
		c.Assert(rec.Body.Bytes(), gc.HasLen, 0)
		return
	}
	resp := reflect.New(reflect.TypeOf(expectBody))
	err := json.Unmarshal(rec.Body.Bytes(), resp.Interface())
	c.Assert(err, gc.IsNil)
	c.Assert(resp.Elem().Interface(), jc.DeepEquals, expectBody)
}

// DoRequest invokes a request on the given handler with the given
// method, URL and body.
func DoRequest(c *gc.C, handler http.Handler, method string, urlStr string, body string) *httptest.ResponseRecorder {
	var r io.Reader
	if body != "" {
		r = strings.NewReader(body)
	}
	req, err := http.NewRequest(method, urlStr, r)
	c.Assert(err, gc.IsNil)
	rec := httptest.NewRecorder()
	handler.ServeHTTP(rec, req)
	return rec
}
<commit_msg>internal/storetesting: more stringent AssertJSONCall test<commit_after>// Copyright 2014 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.

package storetesting

import (
	"encoding/json"
	"io"
	"net/http"
	"net/http/httptest"
	"strings"

	jc "github.com/juju/testing/checkers"
	gc "launchpad.net/gocheck"
)

// AssertJSONCall asserts that when the given handler is called with
// the given method, URL, and body, the result has the expected
// status code and body.
func AssertJSONCall(
	c *gc.C,
	handler http.Handler,
	method string,
	urlStr string,
	body string,
	expectCode int,
	expectBody interface{},
) {
	rec := DoRequest(c, handler, method, urlStr, body)
	c.Assert(rec.Code, gc.Equals, expectCode, gc.Commentf("body: %s", rec.Body.Bytes()))
	if expectBody == nil {
		c.Assert(rec.Body.Bytes(), gc.HasLen, 0)
		return
	}
	// Rather than unmarshaling into something of the expected
	// body type, we reform the expected body in JSON and
	// back to interface{}, so we can check the whole content.
	// Otherwise we lose information when unmarshaling.
	expectBodyBytes, err := json.Marshal(expectBody)
	c.Assert(err, gc.IsNil)
	var expectBodyVal interface{}
	err = json.Unmarshal(expectBodyBytes, &expectBodyVal)
	c.Assert(err, gc.IsNil)

	var gotBodyVal interface{}
	err = json.Unmarshal(rec.Body.Bytes(), &gotBodyVal)
	c.Assert(err, gc.IsNil)

	c.Assert(gotBodyVal, jc.DeepEquals, expectBodyVal)
}

// DoRequest invokes a request on the given handler with the given
// method, URL and body.
func DoRequest(c *gc.C, handler http.Handler, method string, urlStr string, body string) *httptest.ResponseRecorder {
	var r io.Reader
	if body != "" {
		r = strings.NewReader(body)
	}
	req, err := http.NewRequest(method, urlStr, r)
	c.Assert(err, gc.IsNil)
	rec := httptest.NewRecorder()
	handler.ServeHTTP(rec, req)
	return rec
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"

	"github.com/pivotal-cf/cf-rabbit-release/src/rabbitmq-cluster-migration-tool/configuration"
)

func main() {
	migrator := configuration.NewMigrator("")
	err := migrator.MigrateConfiguration()

	if err != nil {
		fmt.Printf("Finished with error: %s", err)
	}

}
<commit_msg>Revert "allow the migration tool to run"<commit_after>package main

func main() {

}
<|endoftext|>


<commit_before>package main

func main()              {}
func sink(v interface{}) {}

func link(from interface{}, into interface{}) {}

func newSource() interface{} {
	return nil
}
<commit_msg>Update main.go<commit_after>package main

func main()              {}
func sink(id int, v interface{}) {}

func link(from interface{}, into interface{}) {}

func newSource(id int) interface{} {
	return nil
}
<|endoftext|>


<commit_before>package backend

import (
	"fmt"
	"math/rand"
)

type Random struct {
	Items []Item
}

func (r Random) Name() string {
	return "Backend-Random"
}

func (r *Random) Open() {
	r.Items = make([]Item, 0)

	seeds := []map[string]string{
		map[string]string{"type": "node", "group_id": "cpu/usage_rate", "units": "cpu", "issue": "42"},
		map[string]string{"type": "node", "group_id": "memory/usage_rate", "units": "byte"},
		map[string]string{"type": "node", "group_id": "cpu/usage_rate", "units": "cpu", "issue": "42"},
		map[string]string{"type": "node", "group_id": "memory/usage_rate", "units": "byte"},
		map[string]string{"type": "node", "group_id": "cpu/limit", "units": "cpu", "issue": "442"},
		map[string]string{"type": "node", "group_id": "memory/limit", "units": "byte", "issue": "442"},
		map[string]string{"type": "node", "group_id": "filesystem/usage_rate", "units": "byte"},
	}

	for i := 0; i < 120; i++ {
		seed := seeds[rand.Intn(len(seeds))]
		tags := map[string]string{
			"type":     seed["type"],
			"group_id": seed["group_id"],
			"units":    seed["units"],
			"issue":    seed["issue"],
			"hostname": fmt.Sprintf("example.%03d.com", i/4),
		}
		r.Items = append(r.Items, Item{
			Id:   fmt.Sprintf("hello_kitty_%3d", i),
			Type: "gauge",
			Tags: tags,
		})
	}
}

func (r Random) GetItemList(tags map[string]string) []Item {
	res := r.Items

	if len(tags) > 0 {
		for key, value := range tags {
			res = FilterItems(res, func(i Item) bool { return i.Tags[key] == value })
		}
	}

	return res
}

func (r Random) GetRawData(id string, end int64, start int64, limit int64, order string) []DataItem {
	res := make([]DataItem, 0)

	delta := int64(5 * 60 * 1000)

	for i := limit; i > 0; i-- {
		res = append(res, DataItem{
			Timestamp: end - i*delta,
			Value:     float64(50 + rand.Intn(50)),
		})
	}

	return res
}

func (r Random) GetStatData(id string, end int64, start int64, limit int64, order string, bucketDuration int64) []StatItem {
	res := make([]StatItem, 0)

	delta := int64(5 * 60 * 1000)

	for i := limit; i > 0; i-- {
		value := float64(50 + rand.Intn(50))
		res = append(res, StatItem{
			Start:   end - i*delta,
			End:     end- (i - 1)*delta,
			Empty:   false,
			Samples: 1,
			Min:     value,
			Max:     value,
			Avg:     value,
			Median:  value,
			Sum:     value,
		})
	}

	return res
}

func (r Random) PostRawData(id string, t int64, v float64) bool {
	return false
}

func (r Random) PutTags(id string, tags map[string]string) bool {
	return false
}
<commit_msg>add a backend name to the status message<commit_after>package backend

import (
	"fmt"
	"math/rand"
)

type Random struct {
	Items []Item
}

func (r Random) Name() string {
	return "Backend-Random"
}

func (r *Random) Open() {
	r.Items = make([]Item, 0)

	seeds := []map[string]string{
		map[string]string{"type": "node", "group_id": "cpu/usage_rate", "units": "cpu", "issue": "42"},
		map[string]string{"type": "node", "group_id": "memory/usage_rate", "units": "byte"},
		map[string]string{"type": "node", "group_id": "cpu/usage_rate", "units": "cpu", "issue": "42"},
		map[string]string{"type": "node", "group_id": "memory/usage_rate", "units": "byte"},
		map[string]string{"type": "node", "group_id": "cpu/limit", "units": "cpu", "issue": "442"},
		map[string]string{"type": "node", "group_id": "memory/limit", "units": "byte", "issue": "442"},
		map[string]string{"type": "node", "group_id": "filesystem/usage_rate", "units": "byte"},
	}

	for i := 0; i < 120; i++ {
		seed := seeds[rand.Intn(len(seeds))]
		tags := map[string]string{
			"type":     seed["type"],
			"group_id": seed["group_id"],
			"units":    seed["units"],
			"issue":    seed["issue"],
			"hostname": fmt.Sprintf("example.%03d.com", i/4),
		}
		r.Items = append(r.Items, Item{
			Id:   fmt.Sprintf("hello_kitty_%3d", i),
			Type: "gauge",
			Tags: tags,
		})
	}
}

func (r Random) GetItemList(tags map[string]string) []Item {
	res := r.Items

	if len(tags) > 0 {
		for key, value := range tags {
			res = FilterItems(res, func(i Item) bool { return i.Tags[key] == value })
		}
	}

	return res
}

func (r Random) GetRawData(id string, end int64, start int64, limit int64, order string) []DataItem {
	res := make([]DataItem, 0)

	delta := int64(5 * 60 * 1000)

	for i := limit; i > 0; i-- {
		res = append(res, DataItem{
			Timestamp: end - i*delta,
			Value:     float64(50 + rand.Intn(50)),
		})
	}

	return res
}

func (r Random) GetStatData(id string, end int64, start int64, limit int64, order string, bucketDuration int64) []StatItem {
	res := make([]StatItem, 0)

	delta := int64(5 * 60 * 1000)

	for i := limit; i > 0; i-- {
		value := float64(50 + rand.Intn(50))
		res = append(res, StatItem{
			Start:   end - i*delta,
			End:     end - (i-1)*delta,
			Empty:   false,
			Samples: 1,
			Min:     value,
			Max:     value,
			Avg:     value,
			Median:  value,
			Sum:     value,
		})
	}

	return res
}

func (r Random) PostRawData(id string, t int64, v float64) bool {
	return false
}

func (r Random) PutTags(id string, tags map[string]string) bool {
	return false
}
<|endoftext|>


<commit_before>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Contributor:
// - Aaron Meihm ameihm@mozilla.com [:alm]

// The agentcontext package provides functionality to obtain information
// about the system a given agent or loader is running on. This includes
// information unrelated to MIG itself, such as the hostname of the system,
// IP addresses, and so on.
package agentcontext /* import "mig.ninja/mig/mig-agent/agentcontext" */

import (
	"fmt"
	"github.com/kardianos/osext"
	"io/ioutil"
	mrand "math/rand"
	"mig.ninja/mig"
	"os"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"time"
)

// Information from the system the agent is running on
type AgentContext struct {
	Hostname     string   // Hostname
	BinPath      string   // Path to invoked binary
	RunDir       string   // Agent runtime directory
	OS           string   // Operating System
	OSIdent      string   // OS release identifier
	Init         string   // OS Init
	Architecture string   // System architecture
	Addresses    []string // IP addresses
	PublicIP     string   // Systems public IP from perspective of API
	UID          string   // Agent ID
	QueueLoc     string   // Agent queue location

	AWS AWSContext // AWS specific information
}

func (ctx *AgentContext) IsZero() bool {
	// If we don't have an OS treat it as unset
	if ctx.OS == "" {
		return true
	}
	return false
}

// Check of any values in the AgentContext differ from those in comp
func (ctx *AgentContext) Differs(comp AgentContext) bool {
	if ctx.Hostname != comp.Hostname ||
		ctx.BinPath != comp.BinPath ||
		ctx.RunDir != comp.RunDir ||
		ctx.OS != comp.OS ||
		ctx.OSIdent != comp.OSIdent ||
		ctx.Init != comp.Init ||
		ctx.Architecture != comp.Architecture ||
		ctx.PublicIP != comp.PublicIP ||
		ctx.AWS.InstanceID != comp.AWS.InstanceID ||
		ctx.AWS.LocalIPV4 != comp.AWS.LocalIPV4 ||
		ctx.AWS.AMIID != comp.AWS.AMIID ||
		ctx.AWS.InstanceType != comp.AWS.InstanceType {
		return true
	}
	if ctx.Addresses == nil && comp.Addresses == nil {
		return false
	}
	if ctx.Addresses == nil || comp.Addresses == nil {
		return true
	}
	if len(ctx.Addresses) != len(comp.Addresses) {
		return true
	}
	for i := range ctx.Addresses {
		if ctx.Addresses[i] != comp.Addresses[i] {
			return true
		}
	}
	return false
}

func (ctx *AgentContext) ToAgent() (ret mig.Agent) {
	ret.Name = ctx.Hostname
	ret.PID = os.Getpid()
	ret.Env.OS = ctx.OS
	ret.Env.Arch = ctx.Architecture
	ret.Env.Ident = ctx.OSIdent
	ret.Env.Init = ctx.Init
	ret.Env.Addresses = ctx.Addresses
	ret.Env.PublicIP = ctx.PublicIP
	ret.Env.AWS.InstanceID = ctx.AWS.InstanceID
	ret.Env.AWS.LocalIPV4 = ctx.AWS.LocalIPV4
	ret.Env.AWS.AMIID = ctx.AWS.AMIID
	ret.Env.AWS.InstanceType = ctx.AWS.InstanceType
	return
}

// Passed to NewAgentContext() to inform environment discovery
type AgentContextHints struct {
	APIUrl           string   // MIG API URL
	Proxies          []string // Proxies avialable for use in discovery
	DiscoverPublicIP bool     // Attempt to discover public IP
	DiscoverAWSMeta  bool     // Attempt to discover AWS metadata
}

// Information used for agents running in AWS environments
type AWSContext struct {
	InstanceID   string // AWS instance ID
	LocalIPV4    string // AWS Local IPV4 address
	AMIID        string // AWS AMI ID
	InstanceType string // AWS instance type
}

var logChan chan mig.Log

func NewAgentContext(lch chan mig.Log, hints AgentContextHints) (ret AgentContext, err error) {
	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("NewAgentContext() -> %v", e)
		}
	}()

	logChan = lch

	ret.BinPath, err = osext.Executable()
	if err != nil {
		panic(err)
	}

	ret, err = findHostname(ret)
	if err != nil {
		panic(err)
	}

	ret.OS = runtime.GOOS
	ret.Architecture = runtime.GOARCH
	ret.RunDir = GetRunDir()
	ret, err = findOSInfo(ret)
	if err != nil {
		panic(err)
	}
	ret, err = findLocalIPs(ret)
	if err != nil {
		panic(err)
	}
	ret, err = initAgentID(ret)
	if err != nil {
		panic(err)
	}

	// build the agent message queue location
	ret.QueueLoc = fmt.Sprintf("%s.%s", ret.OS, ret.UID)

	if hints.DiscoverPublicIP {
		ret, err = findPublicIP(ret, hints)
		if err != nil {
			panic(err)
		}
	}

	if hints.DiscoverAWSMeta {
		ret, err = addAWSMetadata(ret)
		if err != nil {
			panic(err)
		}
	}

	return
}

// initAgentID will retrieve an ID from disk, or request one if missing
func initAgentID(orig_ctx AgentContext) (ctx AgentContext, err error) {
	ctx = orig_ctx
	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("initAgentID() -> %v", e)
		}
		logChan <- mig.Log{Desc: "leaving initAgentID()"}.Debug()
	}()
	os.Chmod(ctx.RunDir, 0755)
	idFile := ctx.RunDir + ".migagtid"
	id, err := ioutil.ReadFile(idFile)
	if err != nil {
		logChan <- mig.Log{Desc: fmt.Sprintf("unable to read agent id from '%s': %v", idFile, err)}.Debug()
		// ID file doesn't exist, create it
		id, err = createIDFile(ctx)
		if err != nil {
			panic(err)
		}
	}
	// Make sure the obtained queue location matches the format that we expect, if
	// it doesn't create a new one
	mtch, err := regexp.Match("^[0-9a-zA-Z]{80,}$", id)
	if err != nil {
		panic(err)
	}
	if !mtch {
		logChan <- mig.Log{Desc: "invalid or deprecated agent ID, recreating"}.Info()
		id, err = createIDFile(ctx)
		if err != nil {
			panic(err)
		}
	}
	ctx.UID = fmt.Sprintf("%s", id)
	os.Chmod(idFile, 0400)
	return
}

// createIDFile will generate a new ID for this agent and store it on disk
// the location depends on the operating system
func createIDFile(ctx AgentContext) (id []byte, err error) {
	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("createIDFile() -> %v", e)
		}
	}()
	// generate an ID with 512 bits of entropy
	r := mrand.New(mrand.NewSource(time.Now().UnixNano()))
	var sid string
	for i := 0; i < 8; i++ {
		sid += strconv.FormatUint(uint64(r.Int63()), 36)
	}

	// check that the storage DIR exist, and that it's a dir
	tdir, err := os.Open(ctx.RunDir)
	defer tdir.Close()
	if err != nil {
		// dir doesn't exist, create it
		logChan <- mig.Log{Desc: fmt.Sprintf("agent rundir is missing from '%s'. creating it", ctx.RunDir)}.Debug()
		err = os.MkdirAll(ctx.RunDir, 0755)
		if err != nil {
			panic(err)
		}
	} else {
		// open worked, verify that it's a dir
		tdirMode, err := tdir.Stat()
		if err != nil {
			panic(err)
		}
		if !tdirMode.Mode().IsDir() {
			logChan <- mig.Log{Desc: fmt.Sprintf("'%s' is not a directory. removing it", ctx.RunDir)}.Debug()
			// not a valid dir. destroy whatever it is, and recreate
			err = os.Remove(ctx.RunDir)
			if err != nil {
				panic(err)
			}
			err = os.MkdirAll(ctx.RunDir, 0755)
			if err != nil {
				panic(err)
			}
		}
	}

	idFile := ctx.RunDir + ".migagtid"

	// something exists at the location of the id file, just plain remove it
	_ = os.Remove(idFile)

	// write the ID file
	err = ioutil.WriteFile(idFile, []byte(sid), 0400)
	if err != nil {
		panic(err)
	}
	// read ID from disk
	id, err = ioutil.ReadFile(idFile)
	if err != nil {
		panic(err)
	}
	logChan <- mig.Log{Desc: fmt.Sprintf("agent id created in '%s'", idFile)}.Debug()
	return
}

// cleanString removes spaces, quotes and newlines
func cleanString(str string) string {
	if len(str) < 1 {
		return str
	}
	if str[len(str)-1] == '\n' {
		str = str[0 : len(str)-1]
	}
	// remove heading whitespaces and quotes
	for {
		if len(str) < 2 {
			break
		}
		switch str[0] {
		case ' ', '"', '\'':
			str = str[1:len(str)]
		default:
			goto trailing
		}
	}
trailing:
	// remove trailing whitespaces, quotes and linebreaks
	for {
		if len(str) < 2 {
			break
		}
		switch str[len(str)-1] {
		case ' ', '"', '\'', '\r', '\n':
			str = str[0 : len(str)-1]
		default:
			goto exit
		}
	}
exit:
	// remove in-string linebreaks
	str = strings.Replace(str, "\n", " ", -1)
	str = strings.Replace(str, "\r", " ", -1)
	return str
}
<commit_msg>[minor] include QueueLoc in agentcontext ToAgent conversion<commit_after>// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Contributor:
// - Aaron Meihm ameihm@mozilla.com [:alm]

// The agentcontext package provides functionality to obtain information
// about the system a given agent or loader is running on. This includes
// information unrelated to MIG itself, such as the hostname of the system,
// IP addresses, and so on.
package agentcontext /* import "mig.ninja/mig/mig-agent/agentcontext" */

import (
	"fmt"
	"github.com/kardianos/osext"
	"io/ioutil"
	mrand "math/rand"
	"mig.ninja/mig"
	"os"
	"regexp"
	"runtime"
	"strconv"
	"strings"
	"time"
)

// Information from the system the agent is running on
type AgentContext struct {
	Hostname     string   // Hostname
	BinPath      string   // Path to invoked binary
	RunDir       string   // Agent runtime directory
	OS           string   // Operating System
	OSIdent      string   // OS release identifier
	Init         string   // OS Init
	Architecture string   // System architecture
	Addresses    []string // IP addresses
	PublicIP     string   // Systems public IP from perspective of API
	UID          string   // Agent ID
	QueueLoc     string   // Agent queue location

	AWS AWSContext // AWS specific information
}

func (ctx *AgentContext) IsZero() bool {
	// If we don't have an OS treat it as unset
	if ctx.OS == "" {
		return true
	}
	return false
}

// Check of any values in the AgentContext differ from those in comp
func (ctx *AgentContext) Differs(comp AgentContext) bool {
	if ctx.Hostname != comp.Hostname ||
		ctx.BinPath != comp.BinPath ||
		ctx.RunDir != comp.RunDir ||
		ctx.OS != comp.OS ||
		ctx.OSIdent != comp.OSIdent ||
		ctx.Init != comp.Init ||
		ctx.Architecture != comp.Architecture ||
		ctx.PublicIP != comp.PublicIP ||
		ctx.AWS.InstanceID != comp.AWS.InstanceID ||
		ctx.AWS.LocalIPV4 != comp.AWS.LocalIPV4 ||
		ctx.AWS.AMIID != comp.AWS.AMIID ||
		ctx.AWS.InstanceType != comp.AWS.InstanceType {
		return true
	}
	if ctx.Addresses == nil && comp.Addresses == nil {
		return false
	}
	if ctx.Addresses == nil || comp.Addresses == nil {
		return true
	}
	if len(ctx.Addresses) != len(comp.Addresses) {
		return true
	}
	for i := range ctx.Addresses {
		if ctx.Addresses[i] != comp.Addresses[i] {
			return true
		}
	}
	return false
}

func (ctx *AgentContext) ToAgent() (ret mig.Agent) {
	ret.Name = ctx.Hostname
	ret.QueueLoc = ctx.QueueLoc
	ret.PID = os.Getpid()
	ret.Env.OS = ctx.OS
	ret.Env.Arch = ctx.Architecture
	ret.Env.Ident = ctx.OSIdent
	ret.Env.Init = ctx.Init
	ret.Env.Addresses = ctx.Addresses
	ret.Env.PublicIP = ctx.PublicIP
	ret.Env.AWS.InstanceID = ctx.AWS.InstanceID
	ret.Env.AWS.LocalIPV4 = ctx.AWS.LocalIPV4
	ret.Env.AWS.AMIID = ctx.AWS.AMIID
	ret.Env.AWS.InstanceType = ctx.AWS.InstanceType
	return
}

// Passed to NewAgentContext() to inform environment discovery
type AgentContextHints struct {
	APIUrl           string   // MIG API URL
	Proxies          []string // Proxies avialable for use in discovery
	DiscoverPublicIP bool     // Attempt to discover public IP
	DiscoverAWSMeta  bool     // Attempt to discover AWS metadata
}

// Information used for agents running in AWS environments
type AWSContext struct {
	InstanceID   string // AWS instance ID
	LocalIPV4    string // AWS Local IPV4 address
	AMIID        string // AWS AMI ID
	InstanceType string // AWS instance type
}

var logChan chan mig.Log

func NewAgentContext(lch chan mig.Log, hints AgentContextHints) (ret AgentContext, err error) {
	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("NewAgentContext() -> %v", e)
		}
	}()

	logChan = lch

	ret.BinPath, err = osext.Executable()
	if err != nil {
		panic(err)
	}

	ret, err = findHostname(ret)
	if err != nil {
		panic(err)
	}

	ret.OS = runtime.GOOS
	ret.Architecture = runtime.GOARCH
	ret.RunDir = GetRunDir()
	ret, err = findOSInfo(ret)
	if err != nil {
		panic(err)
	}
	ret, err = findLocalIPs(ret)
	if err != nil {
		panic(err)
	}
	ret, err = initAgentID(ret)
	if err != nil {
		panic(err)
	}

	// build the agent message queue location
	ret.QueueLoc = fmt.Sprintf("%s.%s", ret.OS, ret.UID)

	if hints.DiscoverPublicIP {
		ret, err = findPublicIP(ret, hints)
		if err != nil {
			panic(err)
		}
	}

	if hints.DiscoverAWSMeta {
		ret, err = addAWSMetadata(ret)
		if err != nil {
			panic(err)
		}
	}

	return
}

// initAgentID will retrieve an ID from disk, or request one if missing
func initAgentID(orig_ctx AgentContext) (ctx AgentContext, err error) {
	ctx = orig_ctx
	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("initAgentID() -> %v", e)
		}
		logChan <- mig.Log{Desc: "leaving initAgentID()"}.Debug()
	}()
	os.Chmod(ctx.RunDir, 0755)
	idFile := ctx.RunDir + ".migagtid"
	id, err := ioutil.ReadFile(idFile)
	if err != nil {
		logChan <- mig.Log{Desc: fmt.Sprintf("unable to read agent id from '%s': %v", idFile, err)}.Debug()
		// ID file doesn't exist, create it
		id, err = createIDFile(ctx)
		if err != nil {
			panic(err)
		}
	}
	// Make sure the obtained queue location matches the format that we expect, if
	// it doesn't create a new one
	mtch, err := regexp.Match("^[0-9a-zA-Z]{80,}$", id)
	if err != nil {
		panic(err)
	}
	if !mtch {
		logChan <- mig.Log{Desc: "invalid or deprecated agent ID, recreating"}.Info()
		id, err = createIDFile(ctx)
		if err != nil {
			panic(err)
		}
	}
	ctx.UID = fmt.Sprintf("%s", id)
	os.Chmod(idFile, 0400)
	return
}

// createIDFile will generate a new ID for this agent and store it on disk
// the location depends on the operating system
func createIDFile(ctx AgentContext) (id []byte, err error) {
	defer func() {
		if e := recover(); e != nil {
			err = fmt.Errorf("createIDFile() -> %v", e)
		}
	}()
	// generate an ID with 512 bits of entropy
	r := mrand.New(mrand.NewSource(time.Now().UnixNano()))
	var sid string
	for i := 0; i < 8; i++ {
		sid += strconv.FormatUint(uint64(r.Int63()), 36)
	}

	// check that the storage DIR exist, and that it's a dir
	tdir, err := os.Open(ctx.RunDir)
	defer tdir.Close()
	if err != nil {
		// dir doesn't exist, create it
		logChan <- mig.Log{Desc: fmt.Sprintf("agent rundir is missing from '%s'. creating it", ctx.RunDir)}.Debug()
		err = os.MkdirAll(ctx.RunDir, 0755)
		if err != nil {
			panic(err)
		}
	} else {
		// open worked, verify that it's a dir
		tdirMode, err := tdir.Stat()
		if err != nil {
			panic(err)
		}
		if !tdirMode.Mode().IsDir() {
			logChan <- mig.Log{Desc: fmt.Sprintf("'%s' is not a directory. removing it", ctx.RunDir)}.Debug()
			// not a valid dir. destroy whatever it is, and recreate
			err = os.Remove(ctx.RunDir)
			if err != nil {
				panic(err)
			}
			err = os.MkdirAll(ctx.RunDir, 0755)
			if err != nil {
				panic(err)
			}
		}
	}

	idFile := ctx.RunDir + ".migagtid"

	// something exists at the location of the id file, just plain remove it
	_ = os.Remove(idFile)

	// write the ID file
	err = ioutil.WriteFile(idFile, []byte(sid), 0400)
	if err != nil {
		panic(err)
	}
	// read ID from disk
	id, err = ioutil.ReadFile(idFile)
	if err != nil {
		panic(err)
	}
	logChan <- mig.Log{Desc: fmt.Sprintf("agent id created in '%s'", idFile)}.Debug()
	return
}

// cleanString removes spaces, quotes and newlines
func cleanString(str string) string {
	if len(str) < 1 {
		return str
	}
	if str[len(str)-1] == '\n' {
		str = str[0 : len(str)-1]
	}
	// remove heading whitespaces and quotes
	for {
		if len(str) < 2 {
			break
		}
		switch str[0] {
		case ' ', '"', '\'':
			str = str[1:len(str)]
		default:
			goto trailing
		}
	}
trailing:
	// remove trailing whitespaces, quotes and linebreaks
	for {
		if len(str) < 2 {
			break
		}
		switch str[len(str)-1] {
		case ' ', '"', '\'', '\r', '\n':
			str = str[0 : len(str)-1]
		default:
			goto exit
		}
	}
exit:
	// remove in-string linebreaks
	str = strings.Replace(str, "\n", " ", -1)
	str = strings.Replace(str, "\r", " ", -1)
	return str
}
<|endoftext|>


<commit_before>package main

import (
	"math/rand"
	"time"

	"github.com/kataras/iris"
	"github.com/kataras/iris/context"

	prometheusMiddleware "github.com/iris-contrib/middleware/prometheus"

	"github.com/prometheus/client_golang/prometheus"
)

func main() {
	app := iris.New()
	m := prometheusMiddleware.New("serviceName", 300, 1200, 5000)

	app.Use(m.ServeHTTP)

	app.OnStatusCode(iris.StatusNotFound, func(ctx context.Context) {
		// error code handlers are not sharing the same middleware as other routes, so we have
		// to call them inside their body.
		m.ServeHTTP(ctx)

		ctx.Writef("Not Found")
	})

	app.Get("/", func(ctx context.Context) {
		sleep := rand.Intn(4999) + 1
		time.Sleep(time.Duration(sleep) * time.Millisecond)
		ctx.Writef("Slept for %d milliseconds", sleep)
	})

	app.Get("/metrics", iris.FromStd(prometheus.Handler()))

	// http://localhost:8080/
	// http://localhost:8080/anotfound
	// http://localhost:8080/metrics
	app.Run(iris.Addr(":8080"))
}
<commit_msg>fix prometheus example :headphones:<commit_after>package main

import (
	"math/rand"
	"time"

	"github.com/kataras/iris"
	"github.com/kataras/iris/context"

	prometheusMiddleware "github.com/iris-contrib/middleware/prometheus"

	"github.com/prometheus/client_golang/prometheus"
)

func main() {
	app := iris.New()
	m := prometheusMiddleware.New("serviceName", 300, 1200, 5000)

	app.Use(m.ServeHTTP)

	app.OnErrorCode(iris.StatusNotFound, func(ctx context.Context) {
		// error code handlers are not sharing the same middleware as other routes, so we have
		// to call them inside their body.
		m.ServeHTTP(ctx)

		ctx.Writef("Not Found")
	})

	app.Get("/", func(ctx context.Context) {
		sleep := rand.Intn(4999) + 1
		time.Sleep(time.Duration(sleep) * time.Millisecond)
		ctx.Writef("Slept for %d milliseconds", sleep)
	})

	app.Get("/metrics", iris.FromStd(prometheus.Handler()))

	// http://localhost:8080/
	// http://localhost:8080/anotfound
	// http://localhost:8080/metrics
	app.Run(iris.Addr(":8080"))
}
<|endoftext|>


<commit_before>package gview_test

import (
	"github.com/gogf/gf/g"
	"github.com/gogf/gf/g/os/gfile"
	"github.com/gogf/gf/g/os/gview"
	"github.com/gogf/gf/g/test/gtest"
	"github.com/gogf/gf/g/text/gstr"
	"io/ioutil"
	"os"
	"testing"
)

func TestView_Basic(t *testing.T) {
	gtest.Case(t, func() {
		str := `hello {{.name}},version:{{.version}};hello {{GetName}},version:{{GetVersion}};{{.other}}`
		pwd := gfile.Pwd()
		view := gview.New()
		view.SetDelimiters("{{", "}}")
		view.AddPath(pwd)
		view.SetPath(pwd)
		view.Assign("name", "gf")
		view.Assigns(g.Map{"version": "1.7.0"})
		view.BindFunc("GetName", func() string { return "gf" })
		view.BindFuncMap(gview.FuncMap{"GetVersion": func() string { return "1.7.0" }})
		result, err := view.ParseContent(str, g.Map{"other": "that's all"})
		gtest.Assert(err != nil, false)
		gtest.Assert(result, "hello gf,version:1.7.0;hello gf,version:1.7.0;that's all")

		//测试api方法
		str = `hello {{.name}}`
		result, err = gview.ParseContent(str, g.Map{"name": "gf"})
		gtest.Assert(err != nil, false)
		gtest.Assert(result, "hello gf")

		//测试instance方法
		result, err = gview.Instance().ParseContent(str, g.Map{"name": "gf"})
		gtest.Assert(err != nil, false)
		gtest.Assert(result, "hello gf")
	})
}

func TestView_Func(t *testing.T) {
	gtest.Case(t, func() {
		str := `{{eq 1 1}};{{eq 1 2}};{{eq "A" "B"}}`
		result, err := gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `true;false;false`)

		str = `{{ne 1 2}};{{ne 1 1}};{{ne "A" "B"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `true;false;true`)

		str = `{{lt 1 2}};{{lt 1 1}};{{lt 1 0}};{{lt "A" "B"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `true;false;false;true`)

		str = `{{le 1 2}};{{le 1 1}};{{le 1 0}};{{le "A" "B"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `true;true;false;true`)

		str = `{{gt 1 2}};{{gt 1 1}};{{gt 1 0}};{{gt "A" "B"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `false;false;true;false`)

		str = `{{ge 1 2}};{{ge 1 1}};{{ge 1 0}};{{ge "A" "B"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `false;true;true;false`)

		str = `{{"<div>测试</div>"|text}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `测试`)

		str = `{{"<div>测试</div>"|html}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `<div>测试</div>`)

		str = `{{"<div>测试</div>"|htmlencode}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `<div>测试</div>`)

		str = `{{"<div>测试</div>"|htmldecode}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `<div>测试</div>`)

		str = `{{"https://goframe.org"|url}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `https%3A%2F%2Fgoframe.org`)

		str = `{{"https://goframe.org"|urlencode}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `https%3A%2F%2Fgoframe.org`)

		str = `{{"https%3A%2F%2Fgoframe.org"|urldecode}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `https://goframe.org`)
		str = `{{"https%3NA%2F%2Fgoframe.org"|urldecode}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(gstr.Contains(result, "invalid URL escape"), true)

		str = `{{1540822968 | date "Y-m-d"}};{{"1540822968" | date "Y-m-d H:i:s"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `2018-10-29;2018-10-29 22:22:48`)
		str = `{{1540822968 | date "Y-m-d"}};{{"1540822968" | date "Y-m-d H:i:s"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `2018-10-29;2018-10-29 22:22:48`)
		str = `{{date "Y-m-d"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)

		str = `{{"我是中国人" | substr 2 -1}};{{"我是中国人" | substr 2  2}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `中国人;中国`)

		str = `{{"我是中国人" | strlimit 2  "..."}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `我是...`)

		str = `{{compare "A" "B"}};{{compare "1" "2"}};{{compare 2 1}};{{compare 1 1}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `-1;-1;1;0`)

		str = `{{"热爱GF热爱生活" | hidestr 20  "*"}};{{"热爱GF热爱生活" | hidestr 50  "*"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `热爱GF*爱生活;热爱****生活`)

		str = `{{"热爱GF热爱生活" | highlight "GF" "red"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `热爱<span style="color:red;">GF</span>热爱生活`)

		str = `{{"gf" | toupper}};{{"GF" | tolower}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `GF;gf`)

		str = `{{"Go\nFrame" | nl2br}}`
		view := gview.New()
		result, err = view.ParseContent(str)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `Go<br>Frame`)
	})
}

func TestView_FuncInclude(t *testing.T) {
	gtest.Case(t, func() {
		header := `<h1>HEADER</h1>`
		main := `<h1>hello gf</h1>`
		footer := `<h1>FOOTER</h1>`
		layout := `{{include "header.html" .}}
{{include "main.html" .}}
{{include "footer.html" .}}`
		templatePath := gfile.Pwd() + gfile.Separator + "template"
		gfile.Mkdir(templatePath)
		defer gfile.Remove(templatePath)
		//headerFile, _ := gfile.Create(templatePath + gfile.Separator + "header.html")
		err := ioutil.WriteFile(templatePath+gfile.Separator+"header.html", []byte(header), 0644)
		if err != nil {
			t.Error(err)
		}
		ioutil.WriteFile(templatePath+gfile.Separator+"main.html", []byte(main), 0644)
		ioutil.WriteFile(templatePath+gfile.Separator+"footer.html", []byte(footer), 0644)
		ioutil.WriteFile(templatePath+gfile.Separator+"layout.html", []byte(layout), 0644)
		view := gview.New(templatePath)
		result, err := view.Parse("notfound.html")
		gtest.Assert(err != nil, true)
		gtest.Assert(result, ``)
		result, err = view.Parse("layout.html")
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `
HEADER

hello gf

FOOTER
`)
		notfoundPath := templatePath + gfile.Separator + "template" + gfile.Separator + "notfound.html"
		gfile.Mkdir(templatePath + gfile.Separator + "template")
		gfile.Create(notfoundPath)
		ioutil.WriteFile(notfoundPath, []byte("notfound"), 0644)
		result, err = view.Parse("notfound.html")
		gtest.Assert(err != nil, true)
		gtest.Assert(result, ``)
	})
}

func TestView_SetPath(t *testing.T) {
	gtest.Case(t, func() {
		view := gview.Instance("addpath")
		err := view.AddPath("tmp")
		gtest.Assert(err == nil, false)

		err = view.AddPath("gview.go")
		gtest.Assert(err == nil, false)

		os.Setenv("GF_GVIEW_PATH", "tmp")
		view = gview.Instance("setpath")
		err = view.SetPath("tmp")
		gtest.Assert(err == nil, false)

		err = view.SetPath("gview.go")
		gtest.Assert(err == nil, false)

		view = gview.New(gfile.Pwd())
		err = view.SetPath("tmp")
		gtest.Assert(err == nil, false)

		err = view.SetPath("gview.go")
		gtest.Assert(err == nil, false)

		os.Setenv("GF_GVIEW_PATH", "template")
		gfile.Mkdir(gfile.Pwd() + gfile.Separator + "template")
		view = gview.New()
	})
}

func TestView_ParseContent(t *testing.T) {
	gtest.Case(t, func() {
		str := `{{.name}}`
		view := gview.New()
		result, err := view.ParseContent(str, g.Map{"name": func() {}})
		gtest.Assert(err != nil, true)
		gtest.Assert(result, ``)
	})
}
<commit_msg>gspath模块及gview模块测试用例编写<commit_after>package gview_test

import (
	"github.com/gogf/gf/g"
	"github.com/gogf/gf/g/os/gfile"
	"github.com/gogf/gf/g/os/gview"
	"github.com/gogf/gf/g/test/gtest"
	"github.com/gogf/gf/g/text/gstr"
	"io/ioutil"
	"os"
	"testing"
)

func TestView_Basic(t *testing.T) {
	gtest.Case(t, func() {
		str := `hello {{.name}},version:{{.version}};hello {{GetName}},version:{{GetVersion}};{{.other}}`
		pwd := gfile.Pwd()
		view := gview.New()
		view.SetDelimiters("{{", "}}")
		view.AddPath(pwd)
		view.SetPath(pwd)
		view.Assign("name", "gf")
		view.Assigns(g.Map{"version": "1.7.0"})
		view.BindFunc("GetName", func() string { return "gf" })
		view.BindFuncMap(gview.FuncMap{"GetVersion": func() string { return "1.7.0" }})
		result, err := view.ParseContent(str, g.Map{"other": "that's all"})
		gtest.Assert(err != nil, false)
		gtest.Assert(result, "hello gf,version:1.7.0;hello gf,version:1.7.0;that's all")

		//测试api方法
		str = `hello {{.name}}`
		result, err = gview.ParseContent(str, g.Map{"name": "gf"})
		gtest.Assert(err != nil, false)
		gtest.Assert(result, "hello gf")

		//测试instance方法
		result, err = gview.Instance().ParseContent(str, g.Map{"name": "gf"})
		gtest.Assert(err != nil, false)
		gtest.Assert(result, "hello gf")
	})
}

func TestView_Func(t *testing.T) {
	gtest.Case(t, func() {
		str := `{{eq 1 1}};{{eq 1 2}};{{eq "A" "B"}}`
		result, err := gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `true;false;false`)

		str = `{{ne 1 2}};{{ne 1 1}};{{ne "A" "B"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `true;false;true`)

		str = `{{lt 1 2}};{{lt 1 1}};{{lt 1 0}};{{lt "A" "B"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `true;false;false;true`)

		str = `{{le 1 2}};{{le 1 1}};{{le 1 0}};{{le "A" "B"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `true;true;false;true`)

		str = `{{gt 1 2}};{{gt 1 1}};{{gt 1 0}};{{gt "A" "B"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `false;false;true;false`)

		str = `{{ge 1 2}};{{ge 1 1}};{{ge 1 0}};{{ge "A" "B"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `false;true;true;false`)

		str = `{{"<div>测试</div>"|text}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `测试`)

		str = `{{"<div>测试</div>"|html}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `<div>测试</div>`)

		str = `{{"<div>测试</div>"|htmlencode}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `<div>测试</div>`)

		str = `{{"<div>测试</div>"|htmldecode}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `<div>测试</div>`)

		str = `{{"https://goframe.org"|url}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `https%3A%2F%2Fgoframe.org`)

		str = `{{"https://goframe.org"|urlencode}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `https%3A%2F%2Fgoframe.org`)

		str = `{{"https%3A%2F%2Fgoframe.org"|urldecode}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `https://goframe.org`)
		str = `{{"https%3NA%2F%2Fgoframe.org"|urldecode}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(gstr.Contains(result, "invalid URL escape"), true)

		str = `{{1540822968 | date "Y-m-d"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `2018-10-29`)
		str = `{{date "Y-m-d"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)

		str = `{{"我是中国人" | substr 2 -1}};{{"我是中国人" | substr 2  2}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `中国人;中国`)

		str = `{{"我是中国人" | strlimit 2  "..."}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `我是...`)

		str = `{{compare "A" "B"}};{{compare "1" "2"}};{{compare 2 1}};{{compare 1 1}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `-1;-1;1;0`)

		str = `{{"热爱GF热爱生活" | hidestr 20  "*"}};{{"热爱GF热爱生活" | hidestr 50  "*"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `热爱GF*爱生活;热爱****生活`)

		str = `{{"热爱GF热爱生活" | highlight "GF" "red"}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `热爱<span style="color:red;">GF</span>热爱生活`)

		str = `{{"gf" | toupper}};{{"GF" | tolower}}`
		result, err = gview.ParseContent(str, nil)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `GF;gf`)

		str = `{{"Go\nFrame" | nl2br}}`
		view := gview.New()
		result, err = view.ParseContent(str)
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `Go<br>Frame`)
	})
}

func TestView_FuncInclude(t *testing.T) {
	gtest.Case(t, func() {
		header := `<h1>HEADER</h1>`
		main := `<h1>hello gf</h1>`
		footer := `<h1>FOOTER</h1>`
		layout := `{{include "header.html" .}}
{{include "main.html" .}}
{{include "footer.html" .}}`
		templatePath := gfile.Pwd() + gfile.Separator + "template"
		gfile.Mkdir(templatePath)
		defer gfile.Remove(templatePath)
		//headerFile, _ := gfile.Create(templatePath + gfile.Separator + "header.html")
		err := ioutil.WriteFile(templatePath+gfile.Separator+"header.html", []byte(header), 0644)
		if err != nil {
			t.Error(err)
		}
		ioutil.WriteFile(templatePath+gfile.Separator+"main.html", []byte(main), 0644)
		ioutil.WriteFile(templatePath+gfile.Separator+"footer.html", []byte(footer), 0644)
		ioutil.WriteFile(templatePath+gfile.Separator+"layout.html", []byte(layout), 0644)
		view := gview.New(templatePath)
		result, err := view.Parse("notfound.html")
		gtest.Assert(err != nil, true)
		gtest.Assert(result, ``)
		result, err = view.Parse("layout.html")
		gtest.Assert(err != nil, false)
		gtest.Assert(result, `
HEADER

hello gf

FOOTER
`)
		notfoundPath := templatePath + gfile.Separator + "template" + gfile.Separator + "notfound.html"
		gfile.Mkdir(templatePath + gfile.Separator + "template")
		gfile.Create(notfoundPath)
		ioutil.WriteFile(notfoundPath, []byte("notfound"), 0644)
		result, err = view.Parse("notfound.html")
		gtest.Assert(err != nil, true)
		gtest.Assert(result, ``)
	})
}

func TestView_SetPath(t *testing.T) {
	gtest.Case(t, func() {
		view := gview.Instance("addpath")
		err := view.AddPath("tmp")
		gtest.Assert(err == nil, false)

		err = view.AddPath("gview.go")
		gtest.Assert(err == nil, false)

		os.Setenv("GF_GVIEW_PATH", "tmp")
		view = gview.Instance("setpath")
		err = view.SetPath("tmp")
		gtest.Assert(err == nil, false)

		err = view.SetPath("gview.go")
		gtest.Assert(err == nil, false)

		view = gview.New(gfile.Pwd())
		err = view.SetPath("tmp")
		gtest.Assert(err == nil, false)

		err = view.SetPath("gview.go")
		gtest.Assert(err == nil, false)

		os.Setenv("GF_GVIEW_PATH", "template")
		gfile.Mkdir(gfile.Pwd() + gfile.Separator + "template")
		view = gview.New()
	})
}

func TestView_ParseContent(t *testing.T) {
	gtest.Case(t, func() {
		str := `{{.name}}`
		view := gview.New()
		result, err := view.ParseContent(str, g.Map{"name": func() {}})
		gtest.Assert(err != nil, true)
		gtest.Assert(result, ``)
	})
}
<|endoftext|>


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

package gcsproxy_test

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"testing"

	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/mock_gcs"
	"github.com/jacobsa/gcsfuse/gcsproxy"
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	"golang.org/x/net/context"
	"google.golang.org/cloud/storage"
)

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

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

// An oglemock.Matcher that accepts a predicate function and a description,
// making it easy to make anonymous matcher types.
type predicateMatcher struct {
	Desc      string
	Predicate func(interface{}) error
}

var _ Matcher = &predicateMatcher{}

func (m *predicateMatcher) Matches(candidate interface{}) error {
	return m.Predicate(candidate)
}

func (m *predicateMatcher) Description() string {
	return m.Desc
}

func nameIs(name string) Matcher {
	return &predicateMatcher{
		Desc: fmt.Sprintf("Name is: %s", name),
		Predicate: func(candidate interface{}) error {
			req := candidate.(*gcs.CreateObjectRequest)
			if req.Attrs.Name != name {
				return errors.New("")
			}

			return nil
		},
	}
}

func contentsAre(s string) Matcher {
	return &predicateMatcher{
		Desc: fmt.Sprintf("Object contents are: %s", s),
		Predicate: func(candidate interface{}) error {
			// Snarf the contents.
			req := candidate.(*gcs.CreateObjectRequest)
			contents, err := ioutil.ReadAll(req.Contents)
			if err != nil {
				panic(err)
			}

			// Compare
			if string(contents) != s {
				return errors.New("")
			}

			return nil
		},
	}
}

////////////////////////////////////////////////////////////////////////
// Invariant-checking object proxy
////////////////////////////////////////////////////////////////////////

// A wrapper around ObjectProxy that calls CheckInvariants whenever invariants
// should hold. For catching logic errors early in the test.
type checkingObjectProxy struct {
	wrapped *gcsproxy.ObjectProxy
}

func (op *checkingObjectProxy) Name() string {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Name()
}

func (op *checkingObjectProxy) Stat() (uint64, bool, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Stat(context.Background())
}

func (op *checkingObjectProxy) ReadAt(b []byte, o int64) (int, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.ReadAt(context.Background(), b, o)
}

func (op *checkingObjectProxy) WriteAt(b []byte, o int64) (int, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.WriteAt(context.Background(), b, o)
}

func (op *checkingObjectProxy) Truncate(n uint64) error {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Truncate(context.Background(), n)
}

func (op *checkingObjectProxy) Sync() (uint64, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Sync(context.Background())
}

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

type ObjectProxyTest struct {
	objectName string
	bucket     mock_gcs.MockBucket
	op         checkingObjectProxy
}

func (t *ObjectProxyTest) setUp(ti *TestInfo, srcGeneration uint64) {
	t.objectName = "some/object"
	t.bucket = mock_gcs.NewMockBucket(ti.MockController, "bucket")

	var err error
	t.op.wrapped, err = gcsproxy.NewObjectProxy(
		context.Background(),
		t.bucket,
		t.objectName,
		srcGeneration)

	if err != nil {
		panic(err)
	}
}

////////////////////////////////////////////////////////////////////////
// No source object
////////////////////////////////////////////////////////////////////////

// A test whose initial conditions are a fresh object proxy without a source
// object set.
type NoSourceObjectTest struct {
	ObjectProxyTest
}

var _ SetUpInterface = &NoSourceObjectTest{}

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

func (t *NoSourceObjectTest) SetUp(ti *TestInfo) {
	t.ObjectProxyTest.setUp(ti, 0)
}

func (t *NoSourceObjectTest) Name() {
	ExpectEq(t.objectName, t.op.Name())
}

func (t *NoSourceObjectTest) Read_InitialState() {
	buf := make([]byte, 1024)
	n, err := t.op.ReadAt(buf, 0)

	ExpectEq(io.EOF, err)
	ExpectEq(0, n)
}

func (t *NoSourceObjectTest) WriteToEndOfObjectThenRead() {
	var buf []byte
	var n int
	var err error

	// Extend the object by writing twice.
	n, err = t.op.WriteAt([]byte("taco"), 0)
	AssertEq(nil, err)
	AssertEq(len("taco"), n)

	n, err = t.op.WriteAt([]byte("burrito"), int64(len("taco")))
	AssertEq(nil, err)
	AssertEq(len("burrito"), n)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(len("tacoburrito"), n)
	ExpectEq("tacoburrito", string(buf[:n]))

	// Read a range in the middle.
	buf = make([]byte, 4)
	n, err = t.op.ReadAt(buf, 3)

	AssertEq(nil, err)
	ExpectEq(4, n)
	ExpectEq("obur", string(buf[:n]))
}

func (t *NoSourceObjectTest) WritePastEndOfObjectThenRead() {
	var n int
	var err error
	var buf []byte

	// Extend the object by writing past its end.
	n, err = t.op.WriteAt([]byte("taco"), 2)
	AssertEq(nil, err)
	AssertEq(len("taco"), n)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(2+len("taco"), n)
	ExpectEq("\x00\x00taco", string(buf[:n]))

	// Read a range in the middle.
	buf = make([]byte, 4)
	n, err = t.op.ReadAt(buf, 1)

	AssertEq(nil, err)
	ExpectEq(4, n)
	ExpectEq("\x00tac", string(buf[:n]))
}

func (t *NoSourceObjectTest) WriteWithinObjectThenRead() {
	var n int
	var err error
	var buf []byte

	// Write several bytes to extend the object.
	n, err = t.op.WriteAt([]byte("00000"), 0)
	AssertEq(nil, err)
	AssertEq(len("00000"), n)

	// Overwrite some in the middle.
	n, err = t.op.WriteAt([]byte("11"), 1)
	AssertEq(nil, err)
	AssertEq(len("11"), n)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(len("01100"), n)
	ExpectEq("01100", string(buf[:n]))
}

func (t *NoSourceObjectTest) GrowByTruncating() {
	var n int
	var err error
	var buf []byte

	// Truncate
	err = t.op.Truncate(4)
	AssertEq(nil, err)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(4, n)
	ExpectEq("\x00\x00\x00\x00", string(buf[:n]))
}

func (t *NoSourceObjectTest) Sync_CallsCreateObject() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Sync_CreateObjectFails() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Sync_CreateObjectSaysPreconditionFailed() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Sync_Successful() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_CallsBucket() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_BucketFails() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_InitialState() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterShortening() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterGrowing() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterReading() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterWriting() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_Clobbered() {
	AssertTrue(false, "TODO")
}

////////////////////////////////////////////////////////////////////////
// Source object present
////////////////////////////////////////////////////////////////////////

// A test whose initial conditions are an object proxy branching from a source
// object in the bucket.
type SourceObjectPresentTest struct {
	ObjectProxyTest
	sourceObject *storage.Object
}

var _ SetUpInterface = &SourceObjectPresentTest{}

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

func (t *SourceObjectPresentTest) SetUp(ti *TestInfo) {
	t.ObjectProxyTest.setUp(ti, 123)
}

func (t *SourceObjectPresentTest) Read_CallsNewReader() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Read_NewReaderFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Read_NewReaderSucceeds() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Write_CallsNewReader() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Write_NewReaderFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Write_NewReaderSucceeds() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Truncate_CallsNewReader() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Truncate_NewReaderFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Truncate_NewReaderSucceeds() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_NoInteractions() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_AfterReading() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_AfterWriting() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_AfterTruncating() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_CallsCreateObject() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_CallsBucket() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_BucketFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_BucketSaysNotFound() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_InitialState() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterShortening() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterGrowing() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterReading() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterWriting() {
	AssertTrue(false, "TODO")
}

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

package gcsproxy_test

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"testing"

	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/mock_gcs"
	"github.com/jacobsa/gcsfuse/gcsproxy"
	. "github.com/jacobsa/oglematchers"
	. "github.com/jacobsa/ogletest"
	"golang.org/x/net/context"
	"google.golang.org/cloud/storage"
)

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

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

// An oglemock.Matcher that accepts a predicate function and a description,
// making it easy to make anonymous matcher types.
type predicateMatcher struct {
	Desc      string
	Predicate func(interface{}) error
}

var _ Matcher = &predicateMatcher{}

func (m *predicateMatcher) Matches(candidate interface{}) error {
	return m.Predicate(candidate)
}

func (m *predicateMatcher) Description() string {
	return m.Desc
}

func nameIs(name string) Matcher {
	return &predicateMatcher{
		Desc: fmt.Sprintf("Name is: %s", name),
		Predicate: func(candidate interface{}) error {
			req := candidate.(*gcs.CreateObjectRequest)
			if req.Attrs.Name != name {
				return errors.New("")
			}

			return nil
		},
	}
}

func contentsAre(s string) Matcher {
	return &predicateMatcher{
		Desc: fmt.Sprintf("Object contents are: %s", s),
		Predicate: func(candidate interface{}) error {
			// Snarf the contents.
			req := candidate.(*gcs.CreateObjectRequest)
			contents, err := ioutil.ReadAll(req.Contents)
			if err != nil {
				panic(err)
			}

			// Compare
			if string(contents) != s {
				return errors.New("")
			}

			return nil
		},
	}
}

////////////////////////////////////////////////////////////////////////
// Invariant-checking object proxy
////////////////////////////////////////////////////////////////////////

// A wrapper around ObjectProxy that calls CheckInvariants whenever invariants
// should hold. For catching logic errors early in the test.
type checkingObjectProxy struct {
	wrapped *gcsproxy.ObjectProxy
}

func (op *checkingObjectProxy) Name() string {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Name()
}

func (op *checkingObjectProxy) Stat() (uint64, bool, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Stat(context.Background())
}

func (op *checkingObjectProxy) ReadAt(b []byte, o int64) (int, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.ReadAt(context.Background(), b, o)
}

func (op *checkingObjectProxy) WriteAt(b []byte, o int64) (int, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.WriteAt(context.Background(), b, o)
}

func (op *checkingObjectProxy) Truncate(n uint64) error {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Truncate(context.Background(), n)
}

func (op *checkingObjectProxy) Sync() (uint64, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Sync(context.Background())
}

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

type ObjectProxyTest struct {
	objectName string
	bucket     mock_gcs.MockBucket
	op         checkingObjectProxy
}

func (t *ObjectProxyTest) setUp(ti *TestInfo, srcGeneration uint64) {
	t.objectName = "some/object"
	t.bucket = mock_gcs.NewMockBucket(ti.MockController, "bucket")

	var err error
	t.op.wrapped, err = gcsproxy.NewObjectProxy(
		context.Background(),
		t.bucket,
		t.objectName,
		srcGeneration)

	if err != nil {
		panic(err)
	}
}

////////////////////////////////////////////////////////////////////////
// No source object
////////////////////////////////////////////////////////////////////////

// A test whose initial conditions are a fresh object proxy without a source
// object set.
type NoSourceObjectTest struct {
	ObjectProxyTest
}

var _ SetUpInterface = &NoSourceObjectTest{}

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

func (t *NoSourceObjectTest) SetUp(ti *TestInfo) {
	t.ObjectProxyTest.setUp(ti, 0)
}

func (t *NoSourceObjectTest) Name() {
	ExpectEq(t.objectName, t.op.Name())
}

func (t *NoSourceObjectTest) Read_InitialState() {
	buf := make([]byte, 1024)
	n, err := t.op.ReadAt(buf, 0)

	ExpectEq(io.EOF, err)
	ExpectEq(0, n)
}

func (t *NoSourceObjectTest) WriteToEndOfObjectThenRead() {
	var buf []byte
	var n int
	var err error

	// Extend the object by writing twice.
	n, err = t.op.WriteAt([]byte("taco"), 0)
	AssertEq(nil, err)
	AssertEq(len("taco"), n)

	n, err = t.op.WriteAt([]byte("burrito"), int64(len("taco")))
	AssertEq(nil, err)
	AssertEq(len("burrito"), n)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(len("tacoburrito"), n)
	ExpectEq("tacoburrito", string(buf[:n]))

	// Read a range in the middle.
	buf = make([]byte, 4)
	n, err = t.op.ReadAt(buf, 3)

	AssertEq(nil, err)
	ExpectEq(4, n)
	ExpectEq("obur", string(buf[:n]))
}

func (t *NoSourceObjectTest) WritePastEndOfObjectThenRead() {
	var n int
	var err error
	var buf []byte

	// Extend the object by writing past its end.
	n, err = t.op.WriteAt([]byte("taco"), 2)
	AssertEq(nil, err)
	AssertEq(len("taco"), n)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(2+len("taco"), n)
	ExpectEq("\x00\x00taco", string(buf[:n]))

	// Read a range in the middle.
	buf = make([]byte, 4)
	n, err = t.op.ReadAt(buf, 1)

	AssertEq(nil, err)
	ExpectEq(4, n)
	ExpectEq("\x00tac", string(buf[:n]))
}

func (t *NoSourceObjectTest) WriteWithinObjectThenRead() {
	var n int
	var err error
	var buf []byte

	// Write several bytes to extend the object.
	n, err = t.op.WriteAt([]byte("00000"), 0)
	AssertEq(nil, err)
	AssertEq(len("00000"), n)

	// Overwrite some in the middle.
	n, err = t.op.WriteAt([]byte("11"), 1)
	AssertEq(nil, err)
	AssertEq(len("11"), n)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(len("01100"), n)
	ExpectEq("01100", string(buf[:n]))
}

func (t *NoSourceObjectTest) GrowByTruncating() {
	var n int
	var err error
	var buf []byte

	// Truncate
	err = t.op.Truncate(4)
	AssertEq(nil, err)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(4, n)
	ExpectEq("\x00\x00\x00\x00", string(buf[:n]))
}

func (t *NoSourceObjectTest) Sync_CallsCreateObject_NoInteractions() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Sync_CallsCreateObject_AfterWriting() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Sync_CreateObjectFails() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Sync_CreateObjectSaysPreconditionFailed() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Sync_Successful() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_CallsBucket() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_BucketFails() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_InitialState() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterShortening() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterGrowing() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterReading() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterWriting() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_Clobbered() {
	AssertTrue(false, "TODO")
}

////////////////////////////////////////////////////////////////////////
// Source object present
////////////////////////////////////////////////////////////////////////

// A test whose initial conditions are an object proxy branching from a source
// object in the bucket.
type SourceObjectPresentTest struct {
	ObjectProxyTest
	sourceObject *storage.Object
}

var _ SetUpInterface = &SourceObjectPresentTest{}

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

func (t *SourceObjectPresentTest) SetUp(ti *TestInfo) {
	t.ObjectProxyTest.setUp(ti, 123)
}

func (t *SourceObjectPresentTest) Read_CallsNewReader() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Read_NewReaderFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Read_NewReaderSucceeds() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Write_CallsNewReader() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Write_NewReaderFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Write_NewReaderSucceeds() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Truncate_CallsNewReader() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Truncate_NewReaderFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Truncate_NewReaderSucceeds() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_NoInteractions() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_AfterReading() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_AfterWriting() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_AfterTruncating() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_CallsCreateObject() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_CallsBucket() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_BucketFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_BucketSaysNotFound() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_InitialState() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterShortening() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterGrowing() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterReading() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterWriting() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_Clobbered() {
	AssertTrue(false, "TODO")
}
<|endoftext|>


<commit_before>// Go Donut!
//
// originals:
// http://www.a1k0n.net/2011/07/20/donut-math.html  (original by Andy Sloane)
// https://github.com/GaryBoone/GoDonut             (donut.go by Gary Boone)
//
// This version tweaks the constants a bit (to lessen the "transparent" effect), uses
// Termbox for rendering, makes the loop interruptable and enables a sort-of-shaded mode.
// Hint: hit enter while running. ESCape to quit.
//
// 20150514 - Onno Siemens

package main

import (
	"github.com/nsf/termbox-go"
	"math"
	"time"
)

const frame_delay = 20
const theta_spacing = 0.01
const phi_spacing = 0.01

const R1 = 1.0
const R2 = 2.0
const K2 = 6.0

type Screen struct {
	dim  int
	data [][]byte
}

func newZBuffer(d int) *[][]float64 {
	b := make([][]float64, d)
	for i := range b {
		b[i] = make([]float64, d)
	}
	return &b
}

func newScreen(d int) *Screen {
	b := make([][]byte, d)
	for i := range b {
		b[i] = make([]byte, d)
	}
	return &Screen{d, b}
}

func (screen Screen) render(asciimode bool) {
	for i, _ := range screen.data {
		for j, _ := range screen.data[i] {
			if asciimode {
				termbox.SetCell(i, j, rune(screen.data[i][j]), 0, 0)
			} else {
				switch screen.data[i][j] {
				case '.':
					termbox.SetCell(i, j, ' ', 0, 5)
				case ',':
					termbox.SetCell(i, j, ' ', 0, 7)
				case '-':
					termbox.SetCell(i, j, ' ', 0, 9)
				case '~':
					termbox.SetCell(i, j, ' ', 0, 11)
				case ':':
					termbox.SetCell(i, j, ' ', 0, 13)
				case ';':
					termbox.SetCell(i, j, ' ', 0, 15)
				case '=':
					termbox.SetCell(i, j, ' ', 0, 17)
				case '!':
					termbox.SetCell(i, j, ' ', 0, 18)
				case '*':
					termbox.SetCell(i, j, ' ', 0, 19)
				case '#':
					termbox.SetCell(i, j, ' ', 0, 20)
				case '$':
					termbox.SetCell(i, j, ' ', 0, 22)
				case '@':
					termbox.SetCell(i, j, ' ', 0, 24)
				default:
					termbox.SetCell(i, j, ' ', 1, 0)
				}
			}
		}
	}
	screen.clear()

}

func (screen *Screen) clear() {
	for i, _ := range screen.data {
		for j, _ := range screen.data[i] {
			screen.data[i][j] = ' '
		}
	}
}

func (screen *Screen) computeFrame(A, B, K1 float64) {

	// precompute sines and cosines of A and B
	cosA := math.Cos(A)
	sinA := math.Sin(A)
	cosB := math.Cos(B)
	sinB := math.Sin(B)

	//screen.clear()
	zbuffer := newZBuffer(screen.dim)

	// theta goes around the cross-sectional circle of a torus
	for theta := 0.0; theta < 2.0*math.Pi; theta += theta_spacing {
		// precompute sines and cosines of theta
		costheta := math.Cos(theta)
		sintheta := math.Sin(theta)

		// phi goes around the center of revolution of a torus
		for phi := 0.0; phi < 2.0*math.Pi; phi += phi_spacing {
			// precompute sines and cosines of phi
			cosphi := math.Cos(phi)
			sinphi := math.Sin(phi)

			// the x,y coordinate of the circle, before revolving (factored out of the above equations)
			circlex := R2 + R1*costheta
			circley := R1 * sintheta

			// final 3D (x,y,z) coordinate after rotations, directly from our math above
			x := circlex*(cosB*cosphi+sinA*sinB*sinphi) - circley*cosA*sinB
			y := circlex*(sinB*cosphi-sinA*cosB*sinphi) + circley*cosA*cosB
			z := K2 + cosA*circlex*sinphi + circley*sinA
			ooz := 1 / z // "one over z"

			// x and y projection.  note that y is negated here, because y goes up in
			// 3D space but down on 2D displays.
			xp := int(float64(screen.dim)/2.0 + K1*ooz*x)
			yp := int(float64(screen.dim)/2.0 - K1*ooz*y)

			// calculate luminance.  ugly, but correct.
			L := cosphi*costheta*sinB - cosA*costheta*sinphi - sinA*sintheta +
				cosB*(cosA*sintheta-costheta*sinA*sinphi)
			// L ranges from -sqrt(2) to +sqrt(2).  If it's < 0, the surface is
			// pointing away from us, so we won't bother trying to plot it.
			if L > 0 {
				// test against the z-buffer.  larger 1/z means the pixel is closer to
				// the viewer than what's already plotted.
				if ooz > (*zbuffer)[yp][xp] {
					(*zbuffer)[yp][xp] = ooz
					luminance_index := int(L * 8.0) // this brings L into the range 0..11 (8*sqrt(2) = 11.3)
					// now we lookup the character corresponding to the luminance and plot it in our output:
					screen.data[yp][xp] = ".,-~:;=!*#$@"[luminance_index]
				}
			}
		}
	}
}

func main() {
	err := termbox.Init()
	if err != nil {
		panic(err)
	}
	defer termbox.Close()

	event_queue := make(chan termbox.Event)
	go func() {
		for {
			event_queue <- termbox.PollEvent()
		}
	}()
	w, h := termbox.Size()
	dim := int(math.Min(float64(w), float64(h)))
	screen := newScreen(dim)
	termbox.SetOutputMode(termbox.OutputGrayscale)
	asciimode := true

	// Calculate K1 based on screen size: the maximum x-distance occurs roughly at
	// the edge of the torus, which is at x=R1+R2, z=0.  we want that to be
	// displaced 3/8ths of the width of the screen, which is 3/4th of the way from
	// the center to the side of the screen.
	// screen_width*3/8 = K1*(R1+R2)/(K2+0)
	// screen_width*K2*3/(8*(R1+R2)) = K1
	A, B, K1 := 1.0, 1.0, float64(screen.dim)*K2*3.0/(8.0*(R1+R2))

loop:
	for {
		select {
		case ev := <-event_queue:
			if ev.Type == termbox.EventKey && ev.Key == termbox.KeyEsc {
				break loop
			}
			if ev.Type == termbox.EventKey && ev.Key == termbox.KeyEnter {
				asciimode = !asciimode
			}

		default:
			A += 0.07
			B += 0.03
			screen.computeFrame(A, B, K1)
			screen.render(asciimode)
			termbox.Flush()
			time.Sleep(frame_delay * time.Millisecond)
		}
	}
}
<commit_msg>use a lookup table for ascii -> termbox_luminance values<commit_after>// Go Donut!
//
// originals:
// http://www.a1k0n.net/2011/07/20/donut-math.html  (original by Andy Sloane)
// https://github.com/GaryBoone/GoDonut             (donut.go by Gary Boone)
//
// This version tweaks the constants a bit (to lessen the "transparent" effect), uses
// Termbox for rendering, makes the loop interruptable and enables a sort-of-shaded mode.
// Hint: hit enter while running. ESCape to quit.
//
// 20150514 - Onno Siemens

package main

import (
	"github.com/nsf/termbox-go"
	"math"
	"time"
)

const frame_delay = 20
const theta_spacing = 0.01
const phi_spacing = 0.01

const R1 = 1.0
const R2 = 2.0
const K2 = 6.0

type Screen struct {
	dim  int
	data [][]byte
}

func newZBuffer(d int) *[][]float64 {
	b := make([][]float64, d)
	for i := range b {
		b[i] = make([]float64, d)
	}
	return &b
}

func newScreen(d int) *Screen {
	b := make([][]byte, d)
	for i := range b {
		b[i] = make([]byte, d)
	}
	return &Screen{d, b}
}

func (screen Screen) render(asciimode bool) {
	for i, _ := range screen.data {
		for j, _ := range screen.data[i] {
			// map our ascii characters to grayscale luminance levels for termbox
			var lindex = map[byte]int{
				'.':5,
				',':7,
				'-':9,
				'~':11,
				':':13,
				';':15,
				'=':17,
				'!':18,
				'*':19,
				'#':20,
				'$':22,
				'@':24,
			}
			if asciimode {
				termbox.SetCell(i, j, rune(screen.data[i][j]), 0, 0)
			} else {
					termbox.SetCell(i, j, ' ', 0, termbox.Attribute(lindex[screen.data[i][j]]))
			}
		}
	}
	screen.clear()

}

func (screen *Screen) clear() {
	for i, _ := range screen.data {
		for j, _ := range screen.data[i] {
			screen.data[i][j] = ' '
		}
	}
}

func (screen *Screen) computeFrame(A, B, K1 float64) {

	// precompute sines and cosines of A and B
	cosA := math.Cos(A)
	sinA := math.Sin(A)
	cosB := math.Cos(B)
	sinB := math.Sin(B)

	//screen.clear()
	zbuffer := newZBuffer(screen.dim)

	// theta goes around the cross-sectional circle of a torus
	for theta := 0.0; theta < 2.0*math.Pi; theta += theta_spacing {
		// precompute sines and cosines of theta
		costheta := math.Cos(theta)
		sintheta := math.Sin(theta)

		// phi goes around the center of revolution of a torus
		for phi := 0.0; phi < 2.0*math.Pi; phi += phi_spacing {
			// precompute sines and cosines of phi
			cosphi := math.Cos(phi)
			sinphi := math.Sin(phi)

			// the x,y coordinate of the circle, before revolving (factored out of the above equations)
			circlex := R2 + R1*costheta
			circley := R1 * sintheta

			// final 3D (x,y,z) coordinate after rotations, directly from our math above
			x := circlex*(cosB*cosphi+sinA*sinB*sinphi) - circley*cosA*sinB
			y := circlex*(sinB*cosphi-sinA*cosB*sinphi) + circley*cosA*cosB
			z := K2 + cosA*circlex*sinphi + circley*sinA
			ooz := 1 / z // "one over z"

			// x and y projection.  note that y is negated here, because y goes up in
			// 3D space but down on 2D displays.
			xp := int(float64(screen.dim)/2.0 + K1*ooz*x)
			yp := int(float64(screen.dim)/2.0 - K1*ooz*y)

			// calculate luminance.  ugly, but correct.
			L := cosphi*costheta*sinB - cosA*costheta*sinphi - sinA*sintheta +
				cosB*(cosA*sintheta-costheta*sinA*sinphi)
			// L ranges from -sqrt(2) to +sqrt(2).  If it's < 0, the surface is
			// pointing away from us, so we won't bother trying to plot it.
			if L > 0 {
				// test against the z-buffer.  larger 1/z means the pixel is closer to
				// the viewer than what's already plotted.
				if ooz > (*zbuffer)[yp][xp] {
					(*zbuffer)[yp][xp] = ooz
					luminance_index := int(L * 8.0) // this brings L into the range 0..11 (8*sqrt(2) = 11.3)
					// now we lookup the character corresponding to the luminance and plot it in our output:
					screen.data[yp][xp] = ".,-~:;=!*#$@"[luminance_index]
				}
			}
		}
	}
}

func main() {
	err := termbox.Init()
	if err != nil {
		panic(err)
	}
	defer termbox.Close()

	event_queue := make(chan termbox.Event)
	go func() {
		for {
			event_queue <- termbox.PollEvent()
		}
	}()
	w, h := termbox.Size()
	dim := int(math.Min(float64(w), float64(h)))
	screen := newScreen(dim)
	termbox.SetOutputMode(termbox.OutputGrayscale)
	asciimode := true

	// Calculate K1 based on screen size: the maximum x-distance occurs roughly at
	// the edge of the torus, which is at x=R1+R2, z=0.  we want that to be
	// displaced 3/8ths of the width of the screen, which is 3/4th of the way from
	// the center to the side of the screen.
	// screen_width*3/8 = K1*(R1+R2)/(K2+0)
	// screen_width*K2*3/(8*(R1+R2)) = K1
	A, B, K1 := 1.0, 1.0, float64(screen.dim)*K2*3.0/(8.0*(R1+R2))

loop:
	for {
		select {
		case ev := <-event_queue:
			if ev.Type == termbox.EventKey && ev.Key == termbox.KeyEsc {
				break loop
			}
			if ev.Type == termbox.EventKey && ev.Key == termbox.KeyEnter {
				asciimode = !asciimode
			}

		default:
			A += 0.07
			B += 0.03
			screen.computeFrame(A, B, K1)
			screen.render(asciimode)
			termbox.Flush()
			time.Sleep(frame_delay * time.Millisecond)
		}
	}
}
<|endoftext|>


<commit_before>package ak

import (
	"encoding/json"
	"net/http"
	"path"
	"reflect"
	"strconv"
)

//定义方法类型
type actionFunc func(*Context)

//请求上下文
type Context struct {
	Request        *http.Request
	ResponseWriter http.ResponseWriter
	Params         map[string]string
	Data           map[string]interface{} //返回参数定义
	server         *Server
	Session        *Session
	closed         bool
}

//返回json
func (ctx *Context) WriteJson(content interface{}) {
	if ctx.closed {
		return
	}
	ctx.ResponseWriter.Header().Set("Content-Type", "application/json;charset=UTF-8")
	cv := reflect.ValueOf(content)
	if cv.Type().Kind() == reflect.String {
		ctx.ResponseWriter.Write([]byte(cv.String()))
	} else if cv.Type().Kind() == reflect.Struct || cv.Type().Kind() == reflect.Slice {
		jsonData, err := json.Marshal(content)
		if err != nil {
			panic(err)
		}
		ctx.ResponseWriter.Write(jsonData)
	}
	ctx.closed = true
}

//字符流
func (ctx *Context) WriteStream(filename string, contentType string, data []byte) {
	if ctx.closed {
		return
	}
	ctx.ResponseWriter.Header().Add("Content-Disposition", "attachment;filename="+filename)
	ctx.ResponseWriter.Header().Set("Content-Type", contentType)
	ctx.ResponseWriter.Header().Set("Content-Length", strconv.Itoa(len(data)))
	ctx.ResponseWriter.Write(data)
	ctx.closed = true
}

//返回html
func (ctx *Context) WriteHtml(html string) {
	if ctx.closed {
		return
	}
	ctx.ResponseWriter.Write([]byte(html))
	ctx.closed = true
}

//返回模板
func (ctx *Context) WriteTpl(tplName string) {
	if ctx.closed {
		return
	}
	tplPath := path.Join(ctx.server.config.tplPath, tplName)
	if !fileExists(tplPath) {
		ctx.Abort(404, tplName+" not fond")
	}
	parseTpl(ctx.ResponseWriter, tplPath, ctx.Data, ctx.server.config.leftDelim, ctx.server.config.rightDelim)
	//	s := parseTmplateToStr(tplPath)
	//	t, err := template.New("index").Funcs(template.FuncMap{"include": includeTmplate}).Parse(s)
	//	tpl, err := template.ParseFiles(tplPath)
	//	if err != nil {
	//		panic(err.Error())
	//	}
	//	t.Execute(ctx.ResponseWriter, ctx.Data)
	ctx.closed = true
}

//重定向 3xx
func (ctx *Context) Redirect(url_ string) {
	if ctx.closed {
		return
	}
	ctx.ResponseWriter.Header().Set("Location", url_)
	ctx.ResponseWriter.WriteHeader(301)
	ctx.ResponseWriter.Write([]byte("Redirecting to: " + url_))
	ctx.closed = true
}

//错误信息
func (ctx *Context) Abort(status int, body string) {
	if ctx.closed {
		return
	}
	ctx.ResponseWriter.WriteHeader(status)
	ctx.ResponseWriter.Write([]byte(body))
	ctx.closed = true
}

//将请求数据的json格式信息转换成结构
func (ctx *Context) ParseReqBodyJson(obj interface{}) error {
	decoder := json.NewDecoder(ctx.Request.Body)
	k := reflect.ValueOf(obj).Type().Kind()
	var err error
	switch k {
	case reflect.Struct:
		err = decoder.Decode(&obj)
	case reflect.Ptr:
		err = decoder.Decode(obj)
	case reflect.Array:
		err = decoder.Decode(obj)
	case reflect.String:
		err = decoder.Decode(&obj)
	}
	return err
}
<commit_msg>fix prt to json<commit_after>package ak

import (
	"encoding/json"
	"log"
	"net/http"
	"path"
	"reflect"
	"strconv"
)

//定义方法类型
type actionFunc func(*Context)

//请求上下文
type Context struct {
	Request        *http.Request
	ResponseWriter http.ResponseWriter
	Params         map[string]string
	Data           map[string]interface{} //返回参数定义
	server         *Server
	Session        *Session
	closed         bool
}

//返回json
func (ctx *Context) WriteJson(content interface{}) {
	if ctx.closed {
		return
	}
	ctx.ResponseWriter.Header().Set("Content-Type", "application/json;charset=UTF-8")
	cv := reflect.ValueOf(content)
	log.Println("cv = ", cv.Type().Kind())
	if cv.Type().Kind() == reflect.String {
		ctx.ResponseWriter.Write([]byte(cv.String()))
	} else if cv.Type().Kind() == reflect.Struct || cv.Type().Kind() == reflect.Slice || cv.Type().Kind() == reflect.Ptr {
		jsonData, err := json.Marshal(content)
		if err != nil {
			panic(err)
		}
		ctx.ResponseWriter.Write(jsonData)
	}
	ctx.closed = true
}

//字符流
func (ctx *Context) WriteStream(filename string, contentType string, data []byte) {
	if ctx.closed {
		return
	}
	ctx.ResponseWriter.Header().Add("Content-Disposition", "attachment;filename="+filename)
	ctx.ResponseWriter.Header().Set("Content-Type", contentType)
	ctx.ResponseWriter.Header().Set("Content-Length", strconv.Itoa(len(data)))
	ctx.ResponseWriter.Write(data)
	ctx.closed = true
}

//返回html
func (ctx *Context) WriteHtml(html string) {
	if ctx.closed {
		return
	}
	ctx.ResponseWriter.Write([]byte(html))
	ctx.closed = true
}

//返回模板
func (ctx *Context) WriteTpl(tplName string) {
	if ctx.closed {
		return
	}
	tplPath := path.Join(ctx.server.config.tplPath, tplName)
	if !fileExists(tplPath) {
		ctx.Abort(404, tplName+" not fond")
	}
	parseTpl(ctx.ResponseWriter, tplPath, ctx.Data, ctx.server.config.leftDelim, ctx.server.config.rightDelim)
	//	s := parseTmplateToStr(tplPath)
	//	t, err := template.New("index").Funcs(template.FuncMap{"include": includeTmplate}).Parse(s)
	//	tpl, err := template.ParseFiles(tplPath)
	//	if err != nil {
	//		panic(err.Error())
	//	}
	//	t.Execute(ctx.ResponseWriter, ctx.Data)
	ctx.closed = true
}

//重定向 3xx
func (ctx *Context) Redirect(url_ string) {
	if ctx.closed {
		return
	}
	ctx.ResponseWriter.Header().Set("Location", url_)
	ctx.ResponseWriter.WriteHeader(301)
	ctx.ResponseWriter.Write([]byte("Redirecting to: " + url_))
	ctx.closed = true
}

//错误信息
func (ctx *Context) Abort(status int, body string) {
	if ctx.closed {
		return
	}
	ctx.ResponseWriter.WriteHeader(status)
	ctx.ResponseWriter.Write([]byte(body))
	ctx.closed = true
}

//将请求数据的json格式信息转换成结构
func (ctx *Context) ParseReqBodyJson(obj interface{}) error {
	decoder := json.NewDecoder(ctx.Request.Body)
	k := reflect.ValueOf(obj).Type().Kind()
	var err error
	switch k {
	case reflect.Struct:
		err = decoder.Decode(&obj)
	case reflect.Ptr:
		err = decoder.Decode(obj)
	case reflect.Array:
		err = decoder.Decode(obj)
	case reflect.String:
		err = decoder.Decode(&obj)
	}
	return err
}
<|endoftext|>