<commit_before>package moduledeps

import (
	"sort"
	"strings"

	"github.com/hashicorp/terraform/plugin/discovery"
)

// Module represents the dependencies of a single module, as well being
// a node in a tree of such structures representing the dependencies of
// an entire configuration.
type Module struct {
	Name      string
	Providers Providers
	Children  []*Module
}

// WalkFunc is a callback type for use with Module.WalkTree
type WalkFunc func(path []string, parent *Module, current *Module) error

// WalkTree calls the given callback once for the receiver and then
// once for each descendent, in an order such that parents are called
// before their children and siblings are called in the order they
// appear in the Children slice.
//
// When calling the callback, parent will be nil for the first call
// for the receiving module, and then set to the direct parent of
// each module for the subsequent calls.
//
// The path given to the callback is valid only until the callback
// returns, after which it will be mutated and reused. Callbacks must
// therefore copy the path slice if they wish to retain it.
//
// If the given callback returns an error, the walk will be aborted at
// that point and that error returned to the caller.
//
// This function is not thread-safe for concurrent modifications of the
// data structure, so it's the caller's responsibility to arrange for that
// should it be needed.
//
// It is safe for a callback to modify the descendents of the "current"
// module, including the ordering of the Children slice itself, but the
// callback MUST NOT modify the parent module.
func (m *Module) WalkTree(cb WalkFunc) error {
	return walkModuleTree(make([]string, 0, 1), nil, m, cb)
}

func walkModuleTree(path []string, parent *Module, current *Module, cb WalkFunc) error {
	path = append(path, current.Name)
	err := cb(path, parent, current)
	if err != nil {
		return err
	}

	for _, child := range current.Children {
		err := walkModuleTree(path, current, child, cb)
		if err != nil {
			return err
		}
	}
	return nil
}

// SortChildren sorts the Children slice into lexicographic order by
// name, in-place.
//
// This is primarily useful prior to calling WalkTree so that the walk
// will proceed in a consistent order.
func (m *Module) SortChildren() {
	sort.Sort(sortModules{m.Children})
}

// SortDescendents is a convenience wrapper for calling SortChildren on
// the receiver and all of its descendent modules.
func (m *Module) SortDescendents() {
	m.WalkTree(func(path []string, parent *Module, current *Module) error {
		current.SortChildren()
		return nil
	})
}

type sortModules struct {
	modules []*Module
}

func (s sortModules) Len() int {
	return len(s.modules)
}

func (s sortModules) Less(i, j int) bool {
	cmp := strings.Compare(s.modules[i].Name, s.modules[j].Name)
	return cmp < 0
}

func (s sortModules) Swap(i, j int) {
	s.modules[i], s.modules[j] = s.modules[j], s.modules[i]
}

// PluginRequirements produces a PluginRequirements structure that can
// be used with discovery.PluginMetaSet.ConstrainVersions to identify
// suitable plugins to satisfy the module's provider dependencies.
//
// This method only considers the direct requirements of the receiver.
// Use AllPluginRequirements to flatten the dependencies for the
// entire tree of modules.
func (m *Module) PluginRequirements() discovery.PluginRequirements {
	ret := make(discovery.PluginRequirements)
	for inst, dep := range m.Providers {
		// m.Providers is keyed on provider names, such as "aws.foo".
		// a PluginRequirements wants keys to be provider *types*, such
		// as "aws". If there are multiple aliases for the same
		// provider then we will flatten them into a single requirement
		// by using Intersection to merge the version sets.
		pty := inst.Type()
		if existing, exists := ret[pty]; exists {
			ret[pty] = existing.Intersection(dep.Versions)
		} else {
			ret[pty] = dep.Versions
		}
	}
	return ret
}

// AllPluginRequirements calls PluginRequirements for the receiver and all
// of its descendents, and merges the result into a single PluginRequirements
// structure that would satisfy all of the modules together.
func (m *Module) AllPluginRequirements() discovery.PluginRequirements {
	var ret discovery.PluginRequirements
	m.WalkTree(func(path []string, parent *Module, current *Module) error {
		ret = ret.Merge(current.PluginRequirements())
		return nil
	})
	return ret
}
<commit_msg>moduledeps: Module.Equals<commit_after>package moduledeps

import (
	"sort"
	"strings"

	"github.com/hashicorp/terraform/plugin/discovery"
)

// Module represents the dependencies of a single module, as well being
// a node in a tree of such structures representing the dependencies of
// an entire configuration.
type Module struct {
	Name      string
	Providers Providers
	Children  []*Module
}

// WalkFunc is a callback type for use with Module.WalkTree
type WalkFunc func(path []string, parent *Module, current *Module) error

// WalkTree calls the given callback once for the receiver and then
// once for each descendent, in an order such that parents are called
// before their children and siblings are called in the order they
// appear in the Children slice.
//
// When calling the callback, parent will be nil for the first call
// for the receiving module, and then set to the direct parent of
// each module for the subsequent calls.
//
// The path given to the callback is valid only until the callback
// returns, after which it will be mutated and reused. Callbacks must
// therefore copy the path slice if they wish to retain it.
//
// If the given callback returns an error, the walk will be aborted at
// that point and that error returned to the caller.
//
// This function is not thread-safe for concurrent modifications of the
// data structure, so it's the caller's responsibility to arrange for that
// should it be needed.
//
// It is safe for a callback to modify the descendents of the "current"
// module, including the ordering of the Children slice itself, but the
// callback MUST NOT modify the parent module.
func (m *Module) WalkTree(cb WalkFunc) error {
	return walkModuleTree(make([]string, 0, 1), nil, m, cb)
}

func walkModuleTree(path []string, parent *Module, current *Module, cb WalkFunc) error {
	path = append(path, current.Name)
	err := cb(path, parent, current)
	if err != nil {
		return err
	}

	for _, child := range current.Children {
		err := walkModuleTree(path, current, child, cb)
		if err != nil {
			return err
		}
	}
	return nil
}

// SortChildren sorts the Children slice into lexicographic order by
// name, in-place.
//
// This is primarily useful prior to calling WalkTree so that the walk
// will proceed in a consistent order.
func (m *Module) SortChildren() {
	sort.Sort(sortModules{m.Children})
}

// SortDescendents is a convenience wrapper for calling SortChildren on
// the receiver and all of its descendent modules.
func (m *Module) SortDescendents() {
	m.WalkTree(func(path []string, parent *Module, current *Module) error {
		current.SortChildren()
		return nil
	})
}

type sortModules struct {
	modules []*Module
}

func (s sortModules) Len() int {
	return len(s.modules)
}

func (s sortModules) Less(i, j int) bool {
	cmp := strings.Compare(s.modules[i].Name, s.modules[j].Name)
	return cmp < 0
}

func (s sortModules) Swap(i, j int) {
	s.modules[i], s.modules[j] = s.modules[j], s.modules[i]
}

// PluginRequirements produces a PluginRequirements structure that can
// be used with discovery.PluginMetaSet.ConstrainVersions to identify
// suitable plugins to satisfy the module's provider dependencies.
//
// This method only considers the direct requirements of the receiver.
// Use AllPluginRequirements to flatten the dependencies for the
// entire tree of modules.
func (m *Module) PluginRequirements() discovery.PluginRequirements {
	ret := make(discovery.PluginRequirements)
	for inst, dep := range m.Providers {
		// m.Providers is keyed on provider names, such as "aws.foo".
		// a PluginRequirements wants keys to be provider *types*, such
		// as "aws". If there are multiple aliases for the same
		// provider then we will flatten them into a single requirement
		// by using Intersection to merge the version sets.
		pty := inst.Type()
		if existing, exists := ret[pty]; exists {
			ret[pty] = existing.Intersection(dep.Versions)
		} else {
			ret[pty] = dep.Versions
		}
	}
	return ret
}

// AllPluginRequirements calls PluginRequirements for the receiver and all
// of its descendents, and merges the result into a single PluginRequirements
// structure that would satisfy all of the modules together.
func (m *Module) AllPluginRequirements() discovery.PluginRequirements {
	var ret discovery.PluginRequirements
	m.WalkTree(func(path []string, parent *Module, current *Module) error {
		ret = ret.Merge(current.PluginRequirements())
		return nil
	})
	return ret
}

// Equal returns true if the receiver is the root of an identical tree
// to the other given Module. This is a deep comparison that considers
// the equality of all downstream modules too.
//
// The children are considered to be ordered, so callers may wish to use
// SortDescendents first to normalize the order of the slices of child nodes.
//
// The implementation of this function is not optimized since it is provided
// primarily for use in tests.
func (m *Module) Equal(other *Module) bool {
	// take care of nils first
	if m == nil && other == nil {
		return true
	} else if (m == nil && other != nil) || (m != nil && other == nil) {
		return false
	}

	if m.Name != other.Name {
		return false
	}

	if len(m.Providers) != len(other.Providers) {
		return false
	}
	if len(m.Children) != len(other.Children) {
		return false
	}

	// Can't use reflect.DeepEqual on this provider structure because
	// the nested VersionSet objects contain function pointers that
	// never compare as equal. So we'll need to walk it the long way.
	for inst, dep := range m.Providers {
		if _, exists := other.Providers[inst]; !exists {
			return false
		}

		if dep.Reason != other.Providers[inst].Reason {
			return false
		}

		// VersionSets are not too easy to compare robustly, so
		// we'll just use their string representations as a proxy
		// for now.
		if dep.Versions.String() != other.Providers[inst].Versions.String() {
			return false
		}
	}

	// Above we already checked that we have the same number of children
	// in each module, so now we just need to check that they are
	// recursively equal.
	for i := range m.Children {
		if !m.Children[i].Equal(other.Children[i]) {
			return false
		}
	}

	// If we fall out here then they are equal
	return true
}
<|endoftext|>


<commit_before>
package libkbgo

/*
 * Interfaces
 *
 *   Here are the interfaces that we're going to assume when
 *   implementing the features of command-line clients or
 *   servers.  Depending on the conext, we might get different
 *   instantiations of these interfaces.
 */

type CommandLine interface {

}

type Server interface {

}

type LocalCache interface {

}

type Config interface {

}

type HttpRequest interface {

}

type Keychain interface {

}

type ProofCheckers interface {

}

type Logger interface {

}<commit_msg>nothing<commit_after>
package libkbgo

/*
 * Interfaces
 *
 *   Here are the interfaces that we're going to assume when
 *   implementing the features of command-line clients or
 *   servers.  Depending on the conext, we might get different
 *   instantiations of these interfaces.
 */

type CommandLine interface {

}

type Server interface {

}

type LocalCache interface {

}

type Config interface {

}

type HttpRequest interface {

}

type Keychain interface {

}

type ProofCheckers interface {

}

type Logger interface {

}<|endoftext|>


<commit_before>package net

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"os"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/cloudfoundry/cli/cf"
	"github.com/cloudfoundry/cli/cf/configuration/coreconfig"
	"github.com/cloudfoundry/cli/cf/errors"
	. "github.com/cloudfoundry/cli/cf/i18n"
	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/cloudfoundry/cli/cf/trace"
)

const (
	JobFinished            = "finished"
	JobFailed              = "failed"
	DefaultPollingThrottle = 5 * time.Second
	DefaultDialTimeout     = 5 * time.Second
)

type JobResource struct {
	Entity struct {
		Status       string
		ErrorDetails struct {
			Description string
		} `json:"error_details"`
	}
}

type AsyncResource struct {
	Metadata struct {
		URL string
	}
}

type apiErrorHandler func(statusCode int, body []byte) error

type tokenRefresher interface {
	RefreshAuthToken() (string, error)
}

type Request struct {
	HTTPReq      *http.Request
	SeekableBody io.ReadSeeker
}

type Gateway struct {
	authenticator   tokenRefresher
	errHandler      apiErrorHandler
	PollingEnabled  bool
	PollingThrottle time.Duration
	trustedCerts    []tls.Certificate
	config          coreconfig.Reader
	warnings        *[]string
	Clock           func() time.Time
	transport       *http.Transport
	ui              terminal.UI
	logger          trace.Printer
	DialTimeout     time.Duration
}

func (gateway *Gateway) AsyncTimeout() time.Duration {
	if gateway.config.AsyncTimeout() > 0 {
		return time.Duration(gateway.config.AsyncTimeout()) * time.Minute
	}

	return 0
}

func (gateway *Gateway) SetTokenRefresher(auth tokenRefresher) {
	gateway.authenticator = auth
}

func (gateway Gateway) GetResource(url string, resource interface{}) (err error) {
	request, err := gateway.NewRequest("GET", url, gateway.config.AccessToken(), nil)
	if err != nil {
		return
	}

	_, err = gateway.PerformRequestForJSONResponse(request, resource)
	return
}

func (gateway Gateway) CreateResourceFromStruct(endpoint, url string, resource interface{}) error {
	data, err := json.Marshal(resource)
	if err != nil {
		return err
	}

	return gateway.CreateResource(endpoint, url, bytes.NewReader(data))
}

func (gateway Gateway) UpdateResourceFromStruct(endpoint, apiURL string, resource interface{}) error {
	data, err := json.Marshal(resource)
	if err != nil {
		return err
	}

	return gateway.UpdateResource(endpoint, apiURL, bytes.NewReader(data))
}

func (gateway Gateway) CreateResource(endpoint, apiURL string, body io.ReadSeeker, resource ...interface{}) error {
	return gateway.createUpdateOrDeleteResource("POST", endpoint, apiURL, body, false, resource...)
}

func (gateway Gateway) UpdateResource(endpoint, apiURL string, body io.ReadSeeker, resource ...interface{}) error {
	return gateway.createUpdateOrDeleteResource("PUT", endpoint, apiURL, body, false, resource...)
}

func (gateway Gateway) UpdateResourceSync(endpoint, apiURL string, body io.ReadSeeker, resource ...interface{}) error {
	return gateway.createUpdateOrDeleteResource("PUT", endpoint, apiURL, body, true, resource...)
}

func (gateway Gateway) DeleteResourceSynchronously(endpoint, apiURL string) error {
	return gateway.createUpdateOrDeleteResource("DELETE", endpoint, apiURL, nil, true, &AsyncResource{})
}

func (gateway Gateway) DeleteResource(endpoint, apiURL string) error {
	return gateway.createUpdateOrDeleteResource("DELETE", endpoint, apiURL, nil, false, &AsyncResource{})
}

func (gateway Gateway) ListPaginatedResources(
	target string,
	path string,
	resource interface{},
	cb func(interface{}) bool,
) error {
	for path != "" {
		pagination := NewPaginatedResources(resource)

		apiErr := gateway.GetResource(fmt.Sprintf("%s%s", target, path), &pagination)
		if apiErr != nil {
			return apiErr
		}

		resources, err := pagination.Resources()
		if err != nil {
			return fmt.Errorf("%s: %s", T("Error parsing JSON"), err.Error())
		}

		for _, resource := range resources {
			if !cb(resource) {
				return nil
			}
		}

		path = pagination.NextURL
	}

	return nil
}

func (gateway Gateway) createUpdateOrDeleteResource(verb, endpoint, apiURL string, body io.ReadSeeker, sync bool, optionalResource ...interface{}) error {
	var resource interface{}
	if len(optionalResource) > 0 {
		resource = optionalResource[0]
	}

	request, err := gateway.NewRequest(verb, endpoint+apiURL, gateway.config.AccessToken(), body)
	if err != nil {
		return err
	}

	if resource == nil {
		_, err = gateway.PerformRequest(request)
		return err
	}

	if gateway.PollingEnabled && !sync {
		_, err = gateway.PerformPollingRequestForJSONResponse(endpoint, request, resource, gateway.AsyncTimeout())
		return err
	}

	_, err = gateway.PerformRequestForJSONResponse(request, resource)
	if err != nil {
		return err
	}

	return nil
}

func (gateway Gateway) newRequest(request *http.Request, accessToken string, body io.ReadSeeker) *Request {
	if accessToken != "" {
		request.Header.Set("Authorization", accessToken)
	}

	request.Header.Set("accept", "application/json")
	request.Header.Set("content-type", "application/json")
	request.Header.Set("User-Agent", "go-cli "+cf.Version+" / "+runtime.GOOS)

	return &Request{HTTPReq: request, SeekableBody: body}
}

func (gateway Gateway) NewRequestForFile(method, fullURL, accessToken string, body *os.File) (*Request, error) {
	progressReader := NewProgressReader(body, gateway.ui, 5*time.Second)
	_, _ = progressReader.Seek(0, 0)

	fileStats, err := body.Stat()
	if err != nil {
		return nil, fmt.Errorf("%s: %s", T("Error getting file info"), err.Error())
	}

	request, err := http.NewRequest(method, fullURL, progressReader)
	if err != nil {
		return nil, fmt.Errorf("%s: %s", T("Error building request"), err.Error())
	}

	fileSize := fileStats.Size()
	progressReader.SetTotalSize(fileSize)
	request.ContentLength = fileSize

	if err != nil {
		return nil, fmt.Errorf("%s: %s", T("Error building request"), err.Error())
	}

	return gateway.newRequest(request, accessToken, progressReader), nil
}

func (gateway Gateway) NewRequest(method, path, accessToken string, body io.ReadSeeker) (*Request, error) {
	request, err := http.NewRequest(method, path, body)
	if err != nil {
		return nil, fmt.Errorf("%s: %s", T("Error building request"), err.Error())
	}
	return gateway.newRequest(request, accessToken, body), nil
}

func (gateway Gateway) PerformRequest(request *Request) (*http.Response, error) {
	return gateway.doRequestHandlingAuth(request)
}

func (gateway Gateway) performRequestForResponseBytes(request *Request) ([]byte, http.Header, *http.Response, error) {
	rawResponse, err := gateway.doRequestHandlingAuth(request)
	if err != nil {
		return nil, nil, rawResponse, err
	}
	defer rawResponse.Body.Close()

	bytes, err := ioutil.ReadAll(rawResponse.Body)
	if err != nil {
		return bytes, nil, rawResponse, fmt.Errorf("%s: %s", T("Error reading response"), err.Error())
	}

	return bytes, rawResponse.Header, rawResponse, nil
}

func (gateway Gateway) PerformRequestForTextResponse(request *Request) (string, http.Header, error) {
	bytes, headers, _, err := gateway.performRequestForResponseBytes(request)
	return string(bytes), headers, err
}

func (gateway Gateway) PerformRequestForJSONResponse(request *Request, response interface{}) (http.Header, error) {
	bytes, headers, rawResponse, err := gateway.performRequestForResponseBytes(request)
	if err != nil {
		if rawResponse != nil && rawResponse.Body != nil {
			b, _ := ioutil.ReadAll(rawResponse.Body)
			_ = json.Unmarshal(b, &response)
		}
		return headers, err
	}

	if rawResponse.StatusCode > 203 || strings.TrimSpace(string(bytes)) == "" {
		return headers, nil
	}

	err = json.Unmarshal(bytes, &response)
	if err != nil {
		return headers, fmt.Errorf("%s: %s", T("Invalid JSON response from server"), err.Error())
	}

	return headers, nil
}

func (gateway Gateway) PerformPollingRequestForJSONResponse(endpoint string, request *Request, response interface{}, timeout time.Duration) (http.Header, error) {
	query := request.HTTPReq.URL.Query()
	query.Add("async", "true")
	request.HTTPReq.URL.RawQuery = query.Encode()

	bytes, headers, rawResponse, err := gateway.performRequestForResponseBytes(request)
	if err != nil {
		return headers, err
	}
	defer rawResponse.Body.Close()

	if rawResponse.StatusCode > 203 || strings.TrimSpace(string(bytes)) == "" {
		return headers, nil
	}

	err = json.Unmarshal(bytes, &response)
	if err != nil {
		return headers, fmt.Errorf("%s: %s", T("Invalid JSON response from server"), err.Error())
	}

	asyncResource := &AsyncResource{}
	err = json.Unmarshal(bytes, &asyncResource)
	if err != nil {
		return headers, fmt.Errorf("%s: %s", T("Invalid async response from server"), err.Error())
	}

	jobURL := asyncResource.Metadata.URL
	if jobURL == "" {
		return headers, nil
	}

	if !strings.Contains(jobURL, "/jobs/") {
		return headers, nil
	}

	err = gateway.waitForJob(endpoint+jobURL, request.HTTPReq.Header.Get("Authorization"), timeout)

	return headers, err
}

func (gateway Gateway) Warnings() []string {
	return *gateway.warnings
}

func (gateway Gateway) waitForJob(jobURL, accessToken string, timeout time.Duration) error {
	startTime := gateway.Clock()
	for true {
		if gateway.Clock().Sub(startTime) > timeout && timeout != 0 {
			return errors.NewAsyncTimeoutError(jobURL)
		}
		var request *Request
		request, err := gateway.NewRequest("GET", jobURL, accessToken, nil)
		response := &JobResource{}
		_, err = gateway.PerformRequestForJSONResponse(request, response)
		if err != nil {
			return err
		}

		switch response.Entity.Status {
		case JobFinished:
			return nil
		case JobFailed:
			return errors.New(response.Entity.ErrorDetails.Description)
		}

		accessToken = request.HTTPReq.Header.Get("Authorization")

		time.Sleep(gateway.PollingThrottle)
	}
	return nil
}

func (gateway Gateway) doRequestHandlingAuth(request *Request) (*http.Response, error) {
	httpReq := request.HTTPReq

	if request.SeekableBody != nil {
		httpReq.Body = ioutil.NopCloser(request.SeekableBody)
	}

	// perform request
	rawResponse, err := gateway.doRequestAndHandlerError(request)
	if err == nil || gateway.authenticator == nil {
		return rawResponse, err
	}

	switch err.(type) {
	case *errors.InvalidTokenError:
		// refresh the auth token
		var newToken string
		newToken, err = gateway.authenticator.RefreshAuthToken()
		if err != nil {
			return rawResponse, err
		}

		// reset the auth token and request body
		httpReq.Header.Set("Authorization", newToken)
		if request.SeekableBody != nil {
			_, _ = request.SeekableBody.Seek(0, 0)
			httpReq.Body = ioutil.NopCloser(request.SeekableBody)
		}

		// make the request again
		rawResponse, err = gateway.doRequestAndHandlerError(request)
	}

	return rawResponse, err
}

func (gateway Gateway) doRequestAndHandlerError(request *Request) (*http.Response, error) {
	rawResponse, err := gateway.doRequest(request.HTTPReq)
	if err != nil {
		return rawResponse, WrapNetworkErrors(request.HTTPReq.URL.Host, err)
	}

	if rawResponse.StatusCode > 299 {
		jsonBytes, _ := ioutil.ReadAll(rawResponse.Body)
		_ = rawResponse.Body.Close()
		rawResponse.Body = ioutil.NopCloser(bytes.NewBuffer(jsonBytes))
		err = gateway.errHandler(rawResponse.StatusCode, jsonBytes)
	}

	return rawResponse, err
}

func (gateway Gateway) doRequest(request *http.Request) (*http.Response, error) {
	var response *http.Response
	var err error

	if gateway.transport == nil {
		makeHTTPTransport(&gateway)
	}

	httpClient := NewHTTPClient(gateway.transport, NewRequestDumper(gateway.logger))

	httpClient.DumpRequest(request)

	for i := 0; i < 3; i++ {
		response, err = httpClient.Do(request)
		if response == nil && err != nil {
			continue
		} else {
			break
		}
	}

	if err != nil {
		return response, err
	}

	httpClient.DumpResponse(response)

	header := http.CanonicalHeaderKey("X-Cf-Warnings")
	rawWarnings := response.Header[header]
	for _, rawWarning := range rawWarnings {
		warning, _ := url.QueryUnescape(rawWarning)
		*gateway.warnings = append(*gateway.warnings, warning)
	}

	return response, err
}

func makeHTTPTransport(gateway *Gateway) {
	gateway.transport = &http.Transport{
		Dial:            (&net.Dialer{Timeout: gateway.DialTimeout}).Dial,
		TLSClientConfig: NewTLSConfig(gateway.trustedCerts, gateway.config.IsSSLDisabled()),
		Proxy:           http.ProxyFromEnvironment,
	}
}

func dialTimeout(envDialTimeout string) time.Duration {
	dialTimeout := DefaultDialTimeout
	if timeout, err := strconv.Atoi(envDialTimeout); err == nil {
		dialTimeout = time.Duration(timeout) * time.Second
	}
	return dialTimeout
}

func (gateway *Gateway) SetTrustedCerts(certificates []tls.Certificate) {
	gateway.trustedCerts = certificates
	makeHTTPTransport(gateway)
}
<commit_msg>add close connection to http header<commit_after>package net

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"net/url"
	"os"
	"runtime"
	"strconv"
	"strings"
	"time"

	"github.com/cloudfoundry/cli/cf"
	"github.com/cloudfoundry/cli/cf/configuration/coreconfig"
	"github.com/cloudfoundry/cli/cf/errors"
	. "github.com/cloudfoundry/cli/cf/i18n"
	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/cloudfoundry/cli/cf/trace"
)

const (
	JobFinished            = "finished"
	JobFailed              = "failed"
	DefaultPollingThrottle = 5 * time.Second
	DefaultDialTimeout     = 5 * time.Second
)

type JobResource struct {
	Entity struct {
		Status       string
		ErrorDetails struct {
			Description string
		} `json:"error_details"`
	}
}

type AsyncResource struct {
	Metadata struct {
		URL string
	}
}

type apiErrorHandler func(statusCode int, body []byte) error

type tokenRefresher interface {
	RefreshAuthToken() (string, error)
}

type Request struct {
	HTTPReq      *http.Request
	SeekableBody io.ReadSeeker
}

type Gateway struct {
	authenticator   tokenRefresher
	errHandler      apiErrorHandler
	PollingEnabled  bool
	PollingThrottle time.Duration
	trustedCerts    []tls.Certificate
	config          coreconfig.Reader
	warnings        *[]string
	Clock           func() time.Time
	transport       *http.Transport
	ui              terminal.UI
	logger          trace.Printer
	DialTimeout     time.Duration
}

func (gateway *Gateway) AsyncTimeout() time.Duration {
	if gateway.config.AsyncTimeout() > 0 {
		return time.Duration(gateway.config.AsyncTimeout()) * time.Minute
	}

	return 0
}

func (gateway *Gateway) SetTokenRefresher(auth tokenRefresher) {
	gateway.authenticator = auth
}

func (gateway Gateway) GetResource(url string, resource interface{}) (err error) {
	request, err := gateway.NewRequest("GET", url, gateway.config.AccessToken(), nil)
	if err != nil {
		return
	}

	_, err = gateway.PerformRequestForJSONResponse(request, resource)
	return
}

func (gateway Gateway) CreateResourceFromStruct(endpoint, url string, resource interface{}) error {
	data, err := json.Marshal(resource)
	if err != nil {
		return err
	}

	return gateway.CreateResource(endpoint, url, bytes.NewReader(data))
}

func (gateway Gateway) UpdateResourceFromStruct(endpoint, apiURL string, resource interface{}) error {
	data, err := json.Marshal(resource)
	if err != nil {
		return err
	}

	return gateway.UpdateResource(endpoint, apiURL, bytes.NewReader(data))
}

func (gateway Gateway) CreateResource(endpoint, apiURL string, body io.ReadSeeker, resource ...interface{}) error {
	return gateway.createUpdateOrDeleteResource("POST", endpoint, apiURL, body, false, resource...)
}

func (gateway Gateway) UpdateResource(endpoint, apiURL string, body io.ReadSeeker, resource ...interface{}) error {
	return gateway.createUpdateOrDeleteResource("PUT", endpoint, apiURL, body, false, resource...)
}

func (gateway Gateway) UpdateResourceSync(endpoint, apiURL string, body io.ReadSeeker, resource ...interface{}) error {
	return gateway.createUpdateOrDeleteResource("PUT", endpoint, apiURL, body, true, resource...)
}

func (gateway Gateway) DeleteResourceSynchronously(endpoint, apiURL string) error {
	return gateway.createUpdateOrDeleteResource("DELETE", endpoint, apiURL, nil, true, &AsyncResource{})
}

func (gateway Gateway) DeleteResource(endpoint, apiURL string) error {
	return gateway.createUpdateOrDeleteResource("DELETE", endpoint, apiURL, nil, false, &AsyncResource{})
}

func (gateway Gateway) ListPaginatedResources(
	target string,
	path string,
	resource interface{},
	cb func(interface{}) bool,
) error {
	for path != "" {
		pagination := NewPaginatedResources(resource)

		apiErr := gateway.GetResource(fmt.Sprintf("%s%s", target, path), &pagination)
		if apiErr != nil {
			return apiErr
		}

		resources, err := pagination.Resources()
		if err != nil {
			return fmt.Errorf("%s: %s", T("Error parsing JSON"), err.Error())
		}

		for _, resource := range resources {
			if !cb(resource) {
				return nil
			}
		}

		path = pagination.NextURL
	}

	return nil
}

func (gateway Gateway) createUpdateOrDeleteResource(verb, endpoint, apiURL string, body io.ReadSeeker, sync bool, optionalResource ...interface{}) error {
	var resource interface{}
	if len(optionalResource) > 0 {
		resource = optionalResource[0]
	}

	request, err := gateway.NewRequest(verb, endpoint+apiURL, gateway.config.AccessToken(), body)
	if err != nil {
		return err
	}

	if resource == nil {
		_, err = gateway.PerformRequest(request)
		return err
	}

	if gateway.PollingEnabled && !sync {
		_, err = gateway.PerformPollingRequestForJSONResponse(endpoint, request, resource, gateway.AsyncTimeout())
		return err
	}

	_, err = gateway.PerformRequestForJSONResponse(request, resource)
	if err != nil {
		return err
	}

	return nil
}

func (gateway Gateway) newRequest(request *http.Request, accessToken string, body io.ReadSeeker) *Request {
	if accessToken != "" {
		request.Header.Set("Authorization", accessToken)
	}

	request.Header.Set("accept", "application/json")
	request.Header.Set("Connection", "close")
	request.Header.Set("content-type", "application/json")
	request.Header.Set("User-Agent", "go-cli "+cf.Version+" / "+runtime.GOOS)

	return &Request{HTTPReq: request, SeekableBody: body}
}

func (gateway Gateway) NewRequestForFile(method, fullURL, accessToken string, body *os.File) (*Request, error) {
	progressReader := NewProgressReader(body, gateway.ui, 5*time.Second)
	_, _ = progressReader.Seek(0, 0)

	fileStats, err := body.Stat()
	if err != nil {
		return nil, fmt.Errorf("%s: %s", T("Error getting file info"), err.Error())
	}

	request, err := http.NewRequest(method, fullURL, progressReader)
	if err != nil {
		return nil, fmt.Errorf("%s: %s", T("Error building request"), err.Error())
	}

	fileSize := fileStats.Size()
	progressReader.SetTotalSize(fileSize)
	request.ContentLength = fileSize

	if err != nil {
		return nil, fmt.Errorf("%s: %s", T("Error building request"), err.Error())
	}

	return gateway.newRequest(request, accessToken, progressReader), nil
}

func (gateway Gateway) NewRequest(method, path, accessToken string, body io.ReadSeeker) (*Request, error) {
	request, err := http.NewRequest(method, path, body)
	if err != nil {
		return nil, fmt.Errorf("%s: %s", T("Error building request"), err.Error())
	}
	return gateway.newRequest(request, accessToken, body), nil
}

func (gateway Gateway) PerformRequest(request *Request) (*http.Response, error) {
	return gateway.doRequestHandlingAuth(request)
}

func (gateway Gateway) performRequestForResponseBytes(request *Request) ([]byte, http.Header, *http.Response, error) {
	rawResponse, err := gateway.doRequestHandlingAuth(request)
	if err != nil {
		return nil, nil, rawResponse, err
	}
	defer rawResponse.Body.Close()

	bytes, err := ioutil.ReadAll(rawResponse.Body)
	if err != nil {
		return bytes, nil, rawResponse, fmt.Errorf("%s: %s", T("Error reading response"), err.Error())
	}

	return bytes, rawResponse.Header, rawResponse, nil
}

func (gateway Gateway) PerformRequestForTextResponse(request *Request) (string, http.Header, error) {
	bytes, headers, _, err := gateway.performRequestForResponseBytes(request)
	return string(bytes), headers, err
}

func (gateway Gateway) PerformRequestForJSONResponse(request *Request, response interface{}) (http.Header, error) {
	bytes, headers, rawResponse, err := gateway.performRequestForResponseBytes(request)
	if err != nil {
		if rawResponse != nil && rawResponse.Body != nil {
			b, _ := ioutil.ReadAll(rawResponse.Body)
			_ = json.Unmarshal(b, &response)
		}
		return headers, err
	}

	if rawResponse.StatusCode > 203 || strings.TrimSpace(string(bytes)) == "" {
		return headers, nil
	}

	err = json.Unmarshal(bytes, &response)
	if err != nil {
		return headers, fmt.Errorf("%s: %s", T("Invalid JSON response from server"), err.Error())
	}

	return headers, nil
}

func (gateway Gateway) PerformPollingRequestForJSONResponse(endpoint string, request *Request, response interface{}, timeout time.Duration) (http.Header, error) {
	query := request.HTTPReq.URL.Query()
	query.Add("async", "true")
	request.HTTPReq.URL.RawQuery = query.Encode()

	bytes, headers, rawResponse, err := gateway.performRequestForResponseBytes(request)
	if err != nil {
		return headers, err
	}
	defer rawResponse.Body.Close()

	if rawResponse.StatusCode > 203 || strings.TrimSpace(string(bytes)) == "" {
		return headers, nil
	}

	err = json.Unmarshal(bytes, &response)
	if err != nil {
		return headers, fmt.Errorf("%s: %s", T("Invalid JSON response from server"), err.Error())
	}

	asyncResource := &AsyncResource{}
	err = json.Unmarshal(bytes, &asyncResource)
	if err != nil {
		return headers, fmt.Errorf("%s: %s", T("Invalid async response from server"), err.Error())
	}

	jobURL := asyncResource.Metadata.URL
	if jobURL == "" {
		return headers, nil
	}

	if !strings.Contains(jobURL, "/jobs/") {
		return headers, nil
	}

	err = gateway.waitForJob(endpoint+jobURL, request.HTTPReq.Header.Get("Authorization"), timeout)

	return headers, err
}

func (gateway Gateway) Warnings() []string {
	return *gateway.warnings
}

func (gateway Gateway) waitForJob(jobURL, accessToken string, timeout time.Duration) error {
	startTime := gateway.Clock()
	for true {
		if gateway.Clock().Sub(startTime) > timeout && timeout != 0 {
			return errors.NewAsyncTimeoutError(jobURL)
		}
		var request *Request
		request, err := gateway.NewRequest("GET", jobURL, accessToken, nil)
		response := &JobResource{}
		_, err = gateway.PerformRequestForJSONResponse(request, response)
		if err != nil {
			return err
		}

		switch response.Entity.Status {
		case JobFinished:
			return nil
		case JobFailed:
			return errors.New(response.Entity.ErrorDetails.Description)
		}

		accessToken = request.HTTPReq.Header.Get("Authorization")

		time.Sleep(gateway.PollingThrottle)
	}
	return nil
}

func (gateway Gateway) doRequestHandlingAuth(request *Request) (*http.Response, error) {
	httpReq := request.HTTPReq

	if request.SeekableBody != nil {
		httpReq.Body = ioutil.NopCloser(request.SeekableBody)
	}

	// perform request
	rawResponse, err := gateway.doRequestAndHandlerError(request)
	if err == nil || gateway.authenticator == nil {
		return rawResponse, err
	}

	switch err.(type) {
	case *errors.InvalidTokenError:
		// refresh the auth token
		var newToken string
		newToken, err = gateway.authenticator.RefreshAuthToken()
		if err != nil {
			return rawResponse, err
		}

		// reset the auth token and request body
		httpReq.Header.Set("Authorization", newToken)
		if request.SeekableBody != nil {
			_, _ = request.SeekableBody.Seek(0, 0)
			httpReq.Body = ioutil.NopCloser(request.SeekableBody)
		}

		// make the request again
		rawResponse, err = gateway.doRequestAndHandlerError(request)
	}

	return rawResponse, err
}

func (gateway Gateway) doRequestAndHandlerError(request *Request) (*http.Response, error) {
	rawResponse, err := gateway.doRequest(request.HTTPReq)
	if err != nil {
		return rawResponse, WrapNetworkErrors(request.HTTPReq.URL.Host, err)
	}

	if rawResponse.StatusCode > 299 {
		defer rawResponse.Body.Close()
		jsonBytes, _ := ioutil.ReadAll(rawResponse.Body)
		rawResponse.Body = ioutil.NopCloser(bytes.NewBuffer(jsonBytes))
		err = gateway.errHandler(rawResponse.StatusCode, jsonBytes)
	}

	return rawResponse, err
}

func (gateway Gateway) doRequest(request *http.Request) (*http.Response, error) {
	var response *http.Response
	var err error

	if gateway.transport == nil {
		makeHTTPTransport(&gateway)
	}

	httpClient := NewHTTPClient(gateway.transport, NewRequestDumper(gateway.logger))

	httpClient.DumpRequest(request)

	for i := 0; i < 3; i++ {
		response, err = httpClient.Do(request)
		if response == nil && err != nil {
			continue
		} else {
			break
		}
	}

	if err != nil {
		return response, err
	}

	httpClient.DumpResponse(response)

	header := http.CanonicalHeaderKey("X-Cf-Warnings")
	rawWarnings := response.Header[header]
	for _, rawWarning := range rawWarnings {
		warning, _ := url.QueryUnescape(rawWarning)
		*gateway.warnings = append(*gateway.warnings, warning)
	}

	return response, err
}

func makeHTTPTransport(gateway *Gateway) {
	gateway.transport = &http.Transport{
		Dial:            (&net.Dialer{Timeout: gateway.DialTimeout}).Dial,
		TLSClientConfig: NewTLSConfig(gateway.trustedCerts, gateway.config.IsSSLDisabled()),
		Proxy:           http.ProxyFromEnvironment,
	}
}

func dialTimeout(envDialTimeout string) time.Duration {
	dialTimeout := DefaultDialTimeout
	if timeout, err := strconv.Atoi(envDialTimeout); err == nil {
		dialTimeout = time.Duration(timeout) * time.Second
	}
	return dialTimeout
}

func (gateway *Gateway) SetTrustedCerts(certificates []tls.Certificate) {
	gateway.trustedCerts = certificates
	makeHTTPTransport(gateway)
}
<|endoftext|>


<commit_before>// Copyright ©2014 The gonum 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 fd

import (
	"math"
	"math/rand"
	"testing"

	"github.com/gonum/floats"
)

type Rosenbrock struct {
	nDim int
}

func (r Rosenbrock) F(x []float64) (sum float64) {
	deriv := make([]float64, len(x))
	return r.FDf(x, deriv)
}

func (r Rosenbrock) FDf(x []float64, deriv []float64) (sum float64) {
	for i := range deriv {
		deriv[i] = 0
	}

	for i := 0; i < len(x)-1; i++ {
		sum += math.Pow(1-x[i], 2) + 100*math.Pow(x[i+1]-math.Pow(x[i], 2), 2)
	}
	for i := 0; i < len(x)-1; i++ {
		deriv[i] += -1 * 2 * (1 - x[i])
		deriv[i] += 2 * 100 * (x[i+1] - math.Pow(x[i], 2)) * (-2 * x[i])
	}
	for i := 1; i < len(x); i++ {
		deriv[i] += 2 * 100 * (x[i] - math.Pow(x[i-1], 2))
	}

	return sum
}

func TestGradient(t *testing.T) {
	for i, test := range []struct {
		nDim    int
		tol     float64
		formula Formula
	}{
		{
			nDim:    2,
			tol:     2e-4,
			formula: Forward,
		},
		{
			nDim:    2,
			tol:     1e-6,
			formula: Central,
		},
		{
			nDim:    40,
			tol:     2e-4,
			formula: Forward,
		},
		{
			nDim:    40,
			tol:     1e-6,
			formula: Central,
		},
	} {
		x := make([]float64, test.nDim)
		for i := range x {
			x[i] = rand.Float64()
		}
		xcopy := make([]float64, len(x))
		copy(xcopy, x)

		r := Rosenbrock{len(x)}
		trueGradient := make([]float64, len(x))
		r.FDf(x, trueGradient)

		// Try with gradient nil.
		gradient := Gradient(nil, r.F, x, &Settings{
			Formula: test.formula,
		})
		if !floats.EqualApprox(gradient, trueGradient, test.tol) {
			t.Errorf("Case %v: gradient mismatch in serial with nil. Want: %v, Got: %v.", i, trueGradient, gradient)
		}
		if !floats.Equal(x, xcopy) {
			t.Errorf("Case %v: x modified during call to gradient in serial with nil.", i)
		}

		// Try with provided gradient.
		for i := range gradient {
			gradient[i] = rand.Float64()
		}
		Gradient(gradient, r.F, x, &Settings{
			Formula: test.formula,
		})
		if !floats.EqualApprox(gradient, trueGradient, test.tol) {
			t.Errorf("Case %v: gradient mismatch in serial. Want: %v, Got: %v.", i, trueGradient, gradient)
		}
		if !floats.Equal(x, xcopy) {
			t.Errorf("Case %v: x modified during call to gradient in serial with non-nil.", i)
		}

		// Try with known value.
		for i := range gradient {
			gradient[i] = rand.Float64()
		}
		Gradient(gradient, r.F, x, &Settings{
			Formula:     test.formula,
			OriginKnown: true,
			OriginValue: r.F(x),
		})
		if !floats.EqualApprox(gradient, trueGradient, test.tol) {
			t.Errorf("Case %v: gradient mismatch with known origin in serial. Want: %v, Got: %v.", i, trueGradient, gradient)
		}

		// Try with concurrent evaluation.
		for i := range gradient {
			gradient[i] = rand.Float64()
		}
		Gradient(gradient, r.F, x, &Settings{
			Formula:    test.formula,
			Concurrent: true,
		})
		if !floats.EqualApprox(gradient, trueGradient, test.tol) {
			t.Errorf("Case %v: gradient mismatch with unknown origin in parallel. Want: %v, Got: %v.", i, trueGradient, gradient)
		}
		if !floats.Equal(x, xcopy) {
			t.Errorf("Case %v: x modified during call to gradient in parallel", i)
		}

		// Try with concurrent evaluation with origin known.
		for i := range gradient {
			gradient[i] = rand.Float64()
		}
		Gradient(gradient, r.F, x, &Settings{
			Formula:     test.formula,
			Concurrent:  true,
			OriginKnown: true,
			OriginValue: r.F(x),
		})
		if !floats.EqualApprox(gradient, trueGradient, test.tol) {
			t.Errorf("Case %v: gradient mismatch with known origin in parallel. Want: %v, Got: %v.", i, trueGradient, gradient)
		}

		// Try with nil settings.
		for i := range gradient {
			gradient[i] = rand.Float64()
		}
		Gradient(gradient, r.F, x, nil)
		if !floats.EqualApprox(gradient, trueGradient, test.tol) {
			t.Errorf("Case %v: gradient mismatch with default settings. Want: %v, Got: %v.", i, trueGradient, gradient)
		}

		// Try with zero-valued settings.
		for i := range gradient {
			gradient[i] = rand.Float64()
		}
		Gradient(gradient, r.F, x, &Settings{})
		if !floats.EqualApprox(gradient, trueGradient, test.tol) {
			t.Errorf("Case %v: gradient mismatch with zero settings. Want: %v, Got: %v.", i, trueGradient, gradient)
		}
	}
}

func Panics(fun func()) (b bool) {
	defer func() {
		err := recover()
		if err != nil {
			b = true
		}
	}()
	fun()
	return
}

func TestGradientPanics(t *testing.T) {
	// Test that it panics
	if !Panics(func() {
		Gradient([]float64{0.0}, func(x []float64) float64 { return x[0] * x[0] }, []float64{0.0, 0.0}, nil)
	}) {
		t.Errorf("Gradient did not panic with length mismatch")
	}
}
<commit_msg>fd: make Gradient tests predictable<commit_after>// Copyright ©2014 The gonum 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 fd

import (
	"math"
	"math/rand"
	"testing"

	"github.com/gonum/floats"
)

type Rosenbrock struct {
	nDim int
}

func (r Rosenbrock) F(x []float64) (sum float64) {
	deriv := make([]float64, len(x))
	return r.FDf(x, deriv)
}

func (r Rosenbrock) FDf(x []float64, deriv []float64) (sum float64) {
	for i := range deriv {
		deriv[i] = 0
	}

	for i := 0; i < len(x)-1; i++ {
		sum += math.Pow(1-x[i], 2) + 100*math.Pow(x[i+1]-math.Pow(x[i], 2), 2)
	}
	for i := 0; i < len(x)-1; i++ {
		deriv[i] += -1 * 2 * (1 - x[i])
		deriv[i] += 2 * 100 * (x[i+1] - math.Pow(x[i], 2)) * (-2 * x[i])
	}
	for i := 1; i < len(x); i++ {
		deriv[i] += 2 * 100 * (x[i] - math.Pow(x[i-1], 2))
	}

	return sum
}

func TestGradient(t *testing.T) {
	rand.Seed(1)
	for i, test := range []struct {
		nDim    int
		tol     float64
		formula Formula
	}{
		{
			nDim:    2,
			tol:     2e-4,
			formula: Forward,
		},
		{
			nDim:    2,
			tol:     1e-6,
			formula: Central,
		},
		{
			nDim:    40,
			tol:     2e-4,
			formula: Forward,
		},
		{
			nDim:    40,
			tol:     1e-6,
			formula: Central,
		},
	} {
		x := make([]float64, test.nDim)
		for i := range x {
			x[i] = rand.Float64()
		}
		xcopy := make([]float64, len(x))
		copy(xcopy, x)

		r := Rosenbrock{len(x)}
		trueGradient := make([]float64, len(x))
		r.FDf(x, trueGradient)

		// Try with gradient nil.
		gradient := Gradient(nil, r.F, x, &Settings{
			Formula: test.formula,
		})
		if !floats.EqualApprox(gradient, trueGradient, test.tol) {
			t.Errorf("Case %v: gradient mismatch in serial with nil. Want: %v, Got: %v.", i, trueGradient, gradient)
		}
		if !floats.Equal(x, xcopy) {
			t.Errorf("Case %v: x modified during call to gradient in serial with nil.", i)
		}

		// Try with provided gradient.
		for i := range gradient {
			gradient[i] = rand.Float64()
		}
		Gradient(gradient, r.F, x, &Settings{
			Formula: test.formula,
		})
		if !floats.EqualApprox(gradient, trueGradient, test.tol) {
			t.Errorf("Case %v: gradient mismatch in serial. Want: %v, Got: %v.", i, trueGradient, gradient)
		}
		if !floats.Equal(x, xcopy) {
			t.Errorf("Case %v: x modified during call to gradient in serial with non-nil.", i)
		}

		// Try with known value.
		for i := range gradient {
			gradient[i] = rand.Float64()
		}
		Gradient(gradient, r.F, x, &Settings{
			Formula:     test.formula,
			OriginKnown: true,
			OriginValue: r.F(x),
		})
		if !floats.EqualApprox(gradient, trueGradient, test.tol) {
			t.Errorf("Case %v: gradient mismatch with known origin in serial. Want: %v, Got: %v.", i, trueGradient, gradient)
		}

		// Try with concurrent evaluation.
		for i := range gradient {
			gradient[i] = rand.Float64()
		}
		Gradient(gradient, r.F, x, &Settings{
			Formula:    test.formula,
			Concurrent: true,
		})
		if !floats.EqualApprox(gradient, trueGradient, test.tol) {
			t.Errorf("Case %v: gradient mismatch with unknown origin in parallel. Want: %v, Got: %v.", i, trueGradient, gradient)
		}
		if !floats.Equal(x, xcopy) {
			t.Errorf("Case %v: x modified during call to gradient in parallel", i)
		}

		// Try with concurrent evaluation with origin known.
		for i := range gradient {
			gradient[i] = rand.Float64()
		}
		Gradient(gradient, r.F, x, &Settings{
			Formula:     test.formula,
			Concurrent:  true,
			OriginKnown: true,
			OriginValue: r.F(x),
		})
		if !floats.EqualApprox(gradient, trueGradient, test.tol) {
			t.Errorf("Case %v: gradient mismatch with known origin in parallel. Want: %v, Got: %v.", i, trueGradient, gradient)
		}

		// Try with nil settings.
		for i := range gradient {
			gradient[i] = rand.Float64()
		}
		Gradient(gradient, r.F, x, nil)
		if !floats.EqualApprox(gradient, trueGradient, test.tol) {
			t.Errorf("Case %v: gradient mismatch with default settings. Want: %v, Got: %v.", i, trueGradient, gradient)
		}

		// Try with zero-valued settings.
		for i := range gradient {
			gradient[i] = rand.Float64()
		}
		Gradient(gradient, r.F, x, &Settings{})
		if !floats.EqualApprox(gradient, trueGradient, test.tol) {
			t.Errorf("Case %v: gradient mismatch with zero settings. Want: %v, Got: %v.", i, trueGradient, gradient)
		}
	}
}

func Panics(fun func()) (b bool) {
	defer func() {
		err := recover()
		if err != nil {
			b = true
		}
	}()
	fun()
	return
}

func TestGradientPanics(t *testing.T) {
	// Test that it panics
	if !Panics(func() {
		Gradient([]float64{0.0}, func(x []float64) float64 { return x[0] * x[0] }, []float64{0.0, 0.0}, nil)
	}) {
		t.Errorf("Gradient did not panic with length mismatch")
	}
}
<|endoftext|>


<commit_before>package channeldb

import (
	"encoding/binary"
	"errors"
	"io"
	"net"

	"github.com/lightningnetwork/lnd/tor"
)

// addressType specifies the network protocol and version that should be used
// when connecting to a node at a particular address.
type addressType uint8

const (
	// tcp4Addr denotes an IPv4 TCP address.
	tcp4Addr addressType = 0

	// tcp6Addr denotes an IPv6 TCP address.
	tcp6Addr addressType = 1

	// v2OnionAddr denotes a version 2 Tor onion service address.
	v2OnionAddr addressType = 2

	// v3OnionAddr denotes a version 3 Tor (prop224) onion service address.
	v3OnionAddr addressType = 3
)

// encodeTCPAddr serializes a TCP address into its compact raw bytes
// representation.
func encodeTCPAddr(w io.Writer, addr *net.TCPAddr) error {
	var (
		addrType byte
		ip       []byte
	)

	if addr.IP.To4() != nil {
		addrType = byte(tcp4Addr)
		ip = addr.IP.To4()
	} else {
		addrType = byte(tcp6Addr)
		ip = addr.IP.To16()
	}

	if _, err := w.Write([]byte{addrType}); err != nil {
		return err
	}

	if _, err := w.Write(ip); err != nil {
		return err
	}

	var port [2]byte
	byteOrder.PutUint16(port[:], uint16(addr.Port))
	if _, err := w.Write(port[:]); err != nil {
		return err
	}

	return nil
}

// encodeOnionAddr serializes an onion address into its compact raw bytes
// representation.
func encodeOnionAddr(w io.Writer, addr *tor.OnionAddr) error {
	var suffixIndex int
	switch len(addr.OnionService) {
	case tor.V2Len:
		if _, err := w.Write([]byte{byte(v2OnionAddr)}); err != nil {
			return err
		}
		suffixIndex = tor.V2Len - tor.OnionSuffixLen
	case tor.V3Len:
		if _, err := w.Write([]byte{byte(v3OnionAddr)}); err != nil {
			return err
		}
		suffixIndex = tor.V3Len - tor.OnionSuffixLen
	default:
		return errors.New("unknown onion service length")
	}

	host, err := tor.Base32Encoding.DecodeString(
		addr.OnionService[:suffixIndex],
	)
	if err != nil {
		return err
	}
	if _, err := w.Write(host); err != nil {
		return err
	}

	var port [2]byte
	byteOrder.PutUint16(port[:], uint16(addr.Port))
	if _, err := w.Write(port[:]); err != nil {
		return err
	}

	return nil
}

// deserializeAddr reads the serialized raw representation of an address and
// deserializes it into the actual address. This allows us to avoid address
// resolution within the channeldb package.
func deserializeAddr(r io.Reader) (net.Addr, error) {
	var addrType [1]byte
	if _, err := r.Read(addrType[:]); err != nil {
		return nil, err
	}

	var address net.Addr
	switch addressType(addrType[0]) {
	case tcp4Addr:
		var ip [4]byte
		if _, err := r.Read(ip[:]); err != nil {
			return nil, err
		}

		var port [2]byte
		if _, err := r.Read(port[:]); err != nil {
			return nil, err
		}

		address = &net.TCPAddr{
			IP:   net.IP(ip[:]),
			Port: int(binary.BigEndian.Uint16(port[:])),
		}
	case tcp6Addr:
		var ip [16]byte
		if _, err := r.Read(ip[:]); err != nil {
			return nil, err
		}

		var port [2]byte
		if _, err := r.Read(port[:]); err != nil {
			return nil, err
		}

		address = &net.TCPAddr{
			IP:   net.IP(ip[:]),
			Port: int(binary.BigEndian.Uint16(port[:])),
		}
	case v2OnionAddr:
		var h [tor.V2DecodedLen]byte
		if _, err := r.Read(h[:]); err != nil {
			return nil, err
		}

		var p [2]byte
		if _, err := r.Read(p[:]); err != nil {
			return nil, err
		}

		onionService := tor.Base32Encoding.EncodeToString(h[:])
		onionService += tor.OnionSuffix
		port := int(binary.BigEndian.Uint16(p[:]))

		address = &tor.OnionAddr{
			OnionService: onionService,
			Port:         port,
		}
	case v3OnionAddr:
		var h [tor.V3DecodedLen]byte
		if _, err := r.Read(h[:]); err != nil {
			return nil, err
		}

		var p [2]byte
		if _, err := r.Read(p[:]); err != nil {
			return nil, err
		}

		onionService := tor.Base32Encoding.EncodeToString(h[:])
		onionService += tor.OnionSuffix
		port := int(binary.BigEndian.Uint16(p[:]))

		address = &tor.OnionAddr{
			OnionService: onionService,
			Port:         port,
		}
	default:
		return nil, ErrUnknownAddressType
	}

	return address, nil
}

// serializeAddr serializes an address into its raw bytes representation so that
// it can be deserialized without requiring address resolution.
func serializeAddr(w io.Writer, address net.Addr) error {
	switch addr := address.(type) {
	case *net.TCPAddr:
		return encodeTCPAddr(w, addr)
	case *tor.OnionAddr:
		return encodeOnionAddr(w, addr)
	default:
		return ErrUnknownAddressType
	}
}
<commit_msg>channeldb/addr: validate ip before writing<commit_after>package channeldb

import (
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"net"

	"github.com/lightningnetwork/lnd/tor"
)

// addressType specifies the network protocol and version that should be used
// when connecting to a node at a particular address.
type addressType uint8

const (
	// tcp4Addr denotes an IPv4 TCP address.
	tcp4Addr addressType = 0

	// tcp6Addr denotes an IPv6 TCP address.
	tcp6Addr addressType = 1

	// v2OnionAddr denotes a version 2 Tor onion service address.
	v2OnionAddr addressType = 2

	// v3OnionAddr denotes a version 3 Tor (prop224) onion service address.
	v3OnionAddr addressType = 3
)

// encodeTCPAddr serializes a TCP address into its compact raw bytes
// representation.
func encodeTCPAddr(w io.Writer, addr *net.TCPAddr) error {
	var (
		addrType byte
		ip       []byte
	)

	if addr.IP.To4() != nil {
		addrType = byte(tcp4Addr)
		ip = addr.IP.To4()
	} else {
		addrType = byte(tcp6Addr)
		ip = addr.IP.To16()
	}

	if ip == nil {
		return fmt.Errorf("unable to encode IP %v", addr.IP)
	}

	if _, err := w.Write([]byte{addrType}); err != nil {
		return err
	}

	if _, err := w.Write(ip); err != nil {
		return err
	}

	var port [2]byte
	byteOrder.PutUint16(port[:], uint16(addr.Port))
	if _, err := w.Write(port[:]); err != nil {
		return err
	}

	return nil
}

// encodeOnionAddr serializes an onion address into its compact raw bytes
// representation.
func encodeOnionAddr(w io.Writer, addr *tor.OnionAddr) error {
	var suffixIndex int
	switch len(addr.OnionService) {
	case tor.V2Len:
		if _, err := w.Write([]byte{byte(v2OnionAddr)}); err != nil {
			return err
		}
		suffixIndex = tor.V2Len - tor.OnionSuffixLen
	case tor.V3Len:
		if _, err := w.Write([]byte{byte(v3OnionAddr)}); err != nil {
			return err
		}
		suffixIndex = tor.V3Len - tor.OnionSuffixLen
	default:
		return errors.New("unknown onion service length")
	}

	host, err := tor.Base32Encoding.DecodeString(
		addr.OnionService[:suffixIndex],
	)
	if err != nil {
		return err
	}
	if _, err := w.Write(host); err != nil {
		return err
	}

	var port [2]byte
	byteOrder.PutUint16(port[:], uint16(addr.Port))
	if _, err := w.Write(port[:]); err != nil {
		return err
	}

	return nil
}

// deserializeAddr reads the serialized raw representation of an address and
// deserializes it into the actual address. This allows us to avoid address
// resolution within the channeldb package.
func deserializeAddr(r io.Reader) (net.Addr, error) {
	var addrType [1]byte
	if _, err := r.Read(addrType[:]); err != nil {
		return nil, err
	}

	var address net.Addr
	switch addressType(addrType[0]) {
	case tcp4Addr:
		var ip [4]byte
		if _, err := r.Read(ip[:]); err != nil {
			return nil, err
		}

		var port [2]byte
		if _, err := r.Read(port[:]); err != nil {
			return nil, err
		}

		address = &net.TCPAddr{
			IP:   net.IP(ip[:]),
			Port: int(binary.BigEndian.Uint16(port[:])),
		}
	case tcp6Addr:
		var ip [16]byte
		if _, err := r.Read(ip[:]); err != nil {
			return nil, err
		}

		var port [2]byte
		if _, err := r.Read(port[:]); err != nil {
			return nil, err
		}

		address = &net.TCPAddr{
			IP:   net.IP(ip[:]),
			Port: int(binary.BigEndian.Uint16(port[:])),
		}
	case v2OnionAddr:
		var h [tor.V2DecodedLen]byte
		if _, err := r.Read(h[:]); err != nil {
			return nil, err
		}

		var p [2]byte
		if _, err := r.Read(p[:]); err != nil {
			return nil, err
		}

		onionService := tor.Base32Encoding.EncodeToString(h[:])
		onionService += tor.OnionSuffix
		port := int(binary.BigEndian.Uint16(p[:]))

		address = &tor.OnionAddr{
			OnionService: onionService,
			Port:         port,
		}
	case v3OnionAddr:
		var h [tor.V3DecodedLen]byte
		if _, err := r.Read(h[:]); err != nil {
			return nil, err
		}

		var p [2]byte
		if _, err := r.Read(p[:]); err != nil {
			return nil, err
		}

		onionService := tor.Base32Encoding.EncodeToString(h[:])
		onionService += tor.OnionSuffix
		port := int(binary.BigEndian.Uint16(p[:]))

		address = &tor.OnionAddr{
			OnionService: onionService,
			Port:         port,
		}
	default:
		return nil, ErrUnknownAddressType
	}

	return address, nil
}

// serializeAddr serializes an address into its raw bytes representation so that
// it can be deserialized without requiring address resolution.
func serializeAddr(w io.Writer, address net.Addr) error {
	switch addr := address.(type) {
	case *net.TCPAddr:
		return encodeTCPAddr(w, addr)
	case *tor.OnionAddr:
		return encodeOnionAddr(w, addr)
	default:
		return ErrUnknownAddressType
	}
}
<|endoftext|>


<commit_before>package feedfactory

import (
    "time"
    "fmt"
    "github.com/gorilla/feeds"
    "../couchdbrest"
    "../jsonconvert"
    "../appconfig"
)

func convertToFeed(config appconfig.AppConfig)(*feeds.Feed, error){

    body, err := couchdbrest.GetLastBlogArticles("127.0.0.1", "10")
    fmt.Println("err: ", err)

    if err != nil {
        fmt.Println("CouchDB rest call faild. Is database all ready running?")
//        body := []byte{}
        return nil, fmt.Errorf("CouchDB rest call faild. Is database all ready running?")
    }
    article_list, err := jsonconvert.JsonToObject(body)
    fmt.Println("============================\n")
    fmt.Println(article_list.Rows[0].Value["title"])
    fmt.Println("============================\n")
    fmt.Println("Anzahl Einträge:", len(article_list.Rows))

    now := time.Now()
    feed := &feeds.Feed{
        Title:       "THE INDEPENDENT FRIEND",
        Link:        &feeds.Link{Href: "https://the-independent-friend.de/"},
        Description: "Weblog von Olaf Radicke",
        Author:      &feeds.Author{"Olaf Radicke", "briefkasten@olaf-radicke.de"},
        Created:     now,
    }

    feed.Items = []*feeds.Item{}
    for index,element := range article_list.Rows {
        fmt.Println("============================\n")
        fmt.Println( "No.:" , index ,  " Value: " , element.Value["title"] )
        fmt.Println("============================\n")

        articleTitle := element.Value["title"]
        feed.Items = append(
            feed.Items,
            &feeds.Item{
                Title:       articleTitle.(string),
                Link:        &feeds.Link{Href: "http://jmoiron.net/blog/limiting-concurrency-in-go/"},
                Description: "A discussion on controlled parallelism in golang",
                Author:      &feeds.Author{"Jason Moiron", "jmoiron@jmoiron.net"},
                Created:     now,
            } )
    }

    return feed, nil
}

func GetAtom(config appconfig.AppConfig)(string, error){
    var feed, err = convertToFeed(config)
    if err != nil {
        fmt.Println("Can't create feed!")
        return "", fmt.Errorf("Can't create feed!")
    }
    atom, _ := feed.ToAtom()
//    fmt.Println("============================\n")
//    fmt.Println("atom:", atom)
//    fmt.Println("============================\n")
    return atom, nil
}

func GetRss(config appconfig.AppConfig)(string){
    var feedObject, _ = convertToFeed(config)
    rss, _ := feedObject.ToRss()
//    fmt.Println("atom:", rss)
    return rss
}
<commit_msg>Refactoring<commit_after>package feedfactory

import (
    "time"
    "fmt"
    "github.com/gorilla/feeds"
    "../couchdbrest"
    "../jsonconvert"
    "../appconfig"
)

func convertToFeed(config appconfig.AppConfig)(*feeds.Feed, error){

    body, err := couchdbrest.GetLastBlogArticles("127.0.0.1", "10")
    fmt.Println("err: ", err)

    if err != nil {
        fmt.Println("CouchDB rest call faild. Is database all ready running?")
//        body := []byte{}
        return nil, fmt.Errorf("CouchDB rest call faild. Is database all ready running?")
    }
    article_list, err := jsonconvert.JsonToObject(body)
    fmt.Println("============================\n")
    fmt.Println(article_list.Rows[0].Value["title"])
    fmt.Println("============================\n")
    fmt.Println("Anzahl Einträge:", len(article_list.Rows))

    now := time.Now()
    feed := &feeds.Feed{
        Title:       "THE INDEPENDENT FRIEND",
        Link:        &feeds.Link{Href: "https://the-independent-friend.de/"},
        Description: "Weblog von Olaf Radicke",
        Author:      &feeds.Author{config.Author, config.AuthorMail},
        Created:     now,
    }

    feed.Items = []*feeds.Item{}
    for index,element := range article_list.Rows {
        fmt.Println("============================\n")
        fmt.Println( "No.:" , index ,  " Value: " , element.Value["title"] )
        fmt.Println("============================\n")

        articleTitle := element.Value["title"]
        feed.Items = append(
            feed.Items,
            &feeds.Item{
                Title:       articleTitle.(string),
                Link:        &feeds.Link{Href: config.BlogProtocol + config.BlogDomain},
                Description: "A discussion on controlled parallelism in golang",
                Author:      &feeds.Author{config.Author, config.AuthorMail},
                Created:     now,
            } )
    }

    return feed, nil
}

func GetAtom(config appconfig.AppConfig)(string, error){
    var feed, err = convertToFeed(config)
    if err != nil {
        fmt.Println("Can't create feed!")
        return "", fmt.Errorf("Can't create feed!")
    }
    atom, _ := feed.ToAtom()
//    fmt.Println("============================\n")
//    fmt.Println("atom:", atom)
//    fmt.Println("============================\n")
    return atom, nil
}

func GetRss(config appconfig.AppConfig)(string){
    var feedObject, _ = convertToFeed(config)
    rss, _ := feedObject.ToRss()
//    fmt.Println("atom:", rss)
    return rss
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"encoding/json"
	"flag"
	"fmt"
	"github.com/bitly/go-nsq"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"
)

var (
	conf_file   = flag.String("conf", "config.json", "config file")
	nsq_address = flag.String("nsq_address", "127.0.0.1:4150", "nsq")
)

func main() {
	flag.Parse()
	cfg := nsq.NewConfig()
	hostname, err := os.Hostname()
	cfg.Set("user_agent", fmt.Sprintf("file_to_nsq/%s", hostname))
	cfg.Set("snappy", true)
	w, _ := nsq.NewProducer(*nsq_address, cfg)
	setting, err := ReadConfig(*conf_file)
	if err != nil {
		log.Fatal("fail to read config", err)
	}
	exitchan := make(chan int)
	for k, v := range setting {
		go readLog(v, k, w, exitchan)
	}
	termchan := make(chan os.Signal, 1)
	signal.Notify(termchan, syscall.SIGINT, syscall.SIGTERM)
	<-termchan
	close(exitchan)
}

func ReadConfig(file string) (map[string]string, error) {
	var setting map[string]string
	config_file, err := os.Open(file)
	config, err := ioutil.ReadAll(config_file)
	if err != nil {
		return nil, err
	}
	defer config_file.Close()
	if err := json.Unmarshal(config, &setting); err != nil {
		return nil, err
	}
	return setting, nil
}

func readLog(file string, topic string, w *nsq.Producer, exitchan chan int) {
	fd, err := os.Open(file)
	if err != nil {
		log.Println(err)
		return
	}
	defer fd.Close()
	_, err = fd.Seek(0, 2)
	if err != nil {
		return
	}
	reader := bufio.NewReader(fd)
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			time.Sleep(time.Second * 10)
			line, err = reader.ReadString('\n')
		}
		if err == io.EOF {
			log.Println("READ EOF")
			size0, err := fd.Seek(0, 1)
			if err != nil {
				return
			}
			fd, err = os.Open(file)
			if err != nil {
				log.Println("open failed", err)
				return
			}
			size1, err := fd.Seek(0, 2)
			if err != nil {
				log.Println(err)
			}
			if size1 < size0 {
				fd.Seek(0, 0)
			} else {
				fd.Seek(size0, 0)
			}
			reader = bufio.NewReader(fd)
			continue
		}
		if err != nil {
			log.Println(err)
			return
		}
		err = w.Publish(topic, []byte(line))
		if err != nil {
			log.Println("NSQ writer", err)
		}
		select {
		case <-exitchan:
			return
		default:
		}
	}
}
<commit_msg>use consul<commit_after>package main

import (
	"bufio"
	"encoding/json"
	"flag"
	"fmt"
	"github.com/hashicorp/consul/api"
	"github.com/nsqio/go-nsq"
	"io"
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"
)

var (
	conf_file   = flag.String("conf", "config.json", "config file")
	nsq_address = flag.String("nsq_address", "127.0.0.1:4150", "nsq")
)

func main() {
	flag.Parse()
	cfg := nsq.NewConfig()
	hostname, err := os.Hostname()
	cfg.Set("user_agent", fmt.Sprintf("file_to_nsq/%s", hostname))
	cfg.Set("snappy", true)
	writer, _ := nsq.NewProducer(*nsq_address, cfg)
	setting, err := ReadConfig(*conf_file)
	if err != nil {
		log.Fatal("fail to read config", err)
	}
	oldConf, err := ReadConfigFromConsul(setting)
	if err != nil {
		log.Fatal("fail to read consul config", err)
	}
	exitchan := make(chan int)
	RunTask(oldConf, setting["topic"], writer, exitchan)
	ticker := time.Tick(time.Second * 600)
	go func() {
		for {
			select {
			case <-ticker:
				newConf, err := ReadConfigFromConsul(setting)
				if err != nil {
					continue
				}
				if CheckReload(oldConf, newConf) {
					oldConf = newConf
					close(exitchan)
					exitchan = make(chan int)
					RunTask(oldConf, setting["topic"], writer, exitchan)
				}
			}
		}
	}()
	termchan := make(chan os.Signal, 1)
	signal.Notify(termchan, syscall.SIGINT, syscall.SIGTERM)
	<-termchan
	close(exitchan)
}
func RunTask(settings map[string]string, topic string, writer *nsq.Producer, exitchan chan int) {
	for files, topic := range settings {
		fileNames := strings.Split(string(files), ",")
		for _, fileName := range fileNames {
			fileName = strings.Trim(fileName, " ")
			go readLog(fileName, topic, writer, exitchan)
		}
	}
}
func CheckReload(oldConf map[string]string, newConf map[string]string) bool {
	for k, _ := range newConf {
		if oldConf[k] != newConf[k] {
			return true
		}
	}
	for k, _ := range oldConf {
		if oldConf[k] != newConf[k] {
			return true
		}
	}
	return false
}
func ReadConfigFromConsul(setting map[string]string) (map[string]string, error) {
	consulSetting := make(map[string]string)
	config := api.DefaultConfig()
	config.Address = setting["consul_address"]
	config.Datacenter = setting["datacenter"]
	config.Token = setting["consul_token"]
	client, err := api.NewClient(config)
	if err != nil {
		return consulSetting, err
	}
	kv := client.KV()
	pairs, _, err := kv.List(setting["cluster"], nil)
	if err != nil {
		return consulSetting, err
	}
	size := len(setting["cluster"]) + 1
	for _, value := range pairs {
		if len(value.Key) > size {
			consulSetting[value.Key[size:]] = string(value.Value)
		}
	}
	return consulSetting, err
}

func ReadConfig(file string) (map[string]string, error) {
	var setting map[string]string
	config_file, err := os.Open(file)
	config, err := ioutil.ReadAll(config_file)
	if err != nil {
		return nil, err
	}
	defer config_file.Close()
	if err := json.Unmarshal(config, &setting); err != nil {
		return nil, err
	}
	return setting, nil
}

func readLog(file string, topic string, w *nsq.Producer, exitchan chan int) {
	fd, err := os.Open(file)
	if err != nil {
		log.Println(err)
		return
	}
	defer fd.Close()
	_, err = fd.Seek(0, 2)
	if err != nil {
		return
	}
	reader := bufio.NewReader(fd)
	for {
		line, err := reader.ReadString('\n')
		if err != nil {
			time.Sleep(time.Second * 10)
			line, err = reader.ReadString('\n')
		}
		if err == io.EOF {
			log.Println("READ EOF")
			size0, err := fd.Seek(0, 1)
			if err != nil {
				return
			}
			fd, err = os.Open(file)
			if err != nil {
				log.Println("open failed", err)
				return
			}
			size1, err := fd.Seek(0, 2)
			if err != nil {
				log.Println(err)
			}
			if size1 < size0 {
				fd.Seek(0, 0)
			} else {
				fd.Seek(size0, 0)
			}
			reader = bufio.NewReader(fd)
			continue
		}
		if err != nil {
			log.Println(err)
			return
		}
		err = w.Publish(topic, []byte(line))
		if err != nil {
			log.Println("NSQ writer", err)
		}
		select {
		case <-exitchan:
			return
		default:
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"github.com/rschoen/fireworks-server/lib"
	"log"
	"math/rand"
	"net/http"
	"strconv"
	"time"
)

func (s *Server) handler(w http.ResponseWriter, r *http.Request) {
	if len(r.URL.Path) < 5 || r.URL.Path[1:5] != "api/" {
		http.FileServer(http.Dir(lib.ClientDirectory)).ServeHTTP(w, r)
		return
	}

	m, ok := lib.DecodeMove(r.PostFormValue("data"))
	if !ok {
		fmt.Printf("Malformed message, Discarding.")
		fmt.Fprintf(w, "Error: malformed JSON message.")
		return
	}
	var game *lib.Game
	for _, ongoingGame := range s.games {
		if ongoingGame.GameID == m.Game {
			game = ongoingGame
		}
	}

	if r.URL.Path[5:] == "join" {
		// create game if it doesn't exist
		if game == nil {
			game = new(lib.Game)
			game.GameID = m.Game
			game.Initialize()
			s.games = append(s.games, game)
		} else {
			fmt.Println(game)
		}

		player := game.GetPlayerByID(m.Player)
		// add player if it doesn't exist
		if player == nil {
			game.AddPlayer(m.Player)
		} else {
			fmt.Println(player)
		}

		fmt.Fprintf(w, lib.EncodeGame(game.CreateState(m.Player)))
		return
	}

	if r.URL.Path[5:] == "status" {
		if game == nil {
			fmt.Printf("Discarding status check for nonexistent game.")
			return
		}
		fmt.Fprintf(w, lib.EncodeGame(game.CreateState(m.Player)))
		return
	}

	player := game.GetPlayerByID(m.Player)

	if game == nil {
		fmt.Printf("Attempting to make a move on a nonexistent game.")
		fmt.Fprintf(w, "Error: Attempted to make a move on nonexistent game.",)
		return
	}

	if player == nil {
		fmt.Printf("Attempting to make a move with nonexistent player.")
		fmt.Fprintf(w, "Error: Attempting to make a move with nonexistent player.",)
		return
	}

	if r.URL.Path[5:] == "start" {
		if game.Started {
			fmt.Printf("Attempting to start already started game.")
			fmt.Fprintf(w, "Error: Attempting to start already started game.",)
			return
		}
		game.Start()
		fmt.Fprintf(w, lib.EncodeGame(game.CreateState(m.Player)))
		return
	}

	if r.URL.Path[5:] == "move" {
		game.ProcessMove(m)
		fmt.Printf("Global game state: %#v\n\n", *game)
		fmt.Fprintf(w, lib.EncodeGame(game.CreateState(m.Player)))
		return
	}

    fmt.Fprintf(w, "done")
}

type Server struct {
	games   []*lib.Game
}

func main() {
	rand.Seed(time.Now().UTC().UnixNano())

	// initialize server
	s := Server{}
	s.games = make([]*lib.Game, 0, lib.MaxConcurrentGames)

	// listen for connections
	var port = flag.Int("port", lib.Port, "Port to listen for connections from client")
	flag.Parse();
	http.HandleFunc("/", s.handler)
    log.Fatal(http.ListenAndServe(":"+strconv.Itoa(*port), nil))

}

<commit_msg>Added additional command-line flags to turn HTTP serving on or off, and which directory to serve<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/rschoen/fireworks-server/lib"
	"log"
	"math/rand"
	"net/http"
	"strconv"
	"time"
)

func (s *Server) handler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Access-Control-Allow-Origin", "*")

	if len(r.URL.Path) < 5 || r.URL.Path[1:5] != "api/" {
		if s.httpServer {
			http.FileServer(http.Dir(s.clientDirectory)).ServeHTTP(w, r)
		}
		return
	}

	m, ok := lib.DecodeMove(r.PostFormValue("data"))
	if !ok {
		fmt.Printf("Malformed message, Discarding.")
		fmt.Fprintf(w, "Error: malformed JSON message.")
		return
	}
	var game *lib.Game
	for _, ongoingGame := range s.games {
		if ongoingGame.GameID == m.Game {
			game = ongoingGame
		}
	}

	if r.URL.Path[5:] == "join" {
		// create game if it doesn't exist
		if game == nil {
			game = new(lib.Game)
			game.GameID = m.Game
			game.Initialize()
			s.games = append(s.games, game)
		} else {
			fmt.Println(game)
		}

		player := game.GetPlayerByID(m.Player)
		// add player if it doesn't exist
		if player == nil {
			game.AddPlayer(m.Player)
		} else {
			fmt.Println(player)
		}

		fmt.Fprintf(w, lib.EncodeGame(game.CreateState(m.Player)))
		return
	}

	if r.URL.Path[5:] == "status" {
		if game == nil {
			fmt.Printf("Discarding status check for nonexistent game.")
			return
		}
		fmt.Fprintf(w, lib.EncodeGame(game.CreateState(m.Player)))
		return
	}

	player := game.GetPlayerByID(m.Player)

	if game == nil {
		fmt.Printf("Attempting to make a move on a nonexistent game.")
		fmt.Fprintf(w, "Error: Attempted to make a move on nonexistent game.",)
		return
	}

	if player == nil {
		fmt.Printf("Attempting to make a move with nonexistent player.")
		fmt.Fprintf(w, "Error: Attempting to make a move with nonexistent player.",)
		return
	}

	if r.URL.Path[5:] == "start" {
		if game.Started {
			fmt.Printf("Attempting to start already started game.")
			fmt.Fprintf(w, "Error: Attempting to start already started game.",)
			return
		}
		game.Start()
		fmt.Fprintf(w, lib.EncodeGame(game.CreateState(m.Player)))
		return
	}

	if r.URL.Path[5:] == "move" {
		game.ProcessMove(m)
		fmt.Printf("Global game state: %#v\n\n", *game)
		fmt.Fprintf(w, lib.EncodeGame(game.CreateState(m.Player)))
		return
	}

    fmt.Fprintf(w, "done")
}

type Server struct {
	games   []*lib.Game
	httpServer	bool
	clientDirectory	string
}

func main() {
	rand.Seed(time.Now().UTC().UnixNano())

	// initialize server
	s := Server{}
	s.games = make([]*lib.Game, 0, lib.MaxConcurrentGames)

	// listen for connections
	s.httpServer = *flag.Bool("http-server", true, "Whether to also serve HTTP responses outside API calls.")
	s.clientDirectory = *flag.String("client-directory", lib.ClientDirectory, "Directory to serve HTTP responses from (fireworks-client directory)")
	var port = flag.Int("port", lib.Port, "Port to listen for connections from client.")
	flag.Parse();
	http.HandleFunc("/", s.handler)
    log.Fatal(http.ListenAndServe(":"+strconv.Itoa(*port), nil))

}

<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"strings"
	"syscall"

	"github.com/pachyderm/pachyderm/src/client"
	ppsclient "github.com/pachyderm/pachyderm/src/client/pps"
	"github.com/pachyderm/pachyderm/src/server/pfs/fuse"
	ppsserver "github.com/pachyderm/pachyderm/src/server/pps"
	"github.com/spf13/cobra"
	"go.pedge.io/env"
	"golang.org/x/net/context"
)

type appEnv struct {
	PachydermAddress string `env:"PACHD_PORT_650_TCP_ADDR,required"`
}

func main() {
	env.Main(do, &appEnv{})
}

func do(appEnvObj interface{}) error {
	appEnv := appEnvObj.(*appEnv)
	rootCmd := &cobra.Command{
		Use:   os.Args[0] + " job-id",
		Short: `Pachyderm job-shim, coordinates with ppsd to create an output commit and run user work.`,
		Long:  `Pachyderm job-shim, coordinates with ppsd to create an output commit and run user work.`,
		Run: func(_ *cobra.Command, args []string) {
			ppsClient, err := ppsserver.NewInternalJobAPIClientFromAddress(fmt.Sprintf("%v:650", appEnv.PachydermAddress))
			if err != nil {
				errorAndExit(err.Error())
			}
			response, err := ppsClient.StartJob(
				context.Background(),
				&ppsserver.StartJobRequest{
					Job: &ppsclient.Job{
						ID: args[0],
					}})
			if err != nil {
				fmt.Fprintf(os.Stderr, "%s\n", err.Error())
				os.Exit(0)
			}

			// We want to make sure that we only send FinishJob once.
			// The most bulletproof way would be to check that on server side,
			// but this is easier.
			var finished bool
			// Make sure that we call FinishJob even if something caused a panic
			defer func() {
				if r := recover(); r != nil && !finished {
					fmt.Println("job shim crashed; this is like a bug in pachyderm")
					if _, err := ppsClient.FinishJob(
						context.Background(),
						&ppsserver.FinishJobRequest{
							Job: &ppsclient.Job{
								ID: args[0],
							},
							Success: false,
						},
					); err != nil {
						errorAndExit(err.Error())
					}
				}
			}()

			c, err := client.NewFromAddress(fmt.Sprintf("%v:650", appEnv.PachydermAddress))
			if err != nil {
				errorAndExit(err.Error())
			}

			mounter := fuse.NewMounter(appEnv.PachydermAddress, c.PfsAPIClient)
			ready := make(chan bool)
			go func() {
				if err := mounter.MountAndCreate(
					"/pfs",
					nil,
					response.CommitMounts,
					ready,
				); err != nil {
					errorAndExit(err.Error())
				}
			}()
			<-ready
			defer func() {
				if err := mounter.Unmount("/pfs"); err != nil {
					errorAndExit(err.Error())
				}
			}()
			var readers []io.Reader
			for _, line := range response.Transform.Stdin {
				readers = append(readers, strings.NewReader(line+"\n"))
			}
			if len(response.Transform.Cmd) == 0 {
				fmt.Println("unable to run; a cmd needs to be provided")
				if _, err := ppsClient.FinishJob(
					context.Background(),
					&ppsserver.FinishJobRequest{
						Job:     client.NewJob(args[0]),
						Success: false,
					},
				); err != nil {
					errorAndExit(err.Error())
				}
				finished = true
				return
			}
			cmd := exec.Command(response.Transform.Cmd[0], response.Transform.Cmd[1:]...)
			cmd.Stdin = io.MultiReader(readers...)
			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr
			success := true
			if err := cmd.Run(); err != nil {
				success = false
				if exiterr, ok := err.(*exec.ExitError); ok {
					if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
						for _, returnCode := range response.Transform.AcceptReturnCode {
							if int(returnCode) == status.ExitStatus() {
								success = true
							}
						}
					}
				}
				if !success {
					fmt.Fprintf(os.Stderr, "Error from exec: %s\n", err.Error())
				}
			}
			if _, err := ppsClient.FinishJob(
				context.Background(),
				&ppsserver.FinishJobRequest{
					Job:     client.NewJob(args[0]),
					Success: success,
				},
			); err != nil {
				errorAndExit(err.Error())
			}
			finished = true
		},
	}

	return rootCmd.Execute()
}

func errorAndExit(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "%s\n", fmt.Sprintf(format, args...))
	os.Exit(1)
}
<commit_msg>Implements Transform.Debug.<commit_after>package main

import (
	"fmt"
	"io"
	"os"
	"os/exec"
	"strings"
	"syscall"

	"github.com/pachyderm/pachyderm/src/client"
	ppsclient "github.com/pachyderm/pachyderm/src/client/pps"
	"github.com/pachyderm/pachyderm/src/server/pfs/fuse"
	ppsserver "github.com/pachyderm/pachyderm/src/server/pps"
	"github.com/spf13/cobra"
	"go.pedge.io/env"
	"go.pedge.io/lion"
	"golang.org/x/net/context"
)

type appEnv struct {
	PachydermAddress string `env:"PACHD_PORT_650_TCP_ADDR,required"`
}

func main() {
	env.Main(do, &appEnv{})
}

func do(appEnvObj interface{}) error {
	appEnv := appEnvObj.(*appEnv)
	rootCmd := &cobra.Command{
		Use:   os.Args[0] + " job-id",
		Short: `Pachyderm job-shim, coordinates with ppsd to create an output commit and run user work.`,
		Long:  `Pachyderm job-shim, coordinates with ppsd to create an output commit and run user work.`,
		Run: func(_ *cobra.Command, args []string) {
			ppsClient, err := ppsserver.NewInternalJobAPIClientFromAddress(fmt.Sprintf("%v:650", appEnv.PachydermAddress))
			if err != nil {
				errorAndExit(err.Error())
			}
			response, err := ppsClient.StartJob(
				context.Background(),
				&ppsserver.StartJobRequest{
					Job: &ppsclient.Job{
						ID: args[0],
					}})
			if err != nil {
				fmt.Fprintf(os.Stderr, "%s\n", err.Error())
				os.Exit(0)
			}

			if response.Transform.Debug {
				lion.SetLevel(lion.LevelDebug)
			}

			// We want to make sure that we only send FinishJob once.
			// The most bulletproof way would be to check that on server side,
			// but this is easier.
			var finished bool
			// Make sure that we call FinishJob even if something caused a panic
			defer func() {
				if r := recover(); r != nil && !finished {
					fmt.Println("job shim crashed; this is like a bug in pachyderm")
					if _, err := ppsClient.FinishJob(
						context.Background(),
						&ppsserver.FinishJobRequest{
							Job: &ppsclient.Job{
								ID: args[0],
							},
							Success: false,
						},
					); err != nil {
						errorAndExit(err.Error())
					}
				}
			}()

			c, err := client.NewFromAddress(fmt.Sprintf("%v:650", appEnv.PachydermAddress))
			if err != nil {
				errorAndExit(err.Error())
			}

			mounter := fuse.NewMounter(appEnv.PachydermAddress, c.PfsAPIClient)
			ready := make(chan bool)
			go func() {
				if err := mounter.MountAndCreate(
					"/pfs",
					nil,
					response.CommitMounts,
					ready,
				); err != nil {
					errorAndExit(err.Error())
				}
			}()
			<-ready
			defer func() {
				if err := mounter.Unmount("/pfs"); err != nil {
					errorAndExit(err.Error())
				}
			}()
			var readers []io.Reader
			for _, line := range response.Transform.Stdin {
				readers = append(readers, strings.NewReader(line+"\n"))
			}
			if len(response.Transform.Cmd) == 0 {
				fmt.Println("unable to run; a cmd needs to be provided")
				if _, err := ppsClient.FinishJob(
					context.Background(),
					&ppsserver.FinishJobRequest{
						Job:     client.NewJob(args[0]),
						Success: false,
					},
				); err != nil {
					errorAndExit(err.Error())
				}
				finished = true
				return
			}
			cmd := exec.Command(response.Transform.Cmd[0], response.Transform.Cmd[1:]...)
			cmd.Stdin = io.MultiReader(readers...)
			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr
			success := true
			if err := cmd.Run(); err != nil {
				success = false
				if exiterr, ok := err.(*exec.ExitError); ok {
					if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
						for _, returnCode := range response.Transform.AcceptReturnCode {
							if int(returnCode) == status.ExitStatus() {
								success = true
							}
						}
					}
				}
				if !success {
					fmt.Fprintf(os.Stderr, "Error from exec: %s\n", err.Error())
				}
			}
			if _, err := ppsClient.FinishJob(
				context.Background(),
				&ppsserver.FinishJobRequest{
					Job:     client.NewJob(args[0]),
					Success: success,
				},
			); err != nil {
				errorAndExit(err.Error())
			}
			finished = true
		},
	}

	return rootCmd.Execute()
}

func errorAndExit(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "%s\n", fmt.Sprintf(format, args...))
	os.Exit(1)
}
<|endoftext|>


<commit_before>package spectrum

import (
	"testing"
	"sdl"
	"io/ioutil"
	"image"
	"image/png"
	"os"
	"strings"
	"unsafe"
)

func (s *SDLSurface) At(x, y int) image.Color {
	var bpp = int(s.surface.Format.BytesPerPixel)

	var pixel = uintptr(unsafe.Pointer(s.surface.Pixels))

	pixel += uintptr(y*int(s.surface.Pitch) + x*bpp)

	var color = *((*uint32)(unsafe.Pointer(pixel)))

	var r uint8
	var g uint8
	var b uint8
	var a uint8

	sdl.GetRGBA(color, s.surface.Format, &r, &g, &b, &a)

	return image.RGBAColor{uint8(r), uint8(g), uint8(b), uint8(a)}
}

func initSDL() {
	if sdl.Init(sdl.INIT_VIDEO) != 0 {
		panic(sdl.GetError())
	}
}

func newSurface() *sdl.Surface {
	return sdl.SetVideoMode(TotalScreenWidth, TotalScreenHeight, 32, 0)
}

func loadExpectedImage(filename string) image.Image {
	var file *os.File
	var err os.Error
	var image image.Image

	if file, err = os.Open(filename, os.O_RDONLY, 0); err != nil {
		panic(err)
	}

	if image, err = png.Decode(file); err != nil {
		panic(err)
	}
	return image
}

func loadScreen(filename string, speccy *Spectrum48k) *ULA {
	memory := NewMemory()
	memory.init(speccy)
	ula := NewULA()
	ula.init(speccy)
	image, _ := ioutil.ReadFile(filename)
	for offset, value := range image {
		speccy.Memory.Write(0x4000+uint16(offset), value)
	}
	return ula
}

func colorsAreNotEqual(got, expected image.Color) bool {
	got_r, got_g, got_b, got_a := got.RGBA()
	expected_r, expected_g, expected_b, expected_a := expected.RGBA()
	if (got_r != expected_r) || (got_g != expected_g) || (got_b != expected_b) || (got_a != expected_a) {
		return true
	}
	return false
}

func imagesAreNotEqual(got *SDLScreen, expected image.Image) image.Image {
	diff := false
	diffImage := image.NewRGBA(TotalScreenWidth, TotalScreenHeight)

	for y := 0; y < TotalScreenHeight; y++ {
		for x := 0; x < TotalScreenWidth; x++ {
			if colorsAreNotEqual(got.screenSurface.At(x, y), expected.At(x, y)) {
				diff = true
				diffImage.Set(x, y, image.Red)
			}
		}
	}

	if diff {
		return diffImage
	}

	return nil

}

type RenderTest struct {
	in, out     string
	borderColor byte
	flash       bool
	diffImage   image.Image
}

func (r *RenderTest) renderScreen(speccy *Spectrum48k) bool {
	renderedSDLScreen := &SDLScreen{nil, SDLSurface{newSurface()}, newUnscaledDisplay()}

	speccy.addDisplay(renderedSDLScreen)

	expectedImage := loadExpectedImage(r.out)
	inputScreen := loadScreen(r.in, speccy)

	inputScreen.borderColor = r.borderColor

	if r.flash {
		inputScreen.frame = 0x10
		inputScreen.prepare(speccy.displays.At(0).(*DisplayInfo))
	}

	displayData := inputScreen.prepare(speccy.displays.At(0).(*DisplayInfo))

	renderedSDLScreen.render(displayData, nil)

	if diffImage := imagesAreNotEqual(renderedSDLScreen, expectedImage); diffImage != nil {
		r.diffImage = diffImage
		return true
	}

	return false
}

func (r *RenderTest) getDiffFn() string {
	return strings.TrimRight(r.out, ".png") + "_diff.png"
}

func (r *RenderTest) reportError(t *testing.T) {
	t.Errorf("Expected image %s is not equal to the rendered one! Check %s\n", r.out, r.getDiffFn())

	if file, err := os.Open(r.getDiffFn(), os.O_CREATE|os.O_WRONLY, 0666); err != nil {
		panic(err)
	} else {
		if err := png.Encode(file, r.diffImage); err != nil {
			panic(err)
		}
	}
}

var RenderTests = []RenderTest{
	RenderTest{in: "testdata/initial.scr", out: "testdata/initial.png", borderColor: 7},
	RenderTest{in: "testdata/flash.scr", out: "testdata/flash_0.png", borderColor: 7},
	RenderTest{in: "testdata/flash.scr", out: "testdata/flash_1.png", borderColor: 7, flash: true},
}

func TestSDLRenderer(t *testing.T) {

	initSDL()

	defaultRomPath = "testdata/48.rom"

	app := NewApplication()

	if speccy, err := NewSpectrum48k(app); err != nil {
		panic(err)
	} else {
		for _, r := range RenderTests {
			if notEqual := r.renderScreen(speccy); notEqual {
				r.reportError(t)
			}
		}
	}

	sdl.Quit()

}

func BenchmarkRender(b *testing.B) {

	b.StopTimer()

	initSDL()

	defaultRomPath = "testdata/48.rom"

	app := NewApplication()

	const numFrames = 1000

	var (
		frames    [numFrames]*DisplayData
		prevFrame *DisplayData = nil
	)

	sdlScreen := &SDLScreen{make(chan *DisplayData), SDLSurface{newSurface()}, newUnscaledDisplay()}

	if speccy, err := NewSpectrum48k(app); err != nil {
		panic(err)
	} else {
		speccy.addDisplay(sdlScreen)
		speccy.loadSna("testdata/fire.sna")

		go func() {
			for i := 0; i < numFrames; i++ {
				speccy.renderFrame()
			}
		}()

		for i := 0; i < numFrames; i++ {
			frames[i] = <-sdlScreen.getDisplayDataChannel()
		}

		var j int

		b.StartTimer()
		for i := 0; i < b.N; i++ {
			j %= numFrames
			sdlScreen.render(frames[j], prevFrame)
			prevFrame = frames[j]
			j++
		}

	}

	sdl.Quit()
}
<commit_msg>Fix sdldisplay_test.go to build with current Go release<commit_after>package spectrum

import (
	"testing"
	"sdl"
	"io/ioutil"
	"image"
	"image/png"
	"os"
	"strings"
	"unsafe"
)

func (s *SDLSurface) At(x, y int) image.Color {
	var bpp = int(s.surface.Format.BytesPerPixel)

	var pixel = uintptr(unsafe.Pointer(s.surface.Pixels))

	pixel += uintptr(y*int(s.surface.Pitch) + x*bpp)

	var color = *((*uint32)(unsafe.Pointer(pixel)))

	var r uint8
	var g uint8
	var b uint8
	var a uint8

	sdl.GetRGBA(color, s.surface.Format, &r, &g, &b, &a)

	return image.RGBAColor{uint8(r), uint8(g), uint8(b), uint8(a)}
}

func initSDL() {
	if sdl.Init(sdl.INIT_VIDEO) != 0 {
		panic(sdl.GetError())
	}
}

func newSurface() *sdl.Surface {
	return sdl.SetVideoMode(TotalScreenWidth, TotalScreenHeight, 32, 0)
}

func loadExpectedImage(filename string) image.Image {
	var file *os.File
	var err os.Error
	var image image.Image

	if file, err = os.Open(filename, os.O_RDONLY, 0); err != nil {
		panic(err)
	}

	if image, err = png.Decode(file); err != nil {
		panic(err)
	}
	return image
}

func loadScreen(filename string, speccy *Spectrum48k) *ULA {
	memory := NewMemory()
	memory.init(speccy)
	ula := NewULA()
	ula.init(speccy)
	image, _ := ioutil.ReadFile(filename)
	for offset, value := range image {
		speccy.Memory.Write(0x4000+uint16(offset), value)
	}
	return ula
}

func colorsAreNotEqual(got, expected image.Color) bool {
	got_r, got_g, got_b, got_a := got.RGBA()
	expected_r, expected_g, expected_b, expected_a := expected.RGBA()
	if (got_r != expected_r) || (got_g != expected_g) || (got_b != expected_b) || (got_a != expected_a) {
		return true
	}
	return false
}

func imagesAreNotEqual(got *SDLScreen, expected image.Image) image.Image {
	diff := false
	diffImage := image.NewRGBA(TotalScreenWidth, TotalScreenHeight)

	for y := 0; y < TotalScreenHeight; y++ {
		for x := 0; x < TotalScreenWidth; x++ {
			if colorsAreNotEqual(got.screenSurface.At(x, y), expected.At(x, y)) {
				diff = true
				diffImage.Set(x, y, image.RGBAColor{255, 0, 0, 255})
			}
		}
	}

	if diff {
		return diffImage
	}

	return nil

}

type RenderTest struct {
	in, out     string
	borderColor byte
	flash       bool
	diffImage   image.Image
}

func (r *RenderTest) renderScreen(speccy *Spectrum48k) bool {
	renderedSDLScreen := &SDLScreen{nil, SDLSurface{newSurface()}, newUnscaledDisplay()}

	speccy.addDisplay(renderedSDLScreen)

	expectedImage := loadExpectedImage(r.out)
	inputScreen := loadScreen(r.in, speccy)

	inputScreen.borderColor = r.borderColor

	if r.flash {
		inputScreen.frame = 0x10
		inputScreen.prepare(speccy.displays.At(0).(*DisplayInfo))
	}

	displayData := inputScreen.prepare(speccy.displays.At(0).(*DisplayInfo))

	renderedSDLScreen.render(displayData, nil)

	if diffImage := imagesAreNotEqual(renderedSDLScreen, expectedImage); diffImage != nil {
		r.diffImage = diffImage
		return true
	}

	return false
}

func (r *RenderTest) getDiffFn() string {
	return strings.TrimRight(r.out, ".png") + "_diff.png"
}

func (r *RenderTest) reportError(t *testing.T) {
	t.Errorf("Expected image %s is not equal to the rendered one! Check %s\n", r.out, r.getDiffFn())

	if file, err := os.Open(r.getDiffFn(), os.O_CREATE|os.O_WRONLY, 0666); err != nil {
		panic(err)
	} else {
		if err := png.Encode(file, r.diffImage); err != nil {
			panic(err)
		}
	}
}

var RenderTests = []RenderTest{
	RenderTest{in: "testdata/initial.scr", out: "testdata/initial.png", borderColor: 7},
	RenderTest{in: "testdata/flash.scr", out: "testdata/flash_0.png", borderColor: 7},
	RenderTest{in: "testdata/flash.scr", out: "testdata/flash_1.png", borderColor: 7, flash: true},
}

func TestSDLRenderer(t *testing.T) {

	initSDL()

	defaultRomPath = "testdata/48.rom"

	app := NewApplication()

	if speccy, err := NewSpectrum48k(app); err != nil {
		panic(err)
	} else {
		for _, r := range RenderTests {
			if notEqual := r.renderScreen(speccy); notEqual {
				r.reportError(t)
			}
		}
	}

	sdl.Quit()

}

func BenchmarkRender(b *testing.B) {

	b.StopTimer()

	initSDL()

	defaultRomPath = "testdata/48.rom"

	app := NewApplication()

	const numFrames = 1000

	var (
		frames    [numFrames]*DisplayData
		prevFrame *DisplayData = nil
	)

	sdlScreen := &SDLScreen{make(chan *DisplayData), SDLSurface{newSurface()}, newUnscaledDisplay()}

	if speccy, err := NewSpectrum48k(app); err != nil {
		panic(err)
	} else {
		speccy.addDisplay(sdlScreen)
		speccy.loadSna("testdata/fire.sna")

		go func() {
			for i := 0; i < numFrames; i++ {
				speccy.renderFrame()
			}
		}()

		for i := 0; i < numFrames; i++ {
			frames[i] = <-sdlScreen.getDisplayDataChannel()
		}

		var j int

		b.StartTimer()
		for i := 0; i < b.N; i++ {
			j %= numFrames
			sdlScreen.render(frames[j], prevFrame)
			prevFrame = frames[j]
			j++
		}

	}

	sdl.Quit()
}
<|endoftext|>


<commit_before>/*
Copyright 2016 Pivotal

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 api

import (
	cfclient "github.com/cloudfoundry-community/go-cfclient"
	"os"
	"log"
	"strconv"
	"strings"
	"app-metrics-nozzle/domain"
)

var logger = log.New(os.Stdout, "", 0)
var client *cfclient.Client

func init(){

	skipSsl, _ := strconv.ParseBool(os.Getenv("SKIP_SSL_VALIDATION"))
	c := cfclient.Config{
		ApiAddress:        os.Getenv("API_ENDPOINT"),
		Username:          os.Getenv("FIREHOSE_USER"),
		Password:          os.Getenv("FIREHOSE_PASSWORD"),
		SkipSslValidation: skipSsl,
	}

	logger.Println("Processing Cloud Controller call to " + os.Getenv("API_ENDPOINT"))
	client, _ = cfclient.NewClient(&c)
}

func AnnotateWithCloudControllerData(app *domain.App) {

	ccAppDetails, _ := client.AppByGuid(app.GUID)

	instances, _ := client.GetAppInstances(app.GUID)
	runnintCount := 0
	instanceUp := "RUNNING"

	space, _ := ccAppDetails.Space()
	org, _ := space.Org()

	app.Diego = ccAppDetails.Diego
	app.Buildpack = ccAppDetails.Buildpack
	app.Instances = make([]domain.Instances, int64(len(instances)))

	for idx, eachInstance := range instances {
		if strings.Compare(instanceUp, eachInstance.State) == 0 {
			runnintCount++;
		}
		i, _ := strconv.ParseInt(idx, 10, 32)
		app.Instances[i].InstanceIndex = i
		app.Instances[i].State = eachInstance.State
		app.Instances[i].Since = eachInstance.Since
		app.Instances[i].Uptime = eachInstance.Uptime
	}

	if len(app.Buildpack) == 0 { app.Buildpack = ccAppDetails.DetectedBP }

	app.Environment = ccAppDetails.Environment

	app.Organization.ID = org.Guid
	app.Organization.Name = org.Name

	app.Space.ID = space.Guid
	app.Space.Name = space.Name

	app.InstanceCount.Configured = len(instances)
	app.InstanceCount.Running = runnintCount

	app.EnvironmentSummary.TotalDiskConfigured = ccAppDetails.DiskQuota
	app.EnvironmentSummary.TotalMemoryConfigured = ccAppDetails.MemQuota

	app.EnvironmentSummary.TotalDiskProvisioned = ccAppDetails.DiskQuota * int32(len(instances))
	app.EnvironmentSummary.TotalMemoryProvisioned = ccAppDetails.MemQuota * int32(len(instances))

	if 0 < len(ccAppDetails.RouteData) {
		app.Routes = make([]string, len(ccAppDetails.RouteData))
		for i := 0; i < len(ccAppDetails.RouteData); i++ {
			app.Routes[i] = ccAppDetails.RouteData[i].Entity.Host + "." + ccAppDetails.RouteData[i].Entity.DomainData.Entity.Name
		}
	}

	app.State = ccAppDetails.State
}

func UsersForSpace(guid string) (Users []cfclient.User) {
	users, _ := client.UsersBy(guid, "spaces")
	return users
}

func UsersForOrganization(guid string) (Users []cfclient.User) {
	users, _ := client.UsersBy(guid, "organizations")
	return users
}

func SpacesDetailsFromCloudController()  (Spaces []cfclient.Space){
	spaces, _ := client.ListSpaces()
	return spaces
}

func OrgsDetailsFromCloudController()  (Orgs []cfclient.Org){
	orgs, _ := client.ListOrgs()
	return orgs
}

<commit_msg>Ensure quotas use same multiplier as usages<commit_after>/*
Copyright 2016 Pivotal

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 api

import (
	cfclient "github.com/cloudfoundry-community/go-cfclient"
	"os"
	"log"
	"strconv"
	"strings"
	"app-metrics-nozzle/domain"
)

var logger = log.New(os.Stdout, "", 0)
var client *cfclient.Client

func init(){

	skipSsl, _ := strconv.ParseBool(os.Getenv("SKIP_SSL_VALIDATION"))
	c := cfclient.Config{
		ApiAddress:        os.Getenv("API_ENDPOINT"),
		Username:          os.Getenv("FIREHOSE_USER"),
		Password:          os.Getenv("FIREHOSE_PASSWORD"),
		SkipSslValidation: skipSsl,
	}

	logger.Println("Processing Cloud Controller call to " + os.Getenv("API_ENDPOINT"))
	client, _ = cfclient.NewClient(&c)
}

func AnnotateWithCloudControllerData(app *domain.App) {

	ccAppDetails, _ := client.AppByGuid(app.GUID)

	instances, _ := client.GetAppInstances(app.GUID)
	runnintCount := 0
	instanceUp := "RUNNING"

	space, _ := ccAppDetails.Space()
	org, _ := space.Org()

	app.Diego = ccAppDetails.Diego
	app.Buildpack = ccAppDetails.Buildpack
	app.Instances = make([]domain.Instances, int64(len(instances)))

	for idx, eachInstance := range instances {
		if strings.Compare(instanceUp, eachInstance.State) == 0 {
			runnintCount++;
		}
		i, _ := strconv.ParseInt(idx, 10, 32)
		app.Instances[i].InstanceIndex = i
		app.Instances[i].State = eachInstance.State
		app.Instances[i].Since = eachInstance.Since
		app.Instances[i].Uptime = eachInstance.Uptime
	}

	if len(app.Buildpack) == 0 { app.Buildpack = ccAppDetails.DetectedBP }

	app.Environment = ccAppDetails.Environment

	app.Organization.ID = org.Guid
	app.Organization.Name = org.Name

	app.Space.ID = space.Guid
	app.Space.Name = space.Name

	app.InstanceCount.Configured = len(instances)
	app.InstanceCount.Running = runnintCount

	app.EnvironmentSummary.TotalDiskConfigured = ccAppDetails.DiskQuota * 1024 * 1024
	app.EnvironmentSummary.TotalMemoryConfigured = ccAppDetails.MemQuota * 1024 * 1024

	app.EnvironmentSummary.TotalDiskProvisioned = ccAppDetails.DiskQuota * 1024 * 1024 * int32(len(instances))
	app.EnvironmentSummary.TotalMemoryProvisioned = ccAppDetails.MemQuota * 1024 * 1024 * int32(len(instances))

	if 0 < len(ccAppDetails.RouteData) {
		app.Routes = make([]string, len(ccAppDetails.RouteData))
		for i := 0; i < len(ccAppDetails.RouteData); i++ {
			app.Routes[i] = ccAppDetails.RouteData[i].Entity.Host + "." + ccAppDetails.RouteData[i].Entity.DomainData.Entity.Name
		}
	}

	app.State = ccAppDetails.State
}

func UsersForSpace(guid string) (Users []cfclient.User) {
	users, _ := client.UsersBy(guid, "spaces")
	return users
}

func UsersForOrganization(guid string) (Users []cfclient.User) {
	users, _ := client.UsersBy(guid, "organizations")
	return users
}

func SpacesDetailsFromCloudController()  (Spaces []cfclient.Space){
	spaces, _ := client.ListSpaces()
	return spaces
}

func OrgsDetailsFromCloudController()  (Orgs []cfclient.Org){
	orgs, _ := client.ListOrgs()
	return orgs
}

<|endoftext|>