<commit_before>package aero_test

import (
	"errors"
	"fmt"
	"net/http"
	"net/http/httptest"
	"os"
	"syscall"
	"testing"
	"time"

	"github.com/aerogo/aero"
	"github.com/aerogo/http/client"
	"github.com/akyoto/assert"
)

const helloWorld = "Hello World"

func TestApplicationAny(t *testing.T) {
	app := aero.New()

	app.Any("/", func(ctx aero.Context) error {
		return ctx.Text(helloWorld)
	})

	app.OnError(func(ctx aero.Context, err error) {
		t.Fatal(err)
	})

	methods := []string{
		"GET",
		"POST",
		"PUT",
		"DELETE",
	}

	for _, method := range methods {
		// Test existing route
		request := httptest.NewRequest(method, "/", nil)
		response := httptest.NewRecorder()
		app.ServeHTTP(response, request)

		assert.Equal(t, response.Code, http.StatusOK)
		assert.Equal(t, response.Body.String(), helloWorld)

		// Test non-existing route
		request = httptest.NewRequest(method, "/404", nil)
		response = httptest.NewRecorder()
		app.ServeHTTP(response, request)

		assert.Equal(t, response.Code, http.StatusNotFound)
		assert.Equal(t, response.Body.String(), "")
	}
}

func TestApplicationRewrite(t *testing.T) {
	app := aero.New()

	app.Get("/hello", func(ctx aero.Context) error {
		return ctx.Text(helloWorld)
	})

	// Rewrite route
	app.Rewrite(func(ctx aero.RewriteContext) {
		if ctx.Path() == "/" {
			ctx.SetPath("/hello")
			return
		}
	})

	response := test(app, "/")

	assert.Equal(t, response.Code, http.StatusOK)
	assert.Equal(t, response.Body.String(), helloWorld)
}

func TestApplicationLoadConfig(t *testing.T) {
	app := aero.New()
	workingDirectory, _ := os.Getwd()

	err := os.Chdir("testdata")
	assert.Nil(t, err)

	app.Load()

	err = os.Chdir(workingDirectory)
	assert.Nil(t, err)
}

func TestApplicationRun(t *testing.T) {
	app := aero.New()

	// When frontpage is requested, kill the server
	app.Get("/", func(ctx aero.Context) error {
		return ctx.HTML(helloWorld)
	})

	// When the server is started, we request the frontpage
	app.OnStart(func() {
		_, err := client.Get(fmt.Sprintf("http://localhost:%d/", app.Config.Ports.HTTP)).End()
		assert.Nil(t, err)

		err = syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
		assert.Nil(t, err)
	})

	// When the server ends, check elapsed time
	app.OnEnd(func() {
		elapsed := time.Since(app.StartTime())
		assert.Equal(t, elapsed < 2*time.Second, true)
	})

	// Run
	app.Run()
}

func TestApplicationRunHTTPS(t *testing.T) {
	app := aero.New()
	app.Security.Load("testdata/fullchain.pem", "testdata/privkey.pem")

	app.Get("/", func(ctx aero.Context) error {
		return ctx.HTML(helloWorld)
	})

	// When the server is started, we request the frontpage
	app.OnStart(func() {
		_, err := client.Get(fmt.Sprintf("http://localhost:%d/", app.Config.Ports.HTTP)).End()
		assert.Nil(t, err)

		_, err = client.Get(fmt.Sprintf("https://localhost:%d/", app.Config.Ports.HTTPS)).End()
		assert.Nil(t, err)

		go func() {
			err = syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
			assert.Nil(t, err)
		}()
	})

	// Run
	app.Run()
}

func TestApplicationRouteTests(t *testing.T) {
	app := aero.New()

	app.Get("/user/:id", func(ctx aero.Context) error {
		return ctx.Text(ctx.Get("id"))
	})

	app.Get("/untested/:untested", func(ctx aero.Context) error {
		return ctx.Text(ctx.Get("untested"))
	})

	// Specify a test route explicitly
	app.Test("/user/:id", "/user/123")
	app.TestRoutes()
}

func TestApplicationUnavailablePort(t *testing.T) {
	defer func() {
		_ = recover()
		// assert.NotNil(t, r)
		// assert.Contains(t, r.(error).Error(), "bind: permission denied")
	}()

	app := aero.New()
	app.Config.Ports.HTTP = 80
	app.Config.Ports.HTTPS = 443
	app.ListenAndServe()
}

// test sends a request to the server and returns the response.
func test(app *aero.Application, route string) *httptest.ResponseRecorder {
	request := httptest.NewRequest("GET", route, nil)
	request.Header.Set("Accept-Encoding", "gzip")

	response := httptest.NewRecorder()
	app.ServeHTTP(response, request)

	return response
}

func TestApplicationOnError(t *testing.T) {
	app := aero.New()

	app.Get("/", func(ctx aero.Context) error {
		return errors.New("something happened")
	})

	app.OnError(func(ctx aero.Context, err error) {
		assert.Equal(t, err.Error(), "something happened")
	})

	test(app, "/")
}
<commit_msg>Fixed test<commit_after>package aero_test

import (
	"errors"
	"fmt"
	"net/http"
	"net/http/httptest"
	"os"
	"syscall"
	"testing"
	"time"

	"github.com/aerogo/aero"
	"github.com/aerogo/http/client"
	"github.com/akyoto/assert"
)

const helloWorld = "Hello World"

func TestApplicationAny(t *testing.T) {
	app := aero.New()

	app.Any("/", func(ctx aero.Context) error {
		return ctx.Text(helloWorld)
	})

	app.OnError(func(ctx aero.Context, err error) {
		t.Fatal(err)
	})

	methods := []string{
		"GET",
		"POST",
		"PUT",
		"DELETE",
	}

	for _, method := range methods {
		// Test existing route
		request := httptest.NewRequest(method, "/", nil)
		response := httptest.NewRecorder()
		app.ServeHTTP(response, request)

		assert.Equal(t, response.Code, http.StatusOK)
		assert.Equal(t, response.Body.String(), helloWorld)

		// Test non-existing route
		request = httptest.NewRequest(method, "/404", nil)
		response = httptest.NewRecorder()
		app.ServeHTTP(response, request)

		assert.Equal(t, response.Code, http.StatusNotFound)
		assert.Equal(t, response.Body.String(), "")
	}
}

func TestApplicationRewrite(t *testing.T) {
	app := aero.New()

	app.Get("/hello", func(ctx aero.Context) error {
		return ctx.Text(helloWorld)
	})

	// Rewrite route
	app.Rewrite(func(ctx aero.RewriteContext) {
		if ctx.Path() == "/" {
			ctx.SetPath("/hello")
			return
		}
	})

	response := test(app, "/")

	assert.Equal(t, response.Code, http.StatusOK)
	assert.Equal(t, response.Body.String(), helloWorld)
}

func TestApplicationLoadConfig(t *testing.T) {
	app := aero.New()
	workingDirectory, _ := os.Getwd()

	err := os.Chdir("testdata")
	assert.Nil(t, err)

	app.Load()

	err = os.Chdir(workingDirectory)
	assert.Nil(t, err)
}

func TestApplicationRun(t *testing.T) {
	start := time.Now()
	app := aero.New()

	// When frontpage is requested, kill the server
	app.Get("/", func(ctx aero.Context) error {
		return ctx.HTML(helloWorld)
	})

	// When the server is started, we request the frontpage
	app.OnStart(func() {
		_, err := client.Get(fmt.Sprintf("http://localhost:%d/", app.Config.Ports.HTTP)).End()
		assert.Nil(t, err)

		err = syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
		assert.Nil(t, err)
	})

	// When the server ends, check elapsed time
	app.OnEnd(func() {
		elapsed := time.Since(start)
		assert.Equal(t, elapsed < 2*time.Second, true)
	})

	// Run
	app.Run()
}

func TestApplicationRunHTTPS(t *testing.T) {
	app := aero.New()
	app.Security.Load("testdata/fullchain.pem", "testdata/privkey.pem")

	app.Get("/", func(ctx aero.Context) error {
		return ctx.HTML(helloWorld)
	})

	// When the server is started, we request the frontpage
	app.OnStart(func() {
		_, err := client.Get(fmt.Sprintf("http://localhost:%d/", app.Config.Ports.HTTP)).End()
		assert.Nil(t, err)

		_, err = client.Get(fmt.Sprintf("https://localhost:%d/", app.Config.Ports.HTTPS)).End()
		assert.Nil(t, err)

		go func() {
			err = syscall.Kill(syscall.Getpid(), syscall.SIGTERM)
			assert.Nil(t, err)
		}()
	})

	// Run
	app.Run()
}

func TestApplicationRouteTests(t *testing.T) {
	app := aero.New()

	app.Get("/user/:id", func(ctx aero.Context) error {
		return ctx.Text(ctx.Get("id"))
	})

	app.Get("/untested/:untested", func(ctx aero.Context) error {
		return ctx.Text(ctx.Get("untested"))
	})

	// Specify a test route explicitly
	app.Test("/user/:id", "/user/123")
	app.TestRoutes()
}

func TestApplicationUnavailablePort(t *testing.T) {
	defer func() {
		_ = recover()
		// assert.NotNil(t, r)
		// assert.Contains(t, r.(error).Error(), "bind: permission denied")
	}()

	app := aero.New()
	app.Config.Ports.HTTP = 80
	app.Config.Ports.HTTPS = 443
	app.ListenAndServe()
}

// test sends a request to the server and returns the response.
func test(app *aero.Application, route string) *httptest.ResponseRecorder {
	request := httptest.NewRequest("GET", route, nil)
	request.Header.Set("Accept-Encoding", "gzip")

	response := httptest.NewRecorder()
	app.ServeHTTP(response, request)

	return response
}

func TestApplicationOnError(t *testing.T) {
	app := aero.New()

	app.Get("/", func(ctx aero.Context) error {
		return errors.New("something happened")
	})

	app.OnError(func(ctx aero.Context, err error) {
		assert.Equal(t, err.Error(), "something happened")
	})

	test(app, "/")
}
<|endoftext|>


<commit_before>package dagcmd

import (
	"fmt"
	"io"
	"strings"

	cmds "github.com/ipfs/go-ipfs/commands"

	ipldcbor "gx/ipfs/QmRcAVqrbY5wryx7hfNLtiUZbCcstzaJL7YJFBboitcqWF/go-ipld-cbor"
	node "gx/ipfs/QmU7bFWQ793qmvNy7outdCaMfSDNk8uqhx4VNrxYj5fj5g/go-ipld-node"
	cid "gx/ipfs/QmXfiyr2RWEXpVDdaYnD2HNiBk6UBddsvEP4RPfXb6nGqY/go-cid"
)

var DagCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline:          "Interact with ipld dag objects.",
		ShortDescription: ``,
	},
	Subcommands: map[string]*cmds.Command{
		"put": DagPutCmd,
		"get": DagGetCmd,
	},
}

type OutputObject struct {
	Cid *cid.Cid
}

var DagPutCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Add a dag node to ipfs.",
	},
	Arguments: []cmds.Argument{
		cmds.FileArg("object data", true, false, "The object to put").EnableStdin(),
	},
	Options: []cmds.Option{
		cmds.StringOption("format", "f", "Format that the object will be added as.").Default("cbor"),
		cmds.StringOption("input-enc", "Format that the input object will be.").Default("json"),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		n, err := req.InvocContext().GetNode()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		fi, err := req.Files().NextFile()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		ienc, _, _ := req.Option("input-enc").String()
		format, _, _ := req.Option("format").String()

		switch ienc {
		case "json":
			nd, err := convertJsonToType(fi, format)
			if err != nil {
				res.SetError(err, cmds.ErrNormal)
				return
			}

			c, err := n.DAG.Add(nd)
			if err != nil {
				res.SetError(err, cmds.ErrNormal)
				return
			}

			res.SetOutput(&OutputObject{Cid: c})
			return
		default:
			res.SetError(fmt.Errorf("unrecognized input encoding: %s", ienc), cmds.ErrNormal)
			return
		}
	},
	Type: OutputObject{},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			oobj, ok := res.Output().(*OutputObject)
			if !ok {
				return nil, fmt.Errorf("expected a different object in marshaler")
			}

			return strings.NewReader(oobj.Cid.String()), nil
		},
	},
}

var DagGetCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Get a dag node from ipfs.",
	},
	Arguments: []cmds.Argument{
		cmds.StringArg("cid", true, false, "The cid of the object to get").EnableStdin(),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		n, err := req.InvocContext().GetNode()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		c, err := cid.Decode(req.Arguments()[0])
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		obj, err := n.DAG.Get(req.Context(), c)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		res.SetOutput(obj)
	},
}

func convertJsonToType(r io.Reader, format string) (node.Node, error) {
	switch format {
	case "cbor", "dag-cbor":
		return ipldcbor.FromJson(r)
	case "dag-pb", "protobuf":
		return nil, fmt.Errorf("protobuf handling in 'dag' command not yet implemented")
	default:
		return nil, fmt.Errorf("unknown target format: %s", format)
	}
}
<commit_msg>add more helptext to dag commands<commit_after>package dagcmd

import (
	"fmt"
	"io"
	"strings"

	cmds "github.com/ipfs/go-ipfs/commands"

	ipldcbor "gx/ipfs/QmRcAVqrbY5wryx7hfNLtiUZbCcstzaJL7YJFBboitcqWF/go-ipld-cbor"
	node "gx/ipfs/QmU7bFWQ793qmvNy7outdCaMfSDNk8uqhx4VNrxYj5fj5g/go-ipld-node"
	cid "gx/ipfs/QmXfiyr2RWEXpVDdaYnD2HNiBk6UBddsvEP4RPfXb6nGqY/go-cid"
)

var DagCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Interact with ipld dag objects.",
		ShortDescription: `
'ipfs dag' is used for creating and manipulating dag objects.

This subcommand is currently an experimental feature, but it is intended
to deprecate and replace the existing 'ipfs object' command moving forward.
		`,
	},
	Subcommands: map[string]*cmds.Command{
		"put": DagPutCmd,
		"get": DagGetCmd,
	},
}

type OutputObject struct {
	Cid *cid.Cid
}

var DagPutCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Add a dag node to ipfs.",
		ShortDescription: `
'ipfs dag put' accepts input from a file or stdin and parses it
into an object of the specified format.
`,
	},
	Arguments: []cmds.Argument{
		cmds.FileArg("object data", true, false, "The object to put").EnableStdin(),
	},
	Options: []cmds.Option{
		cmds.StringOption("format", "f", "Format that the object will be added as.").Default("cbor"),
		cmds.StringOption("input-enc", "Format that the input object will be.").Default("json"),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		n, err := req.InvocContext().GetNode()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		fi, err := req.Files().NextFile()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		ienc, _, _ := req.Option("input-enc").String()
		format, _, _ := req.Option("format").String()

		switch ienc {
		case "json":
			nd, err := convertJsonToType(fi, format)
			if err != nil {
				res.SetError(err, cmds.ErrNormal)
				return
			}

			c, err := n.DAG.Add(nd)
			if err != nil {
				res.SetError(err, cmds.ErrNormal)
				return
			}

			res.SetOutput(&OutputObject{Cid: c})
			return
		default:
			res.SetError(fmt.Errorf("unrecognized input encoding: %s", ienc), cmds.ErrNormal)
			return
		}
	},
	Type: OutputObject{},
	Marshalers: cmds.MarshalerMap{
		cmds.Text: func(res cmds.Response) (io.Reader, error) {
			oobj, ok := res.Output().(*OutputObject)
			if !ok {
				return nil, fmt.Errorf("expected a different object in marshaler")
			}

			return strings.NewReader(oobj.Cid.String()), nil
		},
	},
}

var DagGetCmd = &cmds.Command{
	Helptext: cmds.HelpText{
		Tagline: "Get a dag node from ipfs.",
		ShortDescription: `
'ipfs dag get' fetches a dag node from ipfs and prints it out in the specifed format.
`,
	},
	Arguments: []cmds.Argument{
		cmds.StringArg("cid", true, false, "The cid of the object to get").EnableStdin(),
	},
	Run: func(req cmds.Request, res cmds.Response) {
		n, err := req.InvocContext().GetNode()
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		c, err := cid.Decode(req.Arguments()[0])
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		obj, err := n.DAG.Get(req.Context(), c)
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
		}

		res.SetOutput(obj)
	},
}

func convertJsonToType(r io.Reader, format string) (node.Node, error) {
	switch format {
	case "cbor", "dag-cbor":
		return ipldcbor.FromJson(r)
	case "dag-pb", "protobuf":
		return nil, fmt.Errorf("protobuf handling in 'dag' command not yet implemented")
	default:
		return nil, fmt.Errorf("unknown target format: %s", format)
	}
}
<|endoftext|>


<commit_before>package cloudstack

// UpdateDiskOffering represents the paramter of UpdateDiskOffering
type UpdateDiskOfferingParameter struct {
	// an optional field, whether to display the offering to the end user or not.
	DisplayOffering NullBool
	// updates alternate display text of the disk offering with this value
	DisplayText NullString
	// ID of the disk offering
	Id ID
	// updates name of the disk offering with this value
	Name NullString
	// sort key of the disk offering, integer
	SortKey NullNumber
}

func NewUpdateDiskOfferingParameter(id string) (p *UpdateDiskOfferingParameter) {
	p = new(UpdateDiskOfferingParameter)
	p.Id.Set(id)
	return p
}

// Updates a disk offering.
func (c *Client) UpdateDiskOffering(p *UpdateDiskOfferingParameter) (*DiskOffering, error) {
	obj, err := c.Request("updateDiskOffering", convertParamToMap(p))
	if err != nil {
		return nil, err
	}
	return obj.(*DiskOffering), err
}

// ListDiskOfferings represents the paramter of ListDiskOfferings
type ListDiskOfferingsParameter struct {
	// the ID of the domain of the disk offering.
	DomainId ID
	// ID of the disk offering
	Id ID
	// List by keyword
	Keyword NullString
	// name of the disk offering
	Name     NullString
	Page     NullNumber
	PageSize NullNumber
}

func NewListDiskOfferingsParameter() (p *ListDiskOfferingsParameter) {
	p = new(ListDiskOfferingsParameter)
	return p
}

// Lists all available disk offerings.
func (c *Client) ListDiskOfferings(p *ListDiskOfferingsParameter) ([]*DiskOffering, error) {
	obj, err := c.Request("listDiskOfferings", convertParamToMap(p))
	if err != nil {
		return nil, err
	}
	return obj.([]*DiskOffering), err
}

// DeleteDiskOffering represents the paramter of DeleteDiskOffering
type DeleteDiskOfferingParameter struct {
	// ID of the disk offering
	Id ID
}

func NewDeleteDiskOfferingParameter(id string) (p *DeleteDiskOfferingParameter) {
	p = new(DeleteDiskOfferingParameter)
	p.Id.Set(id)
	return p
}

// Updates a disk offering.
func (c *Client) DeleteDiskOffering(p *DeleteDiskOfferingParameter) (*Result, error) {
	obj, err := c.Request("deleteDiskOffering", convertParamToMap(p))
	if err != nil {
		return nil, err
	}
	return obj.(*Result), err
}

// CreateDiskOffering represents the paramter of CreateDiskOffering
type CreateDiskOfferingParameter struct {
	// bytes read rate of the disk offering
	BytesReadRate NullNumber
	// bytes write rate of the disk offering
	BytesWriteRate NullNumber
	// whether disk offering size is custom or not
	Customized NullBool
	// whether disk offering iops is custom or not
	CustomizedIops NullBool
	// size of the disk offering in GB
	DiskSize NullNumber
	// an optional field, whether to display the offering to the end user or not.
	DisplayOffering NullBool
	// alternate display text of the disk offering
	DisplayText NullString
	// the ID of the containing domain, null for public offerings
	DomainId ID
	// Hypervisor snapshot reserve space as a percent of a volume (for managed
	// storage using Xen or VMware)
	HypervisorSnapshotReserve NullNumber
	// io requests read rate of the disk offering
	IopsReadRate NullNumber
	// io requests write rate of the disk offering
	IopsWriteRate NullNumber
	// max iops of the disk offering
	MaxIops NullNumber
	// min iops of the disk offering
	MinIops NullNumber
	// name of the disk offering
	Name NullString
	// the storage type of the disk offering. Values are local and shared.
	StorageType NullString
	// tags for the disk offering
	Tags NullString
}

func NewCreateDiskOfferingParameter(displaytext string, name string) (p *CreateDiskOfferingParameter) {
	p = new(CreateDiskOfferingParameter)
	p.DisplayText.Set(displaytext)
	p.Name.Set(name)
	return p
}

// Creates a disk offering.
func (c *Client) CreateDiskOffering(p *CreateDiskOfferingParameter) (*DiskOffering, error) {
	obj, err := c.Request("createDiskOffering", convertParamToMap(p))
	if err != nil {
		return nil, err
	}
	return obj.(*DiskOffering), err
}

<commit_msg>update disk offering api parameters<commit_after>package cloudstack

// UpdateDiskOffering represents the paramter of UpdateDiskOffering
type UpdateDiskOfferingParameter struct {
	// an optional field, whether to display the offering to the end user or not.
	DisplayOffering NullBool
	// updates alternate display text of the disk offering with this value
	DisplayText NullString
	// ID of the disk offering
	Id ID
	// updates name of the disk offering with this value
	Name NullString
	// sort key of the disk offering, integer
	SortKey NullNumber
}

func NewUpdateDiskOfferingParameter(id string) (p *UpdateDiskOfferingParameter) {
	p = new(UpdateDiskOfferingParameter)
	p.Id.Set(id)
	return p
}

// Updates a disk offering.
func (c *Client) UpdateDiskOffering(p *UpdateDiskOfferingParameter) (*DiskOffering, error) {
	obj, err := c.Request("updateDiskOffering", convertParamToMap(p))
	if err != nil {
		return nil, err
	}
	return obj.(*DiskOffering), err
}

// ListDiskOfferings represents the paramter of ListDiskOfferings
type ListDiskOfferingsParameter struct {
	// the ID of the domain of the disk offering.
	DomainId ID
	// ID of the disk offering
	Id ID
	// List by keyword
	Keyword NullString
	// name of the disk offering
	Name     NullString
	Page     NullNumber
	PageSize NullNumber
}

func NewListDiskOfferingsParameter() (p *ListDiskOfferingsParameter) {
	p = new(ListDiskOfferingsParameter)
	return p
}

// Lists all available disk offerings.
func (c *Client) ListDiskOfferings(p *ListDiskOfferingsParameter) ([]*DiskOffering, error) {
	obj, err := c.Request("listDiskOfferings", convertParamToMap(p))
	if err != nil {
		return nil, err
	}
	return obj.([]*DiskOffering), err
}

// DeleteDiskOffering represents the paramter of DeleteDiskOffering
type DeleteDiskOfferingParameter struct {
	// ID of the disk offering
	Id ID
}

func NewDeleteDiskOfferingParameter(id string) (p *DeleteDiskOfferingParameter) {
	p = new(DeleteDiskOfferingParameter)
	p.Id.Set(id)
	return p
}

// Updates a disk offering.
func (c *Client) DeleteDiskOffering(p *DeleteDiskOfferingParameter) (*Result, error) {
	obj, err := c.Request("deleteDiskOffering", convertParamToMap(p))
	if err != nil {
		return nil, err
	}
	return obj.(*Result), err
}

// CreateDiskOffering represents the paramter of CreateDiskOffering
type CreateDiskOfferingParameter struct {
	// bytes read rate of the disk offering
	BytesReadRate NullNumber
	// bytes write rate of the disk offering
	BytesWriteRate NullNumber
	// whether disk offering size is custom or not
	Customized NullBool
	// whether disk offering iops is custom or not
	CustomizedIops NullBool
	// size of the disk offering in GB
	DiskSize NullNumber
	// an optional field, whether to display the offering to the end user or not.
	DisplayOffering NullBool
	// alternate display text of the disk offering
	DisplayText NullString
	// the ID of the containing domain, null for public offerings
	DomainId ID
	// Hypervisor snapshot reserve space as a percent of a volume (for managed
	// storage using Xen or VMware)
	HypervisorSnapshotReserve NullNumber
	// io requests read rate of the disk offering
	IopsReadRate NullNumber
	// io requests write rate of the disk offering
	IopsWriteRate NullNumber
	// max iops of the disk offering
	MaxIops NullNumber
	// min iops of the disk offering
	MinIops NullNumber
	// name of the disk offering
	Name NullString
	// provisioning type used to create volumes. Valid values are thin, sparse, fat.
	ProvisioningType NullString
	// the storage type of the disk offering. Values are local and shared.
	StorageType NullString
	// tags for the disk offering
	Tags NullString
}

func NewCreateDiskOfferingParameter(displaytext string, name string) (p *CreateDiskOfferingParameter) {
	p = new(CreateDiskOfferingParameter)
	p.DisplayText.Set(displaytext)
	p.Name.Set(name)
	return p
}

// Creates a disk offering.
func (c *Client) CreateDiskOffering(p *CreateDiskOfferingParameter) (*DiskOffering, error) {
	obj, err := c.Request("createDiskOffering", convertParamToMap(p))
	if err != nil {
		return nil, err
	}
	return obj.(*DiskOffering), err
}
<|endoftext|>


<commit_before>// Copyright 2015 ThoughtWorks, Inc.

// This file is part of Gauge.

// Gauge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

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

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

package skel

var DefaultProperties = `# default.properties
# properties set here will be available to the test execution as environment variables

# sample_key = sample_value

# The path to the gauge reports directory. Should be either relative to the project directory or an absolute path
gauge_reports_dir = reports

# Set as false if gauge reports should not be overwritten on each execution. A new time-stamped directory will be created on each execution.
overwrite_reports = true

# Set to false to disable screenshots on failure in reports.
screenshot_on_failure = true

# The path to the gauge logs directory. Should be either relative to the project directory or an absolute path
logs_directory = logs

# Set to true to use multithreading for parallel execution
enable_multithreading = false

# Possible values for this property are 'suite', 'spec' or 'scenario'.
# 'scenario' clears the objects after the execution of each scenario, new objects are created for next execution.
gauge_clear_state_level = scenario

# The path the gauge specifications directory. Takes a comma separated list of specification files/directories.
gauge_specs_dir = specs

# The default delimiter used read csv files.
csv_delimiter = ,

# Allows steps to be written in multiline
allow_multiline_step = false
`
var ExampleSpec = `# Specification Heading

This is an executable specification file. This file follows markdown syntax.
Every heading in this file denotes a scenario. Every bulleted point denotes a step.

To execute this specification, run

    gauge specs

* Vowels in English language are "aeiou".

## Vowel counts in single word

tags: single word

* The word "gauge" has "3" vowels.

## Vowel counts in multiple word

This is the second scenario in this specification

Here's a step that takes a table

* Almost all words have vowels
     |Word  |Vowel Count|
     |------|-----------|
     |Gauge |3          |
     |Mingle|2          |
     |Snap  |1          |
     |GoCD  |1          |
     |Rhythm|0          |
`
var Notice = `
| Dependency Name | Copyright Information | Description |	Repo URL | License Type	| License URL |	Forked from |
|-----------------|-----------------------|-------------|----------|--------------|-------------|-------------|
|Goproperties|Copyright (c) 2012 The Goproperties Authors.|Simple library for reading .properties (java properties) files for Go	|github.com/dmotylev/goproperties	|BSD Styled|	https://raw.githubusercontent.com/dmotylev/goproperties/master/LICENSE|
|Gauge Common|	Copyright 2015 ThoughtWorks, Inc|	|	github.com/getgauge/common|	GPLv3	|||
|terminal|	Copyright (c) 2013 Meng Zhang	|Colorful terminal output for Golang|github.com/wsxiaoys/terminal	|BSD Styled|https://raw.githubusercontent.com/wsxiaoys/terminal/master/LICENSE||
|gocheck| Copyright (c) 2010-2013 Gustavo Niemeyer <gustavo@niemeyer.net>	|Rich testing for the Go language	|gopkg.in/check.v1	|Simplified BSD	|https://raw.githubusercontent.com/go-check/check/v1/LICENSE||
|protobuf	|Copyright 2010 The Go Authors.	|Go support for Google's protocol buffers	|https://github.com/golang/protobuf	|BSD Styled	|https://raw.githubusercontent.com/golang/protobuf/master/LICENSE|
|grpc-go|Copyright 2014 gRPC authors|The Go language implementation of gRPC. HTTP/2 based RPC|https://google.golang.org/grpc|Apache 2.0|http://www.apache.org/licenses/LICENSE-2.0||
|go-logging|Copyright (c) 2013 Örjan Persson.|Golang logging library|https://github.com/op/go-logging|BSD 3-clause|https://github.com/op/go-logging/blob/master/LICENSE||
|lumberjack|Copyright (c) 2014 Nate Finch |lumberjack is a rolling logger for Go|github.com/natefinch/lumberjack|MIT|https://github.com/natefinch/lumberjack/blob/v2.0/LICENSE||
|go-ogle-analytics|Copyright © 2015 dev@jpillora.com, Google Inc.|Monitor your Go (golang) servers with Google Analytics|github.com/jpillora/go-ogle-analytics|MIT|https://github.com/jpillora/go-ogle-analytics/blob/master/LICENSE||
|fsnotify|Copyright (c) 2012 The Go Authors. All rights reserved.Copyright (c) 2012 fsnotify Authors. All rights reserved.|Cross-platform file system notifications for Go. https://fsnotify.org|github.com/fsnotify/fsnotify|BSD 3-clause|https://github.com/fsnotify/fsnotify/blob/master/LICENSE||
|go-colortext|Copyright (c) 2016, David Deng|Change the color of console text.|github.com/daviddengcn/go-colortext|BSD 3-clause|https://github.com/daviddengcn/go-colortext/blob/master/LICENSE||
|goterminal|Copyright (c) 2015 Apoorva M|A cross-platform Go-library for updating progress in terminal.|github.com/apoorvam/goterminal|MIT|https://github.com/apoorvam/goterminal/blob/master/LICENSE||
|go.uuid|Copyright (C) 2013-2016 by Maxim Bublis <b@codemonkey.ru>|UUID package for Go|github.com/satori/go.uuid|MIT|https://github.com/satori/go.uuid/blob/master/LICENSE||
|go-langserver|Copyright (c) 2016 Sourcegraph|Go language server to add Go support to editors and other tools that use the Language Server Protocol (LSP)|github.com/sourcegraph/go-langserver|MIT|https://github.com/sourcegraph/go-langserver/blob/master/LICENSE||
|jsonrpc2|Copyright (c) 2016 Sourcegraph Inc|Package jsonrpc2 provides a client and server implementation of JSON-RPC 2.0|github.com/sourcegraph/jsonrpc2|MIT|https://github.com/sourcegraph/jsonrpc2/blob/master/LICENSE||
|cobra|Copyright © 2015 Steve Francia <spf@spf13.com>.|A Commander for modern Go CLI interactions|github.com/spf13/cobra|Apache 2.0|https://github.com/spf13/cobra/blob/master/LICENSE.txt||
|pflag|Copyright (c) 2012 Alex Ogier. All rights reserved.Copyright (c) 2012 The Go Authors. All rights reserved.|Drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags.|github.com/spf13/pflag|BSD 3-clause|https://github.com/spf13/pflag/blob/master/LICENSE|https://github.com/ogier/pflag|
`

var Gitignore = `# Gauge - metadata dir
.gauge

# Gauge - log files dir
logs

# Gauge - reports generated by reporting plugins
reports

`
<commit_msg>Remove gauge_clear_state_level property<commit_after>// Copyright 2015 ThoughtWorks, Inc.

// This file is part of Gauge.

// Gauge is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

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

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

package skel

var DefaultProperties = `# default.properties
# properties set here will be available to the test execution as environment variables

# sample_key = sample_value

# The path to the gauge reports directory. Should be either relative to the project directory or an absolute path
gauge_reports_dir = reports

# Set as false if gauge reports should not be overwritten on each execution. A new time-stamped directory will be created on each execution.
overwrite_reports = true

# Set to false to disable screenshots on failure in reports.
screenshot_on_failure = true

# The path to the gauge logs directory. Should be either relative to the project directory or an absolute path
logs_directory = logs

# Set to true to use multithreading for parallel execution
enable_multithreading = false

# The path the gauge specifications directory. Takes a comma separated list of specification files/directories.
gauge_specs_dir = specs

# The default delimiter used read csv files.
csv_delimiter = ,

# Allows steps to be written in multiline
allow_multiline_step = false
`
var ExampleSpec = `# Specification Heading

This is an executable specification file. This file follows markdown syntax.
Every heading in this file denotes a scenario. Every bulleted point denotes a step.

To execute this specification, run

    gauge specs

* Vowels in English language are "aeiou".

## Vowel counts in single word

tags: single word

* The word "gauge" has "3" vowels.

## Vowel counts in multiple word

This is the second scenario in this specification

Here's a step that takes a table

* Almost all words have vowels
     |Word  |Vowel Count|
     |------|-----------|
     |Gauge |3          |
     |Mingle|2          |
     |Snap  |1          |
     |GoCD  |1          |
     |Rhythm|0          |
`
var Notice = `
| Dependency Name | Copyright Information | Description |	Repo URL | License Type	| License URL |	Forked from |
|-----------------|-----------------------|-------------|----------|--------------|-------------|-------------|
|Goproperties|Copyright (c) 2012 The Goproperties Authors.|Simple library for reading .properties (java properties) files for Go	|github.com/dmotylev/goproperties	|BSD Styled|	https://raw.githubusercontent.com/dmotylev/goproperties/master/LICENSE|
|Gauge Common|	Copyright 2015 ThoughtWorks, Inc|	|	github.com/getgauge/common|	GPLv3	|||
|terminal|	Copyright (c) 2013 Meng Zhang	|Colorful terminal output for Golang|github.com/wsxiaoys/terminal	|BSD Styled|https://raw.githubusercontent.com/wsxiaoys/terminal/master/LICENSE||
|gocheck| Copyright (c) 2010-2013 Gustavo Niemeyer <gustavo@niemeyer.net>	|Rich testing for the Go language	|gopkg.in/check.v1	|Simplified BSD	|https://raw.githubusercontent.com/go-check/check/v1/LICENSE||
|protobuf	|Copyright 2010 The Go Authors.	|Go support for Google's protocol buffers	|https://github.com/golang/protobuf	|BSD Styled	|https://raw.githubusercontent.com/golang/protobuf/master/LICENSE|
|grpc-go|Copyright 2014 gRPC authors|The Go language implementation of gRPC. HTTP/2 based RPC|https://google.golang.org/grpc|Apache 2.0|http://www.apache.org/licenses/LICENSE-2.0||
|go-logging|Copyright (c) 2013 Örjan Persson.|Golang logging library|https://github.com/op/go-logging|BSD 3-clause|https://github.com/op/go-logging/blob/master/LICENSE||
|lumberjack|Copyright (c) 2014 Nate Finch |lumberjack is a rolling logger for Go|github.com/natefinch/lumberjack|MIT|https://github.com/natefinch/lumberjack/blob/v2.0/LICENSE||
|go-ogle-analytics|Copyright © 2015 dev@jpillora.com, Google Inc.|Monitor your Go (golang) servers with Google Analytics|github.com/jpillora/go-ogle-analytics|MIT|https://github.com/jpillora/go-ogle-analytics/blob/master/LICENSE||
|fsnotify|Copyright (c) 2012 The Go Authors. All rights reserved.Copyright (c) 2012 fsnotify Authors. All rights reserved.|Cross-platform file system notifications for Go. https://fsnotify.org|github.com/fsnotify/fsnotify|BSD 3-clause|https://github.com/fsnotify/fsnotify/blob/master/LICENSE||
|go-colortext|Copyright (c) 2016, David Deng|Change the color of console text.|github.com/daviddengcn/go-colortext|BSD 3-clause|https://github.com/daviddengcn/go-colortext/blob/master/LICENSE||
|goterminal|Copyright (c) 2015 Apoorva M|A cross-platform Go-library for updating progress in terminal.|github.com/apoorvam/goterminal|MIT|https://github.com/apoorvam/goterminal/blob/master/LICENSE||
|go.uuid|Copyright (C) 2013-2016 by Maxim Bublis <b@codemonkey.ru>|UUID package for Go|github.com/satori/go.uuid|MIT|https://github.com/satori/go.uuid/blob/master/LICENSE||
|go-langserver|Copyright (c) 2016 Sourcegraph|Go language server to add Go support to editors and other tools that use the Language Server Protocol (LSP)|github.com/sourcegraph/go-langserver|MIT|https://github.com/sourcegraph/go-langserver/blob/master/LICENSE||
|jsonrpc2|Copyright (c) 2016 Sourcegraph Inc|Package jsonrpc2 provides a client and server implementation of JSON-RPC 2.0|github.com/sourcegraph/jsonrpc2|MIT|https://github.com/sourcegraph/jsonrpc2/blob/master/LICENSE||
|cobra|Copyright © 2015 Steve Francia <spf@spf13.com>.|A Commander for modern Go CLI interactions|github.com/spf13/cobra|Apache 2.0|https://github.com/spf13/cobra/blob/master/LICENSE.txt||
|pflag|Copyright (c) 2012 Alex Ogier. All rights reserved.Copyright (c) 2012 The Go Authors. All rights reserved.|Drop-in replacement for Go's flag package, implementing POSIX/GNU-style --flags.|github.com/spf13/pflag|BSD 3-clause|https://github.com/spf13/pflag/blob/master/LICENSE|https://github.com/ogier/pflag|
`

var Gitignore = `# Gauge - metadata dir
.gauge

# Gauge - log files dir
logs

# Gauge - reports generated by reporting plugins
reports

`
<|endoftext|>


<commit_before>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
	"github.com/sirupsen/logrus"
)

const VERSION = "0.0.153"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.120", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.StringVar(&conf.MgmtListen, "mgmt-listen", ":8081", "management port to run on")
	flag.IntVar(&conf.ShutdownTimeout, "shutdown-timeout", 0, "graceful shutdown timeout")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckHealthy, "hc-healthy", 1, "threshold of success checks to declare node healthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	db, err := lb.NewDB(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up database")
	}

	g, err := lb.NewAllGrouper(conf, db)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	servers := make([]*http.Server, 0, 1)
	handler := lb.NewProxy(k, g, r, conf)

	// a separate mgmt listener is requested? then let's create a LB traffic only server
	if conf.Listen != conf.MgmtListen {
		servers = append(servers, &http.Server{Addr: conf.Listen, Handler: handler})
		handler = lb.NullHandler()
	}

	// add mgmt endpoints to the handler
	handler = g.Wrap(handler) // add/del/list endpoints
	handler = r.Wrap(handler) // stats / dash endpoint

	servers = append(servers, &http.Server{Addr: conf.MgmtListen, Handler: handler})
	serve(servers, &conf)
}

func serve(servers []*http.Server, conf *lb.Config) {

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)

	for i := 0; i < len(servers); i++ {
		go func(idx int) {
			err := servers[idx].ListenAndServe()
			if err != nil && err != http.ErrServerClosed {
				logrus.WithFields(logrus.Fields{"server_id": idx}).WithError(err).Fatal("server error")
			} else {
				logrus.WithFields(logrus.Fields{"server_id": idx}).Info("server stopped")
			}
		}(i)
	}

	sig := <-ch
	logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")

	for i := 0; i < len(servers); i++ {

		ctx := context.Background()

		if conf.ShutdownTimeout > 0 {
			tmpCtx, cancel := context.WithTimeout(context.Background(), time.Duration(conf.ShutdownTimeout)*time.Second)
			ctx = tmpCtx
			defer cancel()
		}

		err := servers[i].Shutdown(ctx) // safe shutdown
		if err != nil {
			logrus.WithFields(logrus.Fields{"server_id": i}).WithError(err).Fatal("server shutdown error")
		} else {
			logrus.WithFields(logrus.Fields{"server_id": i}).Info("server shutdown")
		}
	}
}
<commit_msg>fnlb: 0.0.154 release [skip ci]<commit_after>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
	"github.com/sirupsen/logrus"
)

const VERSION = "0.0.154"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.121", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.StringVar(&conf.MgmtListen, "mgmt-listen", ":8081", "management port to run on")
	flag.IntVar(&conf.ShutdownTimeout, "shutdown-timeout", 0, "graceful shutdown timeout")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckHealthy, "hc-healthy", 1, "threshold of success checks to declare node healthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	db, err := lb.NewDB(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up database")
	}

	g, err := lb.NewAllGrouper(conf, db)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	servers := make([]*http.Server, 0, 1)
	handler := lb.NewProxy(k, g, r, conf)

	// a separate mgmt listener is requested? then let's create a LB traffic only server
	if conf.Listen != conf.MgmtListen {
		servers = append(servers, &http.Server{Addr: conf.Listen, Handler: handler})
		handler = lb.NullHandler()
	}

	// add mgmt endpoints to the handler
	handler = g.Wrap(handler) // add/del/list endpoints
	handler = r.Wrap(handler) // stats / dash endpoint

	servers = append(servers, &http.Server{Addr: conf.MgmtListen, Handler: handler})
	serve(servers, &conf)
}

func serve(servers []*http.Server, conf *lb.Config) {

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)

	for i := 0; i < len(servers); i++ {
		go func(idx int) {
			err := servers[idx].ListenAndServe()
			if err != nil && err != http.ErrServerClosed {
				logrus.WithFields(logrus.Fields{"server_id": idx}).WithError(err).Fatal("server error")
			} else {
				logrus.WithFields(logrus.Fields{"server_id": idx}).Info("server stopped")
			}
		}(i)
	}

	sig := <-ch
	logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")

	for i := 0; i < len(servers); i++ {

		ctx := context.Background()

		if conf.ShutdownTimeout > 0 {
			tmpCtx, cancel := context.WithTimeout(context.Background(), time.Duration(conf.ShutdownTimeout)*time.Second)
			ctx = tmpCtx
			defer cancel()
		}

		err := servers[i].Shutdown(ctx) // safe shutdown
		if err != nil {
			logrus.WithFields(logrus.Fields{"server_id": i}).WithError(err).Fatal("server shutdown error")
		} else {
			logrus.WithFields(logrus.Fields{"server_id": i}).Info("server shutdown")
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
	"github.com/sirupsen/logrus"
)

const VERSION = "0.0.265"

func main() {
	// XXX (reed): normalize
	level, err := logrus.ParseLevel(os.Getenv("LOG_LEVEL"))
	if err != nil {
		level = logrus.InfoLevel
	}
	logrus.SetLevel(level)

	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.232", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory; use k8s for kuberneted")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.StringVar(&conf.MgmtListen, "mgmt-listen", ":8081", "management port to run on")
	flag.IntVar(&conf.ShutdownTimeout, "shutdown-timeout", 0, "graceful shutdown timeout")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckHealthy, "hc-healthy", 1, "threshold of success checks to declare node healthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.StringVar(&conf.Namespace, "namespace", "", "kubernetes namespace to monitor")
	flag.StringVar(&conf.LabelSelector, "label-selector", "", "kubernetes label selector to monitor")
	flag.IntVar(&conf.TargetPort, "target-port", 8080, "kubernetes port to target on selected pods")

	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	db, err := lb.NewDB(conf) // Handles case where DBurl == "k8s"
	if err != nil {
		logrus.WithError(err).Fatal("error setting up database")
	}
	defer db.Close()

	g, err := lb.NewAllGrouper(conf, db)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	servers := make([]*http.Server, 0, 1)
	handler := lb.NewProxy(k, g, r, conf)

	// a separate mgmt listener is requested? then let's create a LB traffic only server
	if conf.Listen != conf.MgmtListen {
		servers = append(servers, &http.Server{Addr: conf.Listen, Handler: handler})
		handler = lb.NullHandler()
	}

	// add mgmt endpoints to the handler
	handler = g.Wrap(handler) // add/del/list endpoints
	handler = r.Wrap(handler) // stats / dash endpoint

	servers = append(servers, &http.Server{Addr: conf.MgmtListen, Handler: handler})
	serve(servers, &conf)
}

func serve(servers []*http.Server, conf *lb.Config) {

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)

	for i := 0; i < len(servers); i++ {
		go func(idx int) {
			err := servers[idx].ListenAndServe()
			if err != nil && err != http.ErrServerClosed {
				logrus.WithFields(logrus.Fields{"server_id": idx}).WithError(err).Fatal("server error")
			} else {
				logrus.WithFields(logrus.Fields{"server_id": idx}).Info("server stopped")
			}
		}(i)
	}

	sig := <-ch
	logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")

	for i := 0; i < len(servers); i++ {

		ctx := context.Background()

		if conf.ShutdownTimeout > 0 {
			tmpCtx, cancel := context.WithTimeout(context.Background(), time.Duration(conf.ShutdownTimeout)*time.Second)
			ctx = tmpCtx
			defer cancel()
		}

		err := servers[i].Shutdown(ctx) // safe shutdown
		if err != nil {
			logrus.WithFields(logrus.Fields{"server_id": i}).WithError(err).Fatal("server shutdown error")
		} else {
			logrus.WithFields(logrus.Fields{"server_id": i}).Info("server shutdown")
		}
	}
}
<commit_msg>fnlb: 0.0.266 release [skip ci]<commit_after>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
	"github.com/sirupsen/logrus"
)

const VERSION = "0.0.266"

func main() {
	// XXX (reed): normalize
	level, err := logrus.ParseLevel(os.Getenv("LOG_LEVEL"))
	if err != nil {
		level = logrus.InfoLevel
	}
	logrus.SetLevel(level)

	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.233", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory; use k8s for kuberneted")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.StringVar(&conf.MgmtListen, "mgmt-listen", ":8081", "management port to run on")
	flag.IntVar(&conf.ShutdownTimeout, "shutdown-timeout", 0, "graceful shutdown timeout")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckHealthy, "hc-healthy", 1, "threshold of success checks to declare node healthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.StringVar(&conf.Namespace, "namespace", "", "kubernetes namespace to monitor")
	flag.StringVar(&conf.LabelSelector, "label-selector", "", "kubernetes label selector to monitor")
	flag.IntVar(&conf.TargetPort, "target-port", 8080, "kubernetes port to target on selected pods")

	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	db, err := lb.NewDB(conf) // Handles case where DBurl == "k8s"
	if err != nil {
		logrus.WithError(err).Fatal("error setting up database")
	}
	defer db.Close()

	g, err := lb.NewAllGrouper(conf, db)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	servers := make([]*http.Server, 0, 1)
	handler := lb.NewProxy(k, g, r, conf)

	// a separate mgmt listener is requested? then let's create a LB traffic only server
	if conf.Listen != conf.MgmtListen {
		servers = append(servers, &http.Server{Addr: conf.Listen, Handler: handler})
		handler = lb.NullHandler()
	}

	// add mgmt endpoints to the handler
	handler = g.Wrap(handler) // add/del/list endpoints
	handler = r.Wrap(handler) // stats / dash endpoint

	servers = append(servers, &http.Server{Addr: conf.MgmtListen, Handler: handler})
	serve(servers, &conf)
}

func serve(servers []*http.Server, conf *lb.Config) {

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)

	for i := 0; i < len(servers); i++ {
		go func(idx int) {
			err := servers[idx].ListenAndServe()
			if err != nil && err != http.ErrServerClosed {
				logrus.WithFields(logrus.Fields{"server_id": idx}).WithError(err).Fatal("server error")
			} else {
				logrus.WithFields(logrus.Fields{"server_id": idx}).Info("server stopped")
			}
		}(i)
	}

	sig := <-ch
	logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")

	for i := 0; i < len(servers); i++ {

		ctx := context.Background()

		if conf.ShutdownTimeout > 0 {
			tmpCtx, cancel := context.WithTimeout(context.Background(), time.Duration(conf.ShutdownTimeout)*time.Second)
			ctx = tmpCtx
			defer cancel()
		}

		err := servers[i].Shutdown(ctx) // safe shutdown
		if err != nil {
			logrus.WithFields(logrus.Fields{"server_id": i}).WithError(err).Fatal("server shutdown error")
		} else {
			logrus.WithFields(logrus.Fields{"server_id": i}).Info("server shutdown")
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
)

const VERSION = "0.0.17"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.3", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<commit_msg>fnlb: 0.0.18 release [skip ci]<commit_after>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
)

const VERSION = "0.0.18"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.4", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
	"github.com/sirupsen/logrus"
)

const VERSION = "0.0.89"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.56", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<commit_msg>fnlb: 0.0.90 release [skip ci]<commit_after>package main

import (
	"context"
	"crypto/tls"
	"flag"
	"net"
	"net/http"
	"os"
	"os/signal"
	"strings"
	"syscall"
	"time"

	"github.com/coreos/go-semver/semver"
	"github.com/fnproject/fn/fnlb/lb"
	"github.com/sirupsen/logrus"
)

const VERSION = "0.0.90"

func main() {
	// XXX (reed): normalize
	fnodes := flag.String("nodes", "", "comma separated list of functions nodes")
	minAPIVersion := flag.String("min-api-version", "0.0.57", "minimal node API to accept")

	var conf lb.Config
	flag.StringVar(&conf.DBurl, "db", "sqlite3://:memory:", "backend to store nodes, default to in memory")
	flag.StringVar(&conf.Listen, "listen", ":8081", "port to run on")
	flag.IntVar(&conf.HealthcheckInterval, "hc-interval", 3, "how often to check f(x) nodes, in seconds")
	flag.StringVar(&conf.HealthcheckEndpoint, "hc-path", "/version", "endpoint to determine node health")
	flag.IntVar(&conf.HealthcheckUnhealthy, "hc-unhealthy", 2, "threshold of failed checks to declare node unhealthy")
	flag.IntVar(&conf.HealthcheckTimeout, "hc-timeout", 5, "timeout of healthcheck endpoint, in seconds")
	flag.StringVar(&conf.ZipkinURL, "zipkin", "", "zipkin endpoint to send traces")
	flag.Parse()

	conf.MinAPIVersion = semver.New(*minAPIVersion)

	if len(*fnodes) > 0 {
		// starting w/o nodes is fine too
		conf.Nodes = strings.Split(*fnodes, ",")
	}

	conf.Transport = &http.Transport{
		Proxy: http.ProxyFromEnvironment,
		Dial: (&net.Dialer{
			Timeout:   10 * time.Second,
			KeepAlive: 120 * time.Second,
		}).Dial,
		MaxIdleConnsPerHost: 512,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig: &tls.Config{
			ClientSessionCache: tls.NewLRUClientSessionCache(4096),
		},
	}

	g, err := lb.NewAllGrouper(conf)
	if err != nil {
		logrus.WithError(err).Fatal("error setting up grouper")
	}

	r := lb.NewConsistentRouter(conf)
	k := func(r *http.Request) (string, error) {
		return r.URL.Path, nil
	}

	h := lb.NewProxy(k, g, r, conf)
	h = g.Wrap(h) // add/del/list endpoints
	h = r.Wrap(h) // stats / dash endpoint

	err = serve(conf.Listen, h)
	if err != nil {
		logrus.WithError(err).Fatal("server error")
	}
}

func serve(addr string, handler http.Handler) error {
	server := &http.Server{Addr: addr, Handler: handler}

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		for sig := range ch {
			logrus.WithFields(logrus.Fields{"signal": sig}).Info("received signal")
			server.Shutdown(context.Background()) // safe shutdown
			return
		}
	}()
	return server.ListenAndServe()
}
<|endoftext|>


<commit_before>package hoverfly

import (
	"fmt"
	"regexp"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/SpectoLabs/hoverfly/core/cache"
	"github.com/SpectoLabs/hoverfly/core/handlers/v1"
	"github.com/SpectoLabs/hoverfly/core/handlers/v2"
	"github.com/SpectoLabs/hoverfly/core/interfaces"
	"github.com/SpectoLabs/hoverfly/core/metrics"
	"github.com/SpectoLabs/hoverfly/core/models"
)

func (this Hoverfly) GetDestination() string {
	return this.Cfg.Destination
}

// UpdateDestination - updates proxy with new destination regexp
func (hf *Hoverfly) SetDestination(destination string) (err error) {
	_, err = regexp.Compile(destination)
	if err != nil {
		return fmt.Errorf("destination is not a valid regular expression string")
	}

	hf.mu.Lock()
	hf.StopProxy()
	hf.Cfg.Destination = destination
	err = hf.StartProxy()
	hf.mu.Unlock()
	return
}

func (this Hoverfly) GetMode() string {
	return this.Cfg.Mode
}

func (this *Hoverfly) SetMode(mode string) error {
	availableModes := map[string]bool{
		"simulate":   true,
		"capture":    true,
		"modify":     true,
		"synthesize": true,
	}

	if mode == "" || !availableModes[mode] {
		log.Error("Can't change mode to \"%d\"", mode)
		return fmt.Errorf("Not a valid mode")
	}

	if this.Cfg.Webserver {
		log.Error("Can't change state when configured as a webserver ")
		return fmt.Errorf("Can't change state when configured as a webserver")
	}
	this.Cfg.SetMode(mode)
	return nil
}

func (hf Hoverfly) GetMiddleware() string {
	return hf.Cfg.Middleware.FullCommand
}

func (hf Hoverfly) SetMiddleware(middleware string) error {
	if middleware == "" {
		hf.Cfg.Middleware.FullCommand = middleware
		return nil
	}
	originalPair := models.RequestResponsePair{
		Request: models.RequestDetails{
			Path:        "/",
			Method:      "GET",
			Destination: "www.test.com",
			Scheme:      "",
			Query:       "",
			Body:        "",
			Headers:     map[string][]string{"test_header": []string{"true"}},
		},
		Response: models.ResponseDetails{
			Status:  200,
			Body:    "ok",
			Headers: map[string][]string{"test_header": []string{"true"}},
		},
	}
	c := NewConstructor(nil, originalPair)

	middlewareObject := &Middleware{
		FullCommand: middleware,
	}

	err := c.ApplyMiddleware(middlewareObject)
	if err != nil {
		return err
	}

	hf.Cfg.Middleware.FullCommand = middleware
	return nil
}

func (hf Hoverfly) GetRequestCacheCount() (int, error) {
	return hf.RequestCache.RecordsCount()
}

func (this Hoverfly) GetMetadataCache() cache.Cache {
	return this.MetadataCache
}

func (hf Hoverfly) DeleteRequestCache() error {
	return hf.RequestCache.DeleteData()
}

func (this Hoverfly) GetTemplates() v1.RequestTemplateResponsePairPayload {
	return this.RequestMatcher.TemplateStore.GetPayload()
}

func (this *Hoverfly) ImportTemplates(pairPayload v1.RequestTemplateResponsePairPayload) error {
	return this.RequestMatcher.TemplateStore.ImportPayloads(pairPayload)
}

func (this *Hoverfly) DeleteTemplateCache() {
	this.RequestMatcher.TemplateStore.Wipe()
}

func (hf *Hoverfly) GetResponseDelays() v1.ResponseDelayPayloadView {
	return hf.ResponseDelays.ConvertToResponseDelayPayloadView()
}

func (hf *Hoverfly) SetResponseDelays(payloadView v1.ResponseDelayPayloadView) error {
	err := models.ValidateResponseDelayPayload(payloadView)
	if err != nil {
		return err
	}

	var responseDelays models.ResponseDelayList

	for _, responseDelayView := range payloadView.Data {
		responseDelays = append(responseDelays, models.ResponseDelay{
			UrlPattern: responseDelayView.UrlPattern,
			HttpMethod: responseDelayView.HttpMethod,
			Delay:      responseDelayView.Delay,
		})
	}

	hf.ResponseDelays = &responseDelays
	return nil
}

func (hf *Hoverfly) DeleteResponseDelays() {
	hf.ResponseDelays = &models.ResponseDelayList{}
}

func (hf Hoverfly) GetStats() metrics.Stats {
	return hf.Counter.Flush()
}

func (hf Hoverfly) GetRecords() ([]v1.RequestResponsePairView, error) {
	records, err := hf.RequestCache.GetAllEntries()
	if err != nil {
		return nil, err
	}

	var pairViews []v1.RequestResponsePairView

	for _, v := range records {
		if pair, err := models.NewRequestResponsePairFromBytes(v); err == nil {
			pairView := pair.ConvertToV1RequestResponsePairView()
			pairViews = append(pairViews, *pairView)
		} else {
			log.Error(err)
			return nil, err
		}
	}

	for _, v := range hf.RequestMatcher.TemplateStore {
		pairView := v.ConvertToV1RequestResponsePairView()
		pairViews = append(pairViews, pairView)
	}

	return pairViews, nil

}

func (hf Hoverfly) GetSimulation() (v2.SimulationView, error) {
	records, err := hf.RequestCache.GetAllEntries()
	if err != nil {
		return v2.SimulationView{}, err
	}

	pairViews := make([]v2.RequestResponsePairView, 0)

	for _, v := range records {
		if pair, err := models.NewRequestResponsePairFromBytes(v); err == nil {
			pairView := pair.ConvertToRequestResponsePairView()
			pairViews = append(pairViews, pairView)
		} else {
			log.Error(err)
			return v2.SimulationView{}, err
		}
	}

	for _, v := range hf.RequestMatcher.TemplateStore {
		pairViews = append(pairViews, v.ConvertToRequestResponsePairView())
	}

	responseDelays := hf.ResponseDelays.ConvertToResponseDelayPayloadView()

	return v2.SimulationView{
		MetaView: v2.MetaView{
			HoverflyVersion: "v0.9.2",
			SchemaVersion:   "v1",
			TimeExported:    time.Now().Format(time.RFC3339),
		},
		DataView: v2.DataView{
			RequestResponsePairs: pairViews,
			GlobalActions: v2.GlobalActionsView{
				Delays: responseDelays.Data,
			},
		},
	}, nil
}

func (this *Hoverfly) PutSimulation(simulationView v2.SimulationView) error {
	requestResponsePairViews := make([]interfaces.RequestResponsePair, len(simulationView.RequestResponsePairs))
	for i, v := range simulationView.RequestResponsePairs {
		requestResponsePairViews[i] = v
	}

	err := this.ImportRequestResponsePairViews(requestResponsePairViews)
	if err != nil {
		return err
	}

	err = this.SetResponseDelays(v1.ResponseDelayPayloadView{Data: simulationView.GlobalActions.Delays})
	if err != nil {
		return err
	}

	return nil
}

func (this *Hoverfly) DeleteSimulation() {
	this.DeleteTemplateCache()
	this.DeleteResponseDelays()
	this.DeleteRequestCache()
}
<commit_msg>Removed constructor from SetMiddleware()<commit_after>package hoverfly

import (
	"fmt"
	"regexp"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/SpectoLabs/hoverfly/core/cache"
	"github.com/SpectoLabs/hoverfly/core/handlers/v1"
	"github.com/SpectoLabs/hoverfly/core/handlers/v2"
	"github.com/SpectoLabs/hoverfly/core/interfaces"
	"github.com/SpectoLabs/hoverfly/core/metrics"
	"github.com/SpectoLabs/hoverfly/core/models"
)

func (this Hoverfly) GetDestination() string {
	return this.Cfg.Destination
}

// UpdateDestination - updates proxy with new destination regexp
func (hf *Hoverfly) SetDestination(destination string) (err error) {
	_, err = regexp.Compile(destination)
	if err != nil {
		return fmt.Errorf("destination is not a valid regular expression string")
	}

	hf.mu.Lock()
	hf.StopProxy()
	hf.Cfg.Destination = destination
	err = hf.StartProxy()
	hf.mu.Unlock()
	return
}

func (this Hoverfly) GetMode() string {
	return this.Cfg.Mode
}

func (this *Hoverfly) SetMode(mode string) error {
	availableModes := map[string]bool{
		"simulate":   true,
		"capture":    true,
		"modify":     true,
		"synthesize": true,
	}

	if mode == "" || !availableModes[mode] {
		log.Error("Can't change mode to \"%d\"", mode)
		return fmt.Errorf("Not a valid mode")
	}

	if this.Cfg.Webserver {
		log.Error("Can't change state when configured as a webserver ")
		return fmt.Errorf("Can't change state when configured as a webserver")
	}
	this.Cfg.SetMode(mode)
	return nil
}

func (hf Hoverfly) GetMiddleware() string {
	return hf.Cfg.Middleware.FullCommand
}

func (hf Hoverfly) SetMiddleware(middleware string) error {
	if middleware == "" {
		hf.Cfg.Middleware.FullCommand = middleware
		return nil
	}
	originalPair := models.RequestResponsePair{
		Request: models.RequestDetails{
			Path:        "/",
			Method:      "GET",
			Destination: "www.test.com",
			Scheme:      "",
			Query:       "",
			Body:        "",
			Headers:     map[string][]string{"test_header": []string{"true"}},
		},
		Response: models.ResponseDetails{
			Status:  200,
			Body:    "ok",
			Headers: map[string][]string{"test_header": []string{"true"}},
		},
	}

	middlewareObject := &Middleware{
		FullCommand: middleware,
	}

	_, err := middlewareObject.executeMiddlewareLocally(originalPair)
	if err != nil {
		return err
	}

	hf.Cfg.Middleware.FullCommand = middleware
	return nil
}

func (hf Hoverfly) GetRequestCacheCount() (int, error) {
	return hf.RequestCache.RecordsCount()
}

func (this Hoverfly) GetMetadataCache() cache.Cache {
	return this.MetadataCache
}

func (hf Hoverfly) DeleteRequestCache() error {
	return hf.RequestCache.DeleteData()
}

func (this Hoverfly) GetTemplates() v1.RequestTemplateResponsePairPayload {
	return this.RequestMatcher.TemplateStore.GetPayload()
}

func (this *Hoverfly) ImportTemplates(pairPayload v1.RequestTemplateResponsePairPayload) error {
	return this.RequestMatcher.TemplateStore.ImportPayloads(pairPayload)
}

func (this *Hoverfly) DeleteTemplateCache() {
	this.RequestMatcher.TemplateStore.Wipe()
}

func (hf *Hoverfly) GetResponseDelays() v1.ResponseDelayPayloadView {
	return hf.ResponseDelays.ConvertToResponseDelayPayloadView()
}

func (hf *Hoverfly) SetResponseDelays(payloadView v1.ResponseDelayPayloadView) error {
	err := models.ValidateResponseDelayPayload(payloadView)
	if err != nil {
		return err
	}

	var responseDelays models.ResponseDelayList

	for _, responseDelayView := range payloadView.Data {
		responseDelays = append(responseDelays, models.ResponseDelay{
			UrlPattern: responseDelayView.UrlPattern,
			HttpMethod: responseDelayView.HttpMethod,
			Delay:      responseDelayView.Delay,
		})
	}

	hf.ResponseDelays = &responseDelays
	return nil
}

func (hf *Hoverfly) DeleteResponseDelays() {
	hf.ResponseDelays = &models.ResponseDelayList{}
}

func (hf Hoverfly) GetStats() metrics.Stats {
	return hf.Counter.Flush()
}

func (hf Hoverfly) GetRecords() ([]v1.RequestResponsePairView, error) {
	records, err := hf.RequestCache.GetAllEntries()
	if err != nil {
		return nil, err
	}

	var pairViews []v1.RequestResponsePairView

	for _, v := range records {
		if pair, err := models.NewRequestResponsePairFromBytes(v); err == nil {
			pairView := pair.ConvertToV1RequestResponsePairView()
			pairViews = append(pairViews, *pairView)
		} else {
			log.Error(err)
			return nil, err
		}
	}

	for _, v := range hf.RequestMatcher.TemplateStore {
		pairView := v.ConvertToV1RequestResponsePairView()
		pairViews = append(pairViews, pairView)
	}

	return pairViews, nil

}

func (hf Hoverfly) GetSimulation() (v2.SimulationView, error) {
	records, err := hf.RequestCache.GetAllEntries()
	if err != nil {
		return v2.SimulationView{}, err
	}

	pairViews := make([]v2.RequestResponsePairView, 0)

	for _, v := range records {
		if pair, err := models.NewRequestResponsePairFromBytes(v); err == nil {
			pairView := pair.ConvertToRequestResponsePairView()
			pairViews = append(pairViews, pairView)
		} else {
			log.Error(err)
			return v2.SimulationView{}, err
		}
	}

	for _, v := range hf.RequestMatcher.TemplateStore {
		pairViews = append(pairViews, v.ConvertToRequestResponsePairView())
	}

	responseDelays := hf.ResponseDelays.ConvertToResponseDelayPayloadView()

	return v2.SimulationView{
		MetaView: v2.MetaView{
			HoverflyVersion: "v0.9.2",
			SchemaVersion:   "v1",
			TimeExported:    time.Now().Format(time.RFC3339),
		},
		DataView: v2.DataView{
			RequestResponsePairs: pairViews,
			GlobalActions: v2.GlobalActionsView{
				Delays: responseDelays.Data,
			},
		},
	}, nil
}

func (this *Hoverfly) PutSimulation(simulationView v2.SimulationView) error {
	requestResponsePairViews := make([]interfaces.RequestResponsePair, len(simulationView.RequestResponsePairs))
	for i, v := range simulationView.RequestResponsePairs {
		requestResponsePairViews[i] = v
	}

	err := this.ImportRequestResponsePairViews(requestResponsePairViews)
	if err != nil {
		return err
	}

	err = this.SetResponseDelays(v1.ResponseDelayPayloadView{Data: simulationView.GlobalActions.Delays})
	if err != nil {
		return err
	}

	return nil
}

func (this *Hoverfly) DeleteSimulation() {
	this.DeleteTemplateCache()
	this.DeleteResponseDelays()
	this.DeleteRequestCache()
}
<|endoftext|>


<commit_before>package qproc

import (
	"github.com/streadway/amqp"
	"log"
)

type Publisher struct {
	*amqp.Channel
}

type PayloadProcessor func(*Publisher, *amqp.Delivery) error

func CreateConsumer(conn *amqp.Connection, exchange, exchangeType, queuePattern, consumer string) (<-chan amqp.Delivery, error) {
	ch, err := CreateChannel(conn, exchange, exchangeType)
	if err != nil {
		return nil, err
	}
	q, err := ch.QueueDeclare("", false, false, false, false, nil)
	if err != nil {
		return nil, err
	}
	log.Printf("queue declared")
	if err = ch.QueueBind(q.Name, queuePattern, exchange, false, nil); err != nil {
		return nil, err
	}
	log.Printf("queue bound")
	devs, err := ch.Consume(q.Name, consumer, false, false, false, false, nil)
	if err != nil {
		return nil, err
	}
	return devs, nil
}

func CreatePublisher(conn *amqp.Connection, exchange, exchangeType string) (*Publisher, error) {
	ch, err := CreateChannel(conn, exchange, exchangeType)
	if err != nil {
		return nil, err
	}
	return &Publisher{ ch }, nil
}

func CreateChannel(conn *amqp.Connection, exchange, exchangeType string) (*amqp.Channel, error) {
	ch, err := conn.Channel()
	if err != nil {
		return nil, err
	}

	log.Printf("channel created")
	if err = ch.ExchangeDeclare(exchange, exchangeType, false, false, false, false, nil); err != nil {
		return nil, err
	}
	log.Printf("exchange declared")
	return ch, nil
}

func ProcessQueue(conn *amqp.Connection, pub *Publisher, exchange, exchangeType, queuePattern, consumer string, errCh chan<- error, qprocessor PayloadProcessor) error {
	devs, err := CreateConsumer(conn, exchange, exchangeType, queuePattern, consumer)
	if err != nil {
		return nil
	}
	go func(devs <-chan amqp.Delivery) {
		for d := range devs {
			err := qprocessor(pub, &d)
			if err != nil {
				errCh <- err
				return
			}
		}
		errCh <- nil
	}(devs)
	return nil
}
<commit_msg>removing some unneeded debug statements<commit_after>package qproc

import (
	"github.com/streadway/amqp"
)

type Publisher struct {
	*amqp.Channel
}

type PayloadProcessor func(*Publisher, *amqp.Delivery) error

func CreateConsumer(conn *amqp.Connection, exchange, exchangeType, queuePattern, consumer string) (<-chan amqp.Delivery, error) {
	ch, err := CreateChannel(conn, exchange, exchangeType)
	if err != nil {
		return nil, err
	}
	q, err := ch.QueueDeclare("", false, false, false, false, nil)
	if err != nil {
		return nil, err
	}
	if err = ch.QueueBind(q.Name, queuePattern, exchange, false, nil); err != nil {
		return nil, err
	}
	devs, err := ch.Consume(q.Name, consumer, false, false, false, false, nil)
	if err != nil {
		return nil, err
	}
	return devs, nil
}

func CreatePublisher(conn *amqp.Connection, exchange, exchangeType string) (*Publisher, error) {
	ch, err := CreateChannel(conn, exchange, exchangeType)
	if err != nil {
		return nil, err
	}
	return &Publisher{ ch }, nil
}

func CreateChannel(conn *amqp.Connection, exchange, exchangeType string) (*amqp.Channel, error) {
	ch, err := conn.Channel()
	if err != nil {
		return nil, err
	}

	if err = ch.ExchangeDeclare(exchange, exchangeType, false, false, false, false, nil); err != nil {
		return nil, err
	}
	return ch, nil
}

func ProcessQueue(conn *amqp.Connection, pub *Publisher, exchange, exchangeType, queuePattern, consumer string, errCh chan<- error, qprocessor PayloadProcessor) error {
	devs, err := CreateConsumer(conn, exchange, exchangeType, queuePattern, consumer)
	if err != nil {
		return nil
	}
	go func(devs <-chan amqp.Delivery) {
		for d := range devs {
			err := qprocessor(pub, &d)
			if err != nil {
				errCh <- err
				return
			}
		}
		errCh <- nil
	}(devs)
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2016 Hajime Hoshi
//
// 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 loop

import (
	"errors"
	"time"

	"github.com/hajimehoshi/ebiten/audio"
	"github.com/hajimehoshi/ebiten/internal/sync"
	"github.com/hajimehoshi/ebiten/internal/ui"
)

func CurrentFPS() float64 {
	return currentRunContext.getCurrentFPS()
}

type runContext struct {
	running        bool
	fps            int
	currentFPS     float64
	runningSlowly  bool
	frames         int64
	lastUpdated    int64
	lastFPSUpdated int64
	m              sync.RWMutex

	lastAudioFrame     int64
	lastAudioFrameTime int64
	deltaTime          int64
}

var currentRunContext *runContext

func (c *runContext) startRunning() {
	c.m.Lock()
	defer c.m.Unlock()
	c.running = true
}

func (c *runContext) isRunning() bool {
	c.m.RLock()
	defer c.m.RUnlock()
	return c.running
}

func (c *runContext) endRunning() {
	c.m.Lock()
	defer c.m.Unlock()
	c.running = false
}

func (c *runContext) getCurrentFPS() float64 {
	c.m.RLock()
	defer c.m.RUnlock()
	if !c.running {
		// TODO: Should panic here?
		return 0
	}
	return c.currentFPS
}

func (c *runContext) updateFPS(fps float64) {
	c.m.Lock()
	defer c.m.Unlock()
	c.currentFPS = fps
}

type GraphicsContext interface {
	SetSize(width, height int, scale float64)
	UpdateAndDraw(updateCount int) error
	Invalidate()
}

type loopGraphicsContext struct {
	runContext      *runContext
	graphicsContext GraphicsContext
}

func (g *loopGraphicsContext) SetSize(width, height int, scale float64) {
	g.graphicsContext.SetSize(width, height, scale)
}

func (g *loopGraphicsContext) Update() error {
	return g.runContext.render(g.graphicsContext)
}

func (g *loopGraphicsContext) Invalidate() {
	g.graphicsContext.Invalidate()
}

func Run(g GraphicsContext, width, height int, scale float64, title string, fps int) (err error) {
	if currentRunContext != nil {
		return errors.New("loop: The game is already running")
	}
	currentRunContext = &runContext{
		fps: fps,
	}
	currentRunContext.startRunning()
	defer currentRunContext.endRunning()

	n := currentRunContext.adjustedNowWithAudio()
	currentRunContext.lastUpdated = n
	currentRunContext.lastFPSUpdated = n

	lg := &loopGraphicsContext{currentRunContext, g}
	if err := ui.Run(width, height, scale, title, lg); err != nil {
		if _, ok := err.(*ui.RegularTermination); ok {
			return nil
		}
		return err
	}
	return nil
}

func (c *runContext) adjustedNowWithAudio() int64 {
	n := now()
	if audio.CurrentContext() == nil {
		return n
	}
	if c.lastAudioFrameTime == 0 {
		c.lastAudioFrameTime = n
	}
	if f := audio.CurrentContext().Frame(); c.lastAudioFrame != f {
		an := c.lastAudioFrameTime + (f-c.lastAudioFrame)*int64(time.Second)/audio.FPS
		c.deltaTime += an - n
		c.lastAudioFrame = f
		c.lastAudioFrameTime = n
	}
	return n + c.deltaTime
}

func (c *runContext) render(g GraphicsContext) error {
	fps := c.fps
	n := c.adjustedNowWithAudio()
	defer func() {
		// Calc the current FPS.
		if time.Second > time.Duration(n-c.lastFPSUpdated) {
			return
		}
		currentFPS := float64(c.frames) * float64(time.Second) / float64(n-c.lastFPSUpdated)
		c.updateFPS(currentFPS)
		c.lastFPSUpdated = n
		c.frames = 0
	}()

	// If lastUpdated is too old, we assume that screen is not shown.
	if 10*int64(time.Second)/int64(fps) < n-c.lastUpdated {
		c.lastUpdated = n
		return nil
	}
	if audio.CurrentContext() != nil {
		audio.CurrentContext().Ping()
	}

	// Note that generally t is a little different from 1/60[sec].
	t := n - c.lastUpdated
	tt := int(t * int64(fps) / int64(time.Second))

	// As t is not accurate 1/60[sec], errors are accumulated.
	// To make the FPS stable, set tt 1 if t is a little less than 1/60[sec].
	if tt == 0 && (int64(time.Second)/int64(fps)-int64(5*time.Millisecond)) < t {
		tt = 1
	}
	if err := g.UpdateAndDraw(tt); err != nil {
		return err
	}
	c.lastUpdated += int64(tt) * int64(time.Second) / int64(fps)
	c.frames++
	return nil
}
<commit_msg>loop: Early exit when no frame needs to be updated<commit_after>// Copyright 2016 Hajime Hoshi
//
// 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 loop

import (
	"errors"
	"time"

	"github.com/hajimehoshi/ebiten/audio"
	"github.com/hajimehoshi/ebiten/internal/sync"
	"github.com/hajimehoshi/ebiten/internal/ui"
)

func CurrentFPS() float64 {
	return currentRunContext.getCurrentFPS()
}

type runContext struct {
	running        bool
	fps            int
	currentFPS     float64
	runningSlowly  bool
	frames         int64
	lastUpdated    int64
	lastFPSUpdated int64
	m              sync.RWMutex

	lastAudioFrame     int64
	lastAudioFrameTime int64
	deltaTime          int64
}

var currentRunContext *runContext

func (c *runContext) startRunning() {
	c.m.Lock()
	defer c.m.Unlock()
	c.running = true
}

func (c *runContext) isRunning() bool {
	c.m.RLock()
	defer c.m.RUnlock()
	return c.running
}

func (c *runContext) endRunning() {
	c.m.Lock()
	defer c.m.Unlock()
	c.running = false
}

func (c *runContext) getCurrentFPS() float64 {
	c.m.RLock()
	defer c.m.RUnlock()
	if !c.running {
		// TODO: Should panic here?
		return 0
	}
	return c.currentFPS
}

func (c *runContext) updateFPS(fps float64) {
	c.m.Lock()
	defer c.m.Unlock()
	c.currentFPS = fps
}

type GraphicsContext interface {
	SetSize(width, height int, scale float64)
	UpdateAndDraw(updateCount int) error
	Invalidate()
}

type loopGraphicsContext struct {
	runContext      *runContext
	graphicsContext GraphicsContext
}

func (g *loopGraphicsContext) SetSize(width, height int, scale float64) {
	g.graphicsContext.SetSize(width, height, scale)
}

func (g *loopGraphicsContext) Update() error {
	return g.runContext.render(g.graphicsContext)
}

func (g *loopGraphicsContext) Invalidate() {
	g.graphicsContext.Invalidate()
}

func Run(g GraphicsContext, width, height int, scale float64, title string, fps int) (err error) {
	if currentRunContext != nil {
		return errors.New("loop: The game is already running")
	}
	currentRunContext = &runContext{
		fps: fps,
	}
	currentRunContext.startRunning()
	defer currentRunContext.endRunning()

	n := currentRunContext.adjustedNowWithAudio()
	currentRunContext.lastUpdated = n
	currentRunContext.lastFPSUpdated = n

	lg := &loopGraphicsContext{currentRunContext, g}
	if err := ui.Run(width, height, scale, title, lg); err != nil {
		if _, ok := err.(*ui.RegularTermination); ok {
			return nil
		}
		return err
	}
	return nil
}

func (c *runContext) adjustedNowWithAudio() int64 {
	n := now()
	if audio.CurrentContext() == nil {
		return n
	}
	if c.lastAudioFrameTime == 0 {
		c.lastAudioFrameTime = n
	}
	if f := audio.CurrentContext().Frame(); c.lastAudioFrame != f {
		an := c.lastAudioFrameTime + (f-c.lastAudioFrame)*int64(time.Second)/audio.FPS
		c.deltaTime += an - n
		c.lastAudioFrame = f
		c.lastAudioFrameTime = n
	}
	return n + c.deltaTime
}

func (c *runContext) render(g GraphicsContext) error {
	fps := c.fps
	n := c.adjustedNowWithAudio()
	defer func() {
		// Calc the current FPS.
		if time.Second > time.Duration(n-c.lastFPSUpdated) {
			return
		}
		currentFPS := float64(c.frames) * float64(time.Second) / float64(n-c.lastFPSUpdated)
		c.updateFPS(currentFPS)
		c.lastFPSUpdated = n
		c.frames = 0
	}()

	// If lastUpdated is too old, we assume that screen is not shown.
	if 10*int64(time.Second)/int64(fps) < n-c.lastUpdated {
		c.lastUpdated = n
		return nil
	}
	if audio.CurrentContext() != nil {
		audio.CurrentContext().Ping()
	}

	// Note that generally t is a little different from 1/60[sec].
	t := n - c.lastUpdated
	if t < 0 {
		return nil
	}
	tt := int(t * int64(fps) / int64(time.Second))

	// As t is not accurate 1/60[sec], errors are accumulated.
	// To make the FPS stable, set tt 1 if t is a little less than 1/60[sec].
	// TODO: Better stabilizing way for FPS
	if tt == 0 && (int64(time.Second)/int64(fps)-int64(5*time.Millisecond)) < t {
		tt = 1
	}
	if err := g.UpdateAndDraw(tt); err != nil {
		return err
	}
	c.lastUpdated += int64(tt) * int64(time.Second) / int64(fps)
	c.frames++
	return nil
}
<|endoftext|>


<commit_before>package slab

import (
	"testing"
)

func TestBasics(t *testing.T) {
	s := SynchronizedArena(NewSlabArena(1, 1024, 2))
	if s == nil {
		t.Errorf("expected new slab arena to work")
	}
	a := s.Alloc(1)
	if a == nil {
		t.Errorf("expected alloc to work")
	}
	if len(a) != 1 {
		t.Errorf("expected alloc to give right size buf")
	}
	if cap(a) != 1 + SLAB_MEMORY_FOOTER_LEN {
		t.Errorf("expected alloc cap to match algorithm, got: %v vs %v",
			cap(a), 1 + SLAB_MEMORY_FOOTER_LEN)
	}
	a[0] = 66
	s.DecRef(a)
	b := s.Alloc(1)
	if b == nil {
		t.Errorf("expected alloc to work")
	}
	if len(b) != 1 {
		t.Errorf("expected alloc to give right size buf")
	}
	if cap(b) != 1 + SLAB_MEMORY_FOOTER_LEN {
		t.Errorf("expected alloc cap to match algorithm, got: %v vs %v",
			cap(b), 1 + SLAB_MEMORY_FOOTER_LEN)
	}
	if b[0] != 66 {
		t.Errorf("expected alloc to return last freed buf")
	}
}

func TestSlabClassGrowth(t *testing.T) {
	s := NewSlabArena(1, 8, 2).(*slabArena)
	expectSlabClasses := func(numSlabClasses int) {
		if len(s.slabClasses) != numSlabClasses {
			t.Errorf("expected %v slab classses, got: %v",
				numSlabClasses, len(s.slabClasses))
		}
	}
	expectSlabClasses(1)
	s.Alloc(1)
	expectSlabClasses(1)
	s.Alloc(1)
	expectSlabClasses(1)
	s.Alloc(2)
	expectSlabClasses(2)
	s.Alloc(1)
	s.Alloc(2)
	expectSlabClasses(2)
	s.Alloc(3)
	s.Alloc(4)
	expectSlabClasses(3)
	s.Alloc(5)
	s.Alloc(8)
	expectSlabClasses(4)
}<commit_msg>TestDecRef().<commit_after>package slab

import (
	"testing"
)

func TestBasics(t *testing.T) {
	s := SynchronizedArena(NewSlabArena(1, 1024, 2))
	if s == nil {
		t.Errorf("expected new slab arena to work")
	}
	a := s.Alloc(1)
	if a == nil {
		t.Errorf("expected alloc to work")
	}
	if len(a) != 1 {
		t.Errorf("expected alloc to give right size buf")
	}
	if cap(a) != 1 + SLAB_MEMORY_FOOTER_LEN {
		t.Errorf("expected alloc cap to match algorithm, got: %v vs %v",
			cap(a), 1 + SLAB_MEMORY_FOOTER_LEN)
	}
	a[0] = 66
	s.DecRef(a)
	b := s.Alloc(1)
	if b == nil {
		t.Errorf("expected alloc to work")
	}
	if len(b) != 1 {
		t.Errorf("expected alloc to give right size buf")
	}
	if cap(b) != 1 + SLAB_MEMORY_FOOTER_LEN {
		t.Errorf("expected alloc cap to match algorithm, got: %v vs %v",
			cap(b), 1 + SLAB_MEMORY_FOOTER_LEN)
	}
	if b[0] != 66 {
		t.Errorf("expected alloc to return last freed buf")
	}
}

func TestSlabClassGrowth(t *testing.T) {
	s := NewSlabArena(1, 8, 2).(*slabArena)
	expectSlabClasses := func(numSlabClasses int) {
		if len(s.slabClasses) != numSlabClasses {
			t.Errorf("expected %v slab classses, got: %v",
				numSlabClasses, len(s.slabClasses))
		}
	}
	expectSlabClasses(1)
	s.Alloc(1)
	expectSlabClasses(1)
	s.Alloc(1)
	expectSlabClasses(1)
	s.Alloc(2)
	expectSlabClasses(2)
	s.Alloc(1)
	s.Alloc(2)
	expectSlabClasses(2)
	s.Alloc(3)
	s.Alloc(4)
	expectSlabClasses(3)
	s.Alloc(5)
	s.Alloc(8)
	expectSlabClasses(4)
}

func TestDecRef(t *testing.T) {
	s := NewSlabArena(1, 8, 2).(*slabArena)
	expectSlabClasses := func(numSlabClasses int) {
		if len(s.slabClasses) != numSlabClasses {
			t.Errorf("expected %v slab classses, got: %v",
				numSlabClasses, len(s.slabClasses))
		}
	}
	a := make([][]byte, 128)
	for j := 0; j < 100; j++ {
		for i := 0; i < len(a); i++ {
			a[i] = s.Alloc(i % 8)
		}
		for i := 0; i < len(a); i++ {
			s.DecRef(a[i])
		}
	}
	expectSlabClasses(4)
}
<|endoftext|>


<commit_before>// Copyright 2016 The Gosl 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 h5

import (
	"testing"

	"github.com/cpmech/gosl/chk"
)

func TestData01(tst *testing.T) {

	//verbose()
	chk.PrintTitle("Data01. Reading data exported from Matlab")

	dat := Open("./data", "hdf5_sample_from_matlab_online.h5", false)
	M := dat.GetDeep2("/M")
	chk.Deep2(tst, "M", 1e-15, M, [][]float64{
		{1, 2, 3},
		{4, 5, 6},
		{7, 8, 9},
	})
	v := dat.GetArray("/v")
	chk.Array(tst, "v", 1e-15, v, []float64{1, 2, 3})
	w := dat.GetArray("/w")
	chk.Array(tst, "w", 1e-15, w, []float64{14, 32, 50})
}
<commit_msg>Close datafile in h5 test<commit_after>// Copyright 2016 The Gosl 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 h5

import (
	"testing"

	"github.com/cpmech/gosl/chk"
)

func TestData01(tst *testing.T) {

	//verbose()
	chk.PrintTitle("Data01. Reading data exported from Matlab")

	dat := Open("./data", "hdf5_sample_from_matlab_online.h5", false)
	defer dat.Close()
	M := dat.GetDeep2("/M")
	chk.Deep2(tst, "M", 1e-15, M, [][]float64{
		{1, 2, 3},
		{4, 5, 6},
		{7, 8, 9},
	})
	v := dat.GetArray("/v")
	chk.Array(tst, "v", 1e-15, v, []float64{1, 2, 3})
	w := dat.GetArray("/w")
	chk.Array(tst, "w", 1e-15, w, []float64{14, 32, 50})
}
<|endoftext|>


<commit_before>package ioengine

type event struct {
	callback func()
	payload interface{}
}

type IOEngine struct {
	on bool
}

func (self IOEngine) loop() bool {
	if self.on {
		event <- self.queue
		go event.callback(event.payload)
		go self.IOEngine.loop()

		return true
	}

	return false
}

func (self *IOEngine) Stop() {
	self.on = false
}

func (self *IOEngine) Start() {
	self.on = true
	go self.loop()
}

func (self IOEngine) Status() bool {
	return self.on
}
<commit_msg>channel chan<commit_after>package ioengine

type event struct {
	callback func()
	payload interface{}
}

type IOEngine struct {
	on bool
	channel chan
}

func (self IOEngine) loop() bool {
	if self.on {
		event <- self.queue
		go event.callback(event.payload)
		go self.IOEngine.loop()

		return true
	}

	return false
}

func (self *IOEngine) Stop() {
	self.on = false
}

func (self *IOEngine) Start() {
	self.on = true
	go self.loop()
}

func (self IOEngine) Status() bool {
	return self.on
}
<|endoftext|>