<commit_before>package linkedapp

import (
	"github.com/watermint/toolbox/domain/dropbox/api/dbx_conn"
	"github.com/watermint/toolbox/domain/dropbox/model/mo_linkedapp"
	"github.com/watermint/toolbox/domain/dropbox/model/mo_member"
	"github.com/watermint/toolbox/domain/dropbox/service/sv_linkedapp"
	"github.com/watermint/toolbox/domain/dropbox/service/sv_member"
	"github.com/watermint/toolbox/infra/control/app_control"
	"github.com/watermint/toolbox/infra/recipe/rc_exec"
	"github.com/watermint/toolbox/infra/recipe/rc_recipe"
	"github.com/watermint/toolbox/infra/report/rp_model"
)

type List struct {
	Peer      dbx_conn.ConnBusinessFile
	LinkedApp rp_model.RowReport
}

func (z *List) Preset() {
	z.LinkedApp.SetModel(
		&mo_linkedapp.MemberLinkedApp{},
		rp_model.HiddenColumns(
			"team_member_id",
			"familiar_name",
			"abbreviated_name",
			"member_folder_id",
			"external_id",
			"account_id",
			"persistent_id",
			"app_id",
		),
	)
}

func (z *List) Exec(c app_control.Control) error {
	memberList, err := sv_member.New(z.Peer.Context()).List()
	if err != nil {
		return err
	}
	members := mo_member.MapByTeamMemberId(memberList)

	if err := z.LinkedApp.Open(); err != nil {
		return err
	}

	apps, err := sv_linkedapp.New(z.Peer.Context()).List()
	if err != nil {
		return err
	}

	for _, app := range apps {
		m := &mo_member.Member{}
		m.TeamMemberId = app.TeamMemberId

		if m0, e := members[app.TeamMemberId]; e {
			m = m0
		}
		ma := mo_linkedapp.NewMemberLinkedApp(m, app)

		z.LinkedApp.Row(ma)
	}
	return nil
}

func (z *List) Test(c app_control.Control) error {
	if err := rc_exec.Exec(c, &List{}, rc_recipe.NoCustomValues); err != nil {
		return err
	}
	return nil
}
<commit_msg>#410 : team linkedapp list<commit_after>package linkedapp

import (
	"github.com/watermint/toolbox/domain/dropbox/api/dbx_auth"
	"github.com/watermint/toolbox/domain/dropbox/api/dbx_conn"
	"github.com/watermint/toolbox/domain/dropbox/model/mo_linkedapp"
	"github.com/watermint/toolbox/domain/dropbox/model/mo_member"
	"github.com/watermint/toolbox/domain/dropbox/service/sv_linkedapp"
	"github.com/watermint/toolbox/domain/dropbox/service/sv_member"
	"github.com/watermint/toolbox/infra/control/app_control"
	"github.com/watermint/toolbox/infra/recipe/rc_exec"
	"github.com/watermint/toolbox/infra/recipe/rc_recipe"
	"github.com/watermint/toolbox/infra/report/rp_model"
)

type List struct {
	Peer      dbx_conn.ConnScopedTeam
	LinkedApp rp_model.RowReport
}

func (z *List) Preset() {
	z.Peer.SetScopes(
		dbx_auth.ScopeMembersRead,
		dbx_auth.ScopeSessionsList,
	)
	z.LinkedApp.SetModel(
		&mo_linkedapp.MemberLinkedApp{},
		rp_model.HiddenColumns(
			"team_member_id",
			"familiar_name",
			"abbreviated_name",
			"member_folder_id",
			"external_id",
			"account_id",
			"persistent_id",
			"app_id",
		),
	)
}

func (z *List) Exec(c app_control.Control) error {
	memberList, err := sv_member.New(z.Peer.Context()).List()
	if err != nil {
		return err
	}
	members := mo_member.MapByTeamMemberId(memberList)

	if err := z.LinkedApp.Open(); err != nil {
		return err
	}

	apps, err := sv_linkedapp.New(z.Peer.Context()).List()
	if err != nil {
		return err
	}

	for _, app := range apps {
		m := &mo_member.Member{}
		m.TeamMemberId = app.TeamMemberId

		if m0, e := members[app.TeamMemberId]; e {
			m = m0
		}
		ma := mo_linkedapp.NewMemberLinkedApp(m, app)

		z.LinkedApp.Row(ma)
	}
	return nil
}

func (z *List) Test(c app_control.Control) error {
	if err := rc_exec.Exec(c, &List{}, rc_recipe.NoCustomValues); err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>// Package testsuite is a library of functions that may be
// useful for handler's testing.
// It is highly inspired by Revel Framework's testing package.
//
// Some methods require URI while others URN as their input parameters.
// For reference, URI is URL + URN. E.g. "https://example.com/test"
// is a URI, "https://example.com" is URL, and "/test" is URN.
package testsuite

import (
	"io/ioutil"
	"net/http"

	"github.com/anonx/sunplate/log"
)

// Type represents a test suite.
type Type struct {
	Client       *http.Client
	Response     *http.Response
	ResponseBody []byte
	URL          string
}

// Request represents a client HTTP request to server.
// It is a wrapper on standard http.Request that includes
// testsuite information, too.
type Request struct {
	*http.Request
	ts *Type
}

// New allocates and returns a new test suite.
// Server's URL is expected as an input argument.
func New(url string) *Type {
	return &Type{
		URL: url,
	}
}

// Send issues a request and reads the response. If successfull, the caller
// may examine the Response and ResponseBody properties.
func (r *Request) Send() {
	var err error
	if r.ts.Response, err = r.ts.Client.Do(r.Request); err != nil {
		log.Error.Panic(err)
	}
	if r.ts.ResponseBody, err = ioutil.ReadAll(r.ts.Response.Body); err != nil {
		log.Error.Panic(err)
	}
}

// Request allocates and returns a new Request
// for the requested testsuite.
func (t *Type) Request(req *http.Request) *Request {
	return &Request{
		Request: req,
		ts:      t,
	}
}

// Get issues a GET request to the given URN of server's URL
// and stores the result in Response and ResponseBody.
func (t *Type) Get(urn string) {
	log.Trace.Printf(`GET "%s"...`, urn)
	t.GetCustom(t.URL + urn).Send()
	log.Trace.Println("\tDONE.")
}

// GetCustom returns a GET request to the given URI in
// a form of Request structure.
func (t *Type) GetCustom(uri string) *Request {
	req, err := http.NewRequest("GET", uri, nil)
	if err != nil {
		log.Error.Panic(err)
	}
	return t.Request(req)
}
<commit_msg>Initialize client before use<commit_after>// Package testsuite is a library of functions that may be
// useful for handler's testing.
// It is highly inspired by Revel Framework's testing package.
//
// Some methods require URI while others URN as their input parameters.
// For reference, URI is URL + URN. E.g. "https://example.com/test"
// is a URI, "https://example.com" is URL, and "/test" is URN.
package testsuite

import (
	"io/ioutil"
	"net/http"

	"github.com/anonx/sunplate/log"
)

// Type represents a test suite.
type Type struct {
	Client       *http.Client
	Response     *http.Response
	ResponseBody []byte
	URL          string
}

// Request represents a client HTTP request to server.
// It is a wrapper on standard http.Request that includes
// testsuite information, too.
type Request struct {
	*http.Request
	ts *Type
}

// New allocates and returns a new test suite.
// Server's URL is expected as an input argument.
func New(url string) *Type {
	return &Type{
		Client: &http.Client{},
		URL:    url,
	}
}

// Send issues a request and reads the response. If successfull, the caller
// may examine the Response and ResponseBody properties.
func (r *Request) Send() {
	var err error
	if r.ts.Response, err = r.ts.Client.Do(r.Request); err != nil {
		log.Error.Panic(err)
	}
	if r.ts.ResponseBody, err = ioutil.ReadAll(r.ts.Response.Body); err != nil {
		log.Error.Panic(err)
	}
}

// Request allocates and returns a new Request
// for the requested testsuite.
func (t *Type) Request(req *http.Request) *Request {
	return &Request{
		Request: req,
		ts:      t,
	}
}

// Get issues a GET request to the given URN of server's URL
// and stores the result in Response and ResponseBody.
func (t *Type) Get(urn string) {
	log.Trace.Printf(`GET "%s"...`, urn)
	t.GetCustom(t.URL + urn).Send()
	log.Trace.Println("DONE.")
}

// GetCustom returns a GET request to the given URI in
// a form of Request structure.
func (t *Type) GetCustom(uri string) *Request {
	req, err := http.NewRequest("GET", uri, nil)
	if err != nil {
		log.Error.Panic(err)
	}
	return t.Request(req)
}
<|endoftext|>


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

package commands

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"text/tabwriter"

	"github.com/romana/core/cli/util"
	"github.com/romana/core/common"
	"github.com/romana/core/common/api"

	"github.com/go-resty/resty"
	ms "github.com/mitchellh/mapstructure"
	log "github.com/romana/rlog"
	cli "github.com/spf13/cobra"
	config "github.com/spf13/viper"
)

// Policies structure is used to keep track of
// security policies and their status, as to if
// they were applied successfully or not.
type Policies struct {
	SecurityPolicies    []api.Policy
	AppliedSuccessfully []bool
}

// policyCmd represents the policy commands
var policyCmd = &cli.Command{
	Use:   "policy [add|remove|list]",
	Short: "Add, Remove or List a policy.",
	Long: `Add, Remove or List a policy.

For more information, please check http://romana.io
`,
}

func init() {
	policyCmd.AddCommand(policyAddCmd)
	policyCmd.AddCommand(policyRemoveCmd)
	policyCmd.AddCommand(policyListCmd)
	policyCmd.AddCommand(policyShowCmd)
}

var policyAddCmd = &cli.Command{
	Use:          "add [policyFile]",
	Short:        "Add a new policy.",
	Long:         `Add a new policy.`,
	RunE:         policyAdd,
	SilenceUsage: true,
}

var policyRemoveCmd = &cli.Command{
	Use:          "remove [policyID]",
	Short:        "Remove a specific policy.",
	Long:         `Remove a specific policy.`,
	RunE:         policyRemove,
	SilenceUsage: true,
}

var policyListCmd = &cli.Command{
	Use:          "list",
	Short:        "List all policies.",
	Long:         `List all policies.`,
	RunE:         policyList,
	SilenceUsage: true,
}

var policyShowCmd = &cli.Command{
	Use:          "show [PolicyID]",
	Short:        "Show details about a specific policy using name or external id.",
	Long:         `Show details about a specific policy using name or external id.`,
	RunE:         policyShow,
	SilenceUsage: true,
}

// policyAdd adds romana policy for a specific tenant
// using the policyFile provided or through input pipe.
// The features supported are:
//  * Policy addition through file with single policy in it
//  * Policy addition through file with multiple policies
//    in it supporting the SecurityPolicies construct as
//    shown in policy/policy.sample.json
//  * Both the above formats but taking input from standard
//    input (STDIN) instead of a file
//  * Tabular and json output for indication of policy
//    addition
func policyAdd(cmd *cli.Command, args []string) error {
	var buf []byte
	var policyFile string
	var err error
	isFile := true
	isJSON := config.GetString("Format") == "json"

	if len(args) == 0 {
		isFile = false
		buf, err = ioutil.ReadAll(os.Stdin)
		if err != nil {
			util.UsageError(cmd,
				"POLICY FILE name or piped input from 'STDIN' expected.")
			return fmt.Errorf("Cannot read 'STDIN': %s\n", err)
		}
	} else if len(args) != 1 {
		return util.UsageError(cmd,
			"POLICY FILE name or piped input from 'STDIN' expected.")
	}

	if isFile {
		policyFile = args[0]
	}

	rootURL := config.GetString("RootURL")

	reqPolicies := Policies{}
	if isFile {
		pBuf, err := ioutil.ReadFile(policyFile)
		if err != nil {
			return fmt.Errorf("File error: %s\n", err)
		}
		err = json.Unmarshal(pBuf, &reqPolicies.SecurityPolicies)
		if err != nil || len(reqPolicies.SecurityPolicies) == 0 {
			reqPolicies.SecurityPolicies = make([]api.Policy, 1)
			err = json.Unmarshal(pBuf, &reqPolicies.SecurityPolicies[0])
			if err != nil {
				return err
			}
		}
	} else {
		err = json.Unmarshal(buf, &reqPolicies.SecurityPolicies)
		if err != nil || len(reqPolicies.SecurityPolicies) == 0 {
			reqPolicies.SecurityPolicies = make([]api.Policy, 1)
			err = json.Unmarshal(buf, &reqPolicies.SecurityPolicies[0])
			if err != nil {
				return err
			}
		}
	}

	result := make([]map[string]interface{}, len(reqPolicies.SecurityPolicies))
	reqPolicies.AppliedSuccessfully = make([]bool, len(reqPolicies.SecurityPolicies))
	for i, pol := range reqPolicies.SecurityPolicies {
		reqPolicies.AppliedSuccessfully[i] = false
		_, err := resty.R().SetBody(pol).Post(rootURL + "/policies")
		if err != nil {
			log.Printf("Error in applying policy: %v\n", err)
			continue
		}
		reqPolicies.AppliedSuccessfully[i] = true
	}

	if isJSON {
		for i := range reqPolicies.SecurityPolicies {
			// check if any of policy markers are present in the map.
			_, exOk := result[i]["external_id"]
			_, idOk := result[i]["id"]
			_, nmOk := result[i]["name"]
			if exOk || idOk || nmOk {
				var p api.Policy
				dc := &ms.DecoderConfig{TagName: "json", Result: &p}
				decoder, err := ms.NewDecoder(dc)
				if err != nil {
					continue
				}
				err = decoder.Decode(result[i])
				if err != nil {
					continue
				}
				body, err := json.MarshalIndent(p, "", "\t")
				if err != nil {
					continue
				}
				fmt.Println(string(body))
			} else {
				var h common.HttpError
				dc := &ms.DecoderConfig{TagName: "json", Result: &h}
				decoder, err := ms.NewDecoder(dc)
				if err != nil {
					continue
				}
				err = decoder.Decode(result[i])
				if err != nil {
					continue
				}
				status, _ := json.MarshalIndent(h, "", "\t")
				fmt.Println(string(status))
			}
		}
	} else {
		w := new(tabwriter.Writer)
		w.Init(os.Stdout, 0, 8, 0, '\t', 0)
		fmt.Println("New Policies Processed:")
		fmt.Fprintln(w, "Id\t",
			"Policy Name\t",
			"Direction\t",
			"Successful Applied?\t",
		)
		for i, pol := range reqPolicies.SecurityPolicies {
			// check if any of policy markers are present in the map.
			_, exOk := result[i]["external_id"]
			_, idOk := result[i]["id"]
			_, nmOk := result[i]["name"]
			if exOk || idOk || nmOk {
				var p api.Policy
				dc := &ms.DecoderConfig{TagName: "json", Result: &p}
				decoder, err := ms.NewDecoder(dc)
				if err != nil {
					continue
				}
				err = decoder.Decode(result[i])
				if err != nil {
					continue
				}
				fmt.Fprintf(w, "%s \t %s \t %t \n", p.ID,
					p.Direction, reqPolicies.AppliedSuccessfully[i])
			} else {
				fmt.Fprintf(w, "%s \t %s \t %t \n", pol.ID,
					pol.Direction, false)
			}
		}
		w.Flush()
	}

	return nil
}

// policyRemove removes policy using the policy name provided
// as argument through args. It returns error if policy is not
// found, or returns a list of policy ID's if multiple policies
// with same name are found.
func policyRemove(cmd *cli.Command, args []string) error {

	if len(args) != 1 {
		return fmt.Errorf("Policy remove takes exactly one argument i.e policy id.")
	}

	policyID := args[0]

	rootURL := config.GetString("RootURL")
	resp, err := resty.R().Delete(rootURL + "/policies/" + policyID)
	if err != nil {
		return err
	}

	if config.GetString("Format") == "json" {
		JSONFormat(resp.Body(), os.Stdout)
	} else {
		fmt.Printf("Policy (ID: %s) deleted successfully.\n", policyID)
	}

	return nil
}

// policyList lists policies in tabular or json format.
func policyList(cmd *cli.Command, args []string) error {
	if len(args) > 0 {
		return util.UsageError(cmd,
			"Policy listing takes no arguments.")
	}
	return policyListShow(true, nil)
}

// policyShow displays details about a specific policy
// in tabular or json format.
func policyShow(cmd *cli.Command, args []string) error {
	return policyListShow(false, args)
}

// policyListShow lists/shows policies in tabular or json format.
func policyListShow(listOnly bool, args []string) error {
	specificPolicies := false
	if len(args) > 0 {
		specificPolicies = true
	}

	if !listOnly && !specificPolicies {
		return fmt.Errorf("Policy show takes at-least one argument i.e policy id/s.")
	}

	rootURL := config.GetString("RootURL")
	resp, err := resty.R().Get(rootURL + "/policies")
	if err != nil {
		return err
	}

	allPolicies := []api.Policy{}
	policies := []api.Policy{}
	if listOnly {
		policies = allPolicies
	} else {
		if specificPolicies {
			for _, a := range args {
				for _, p := range allPolicies {
					if a == p.ID {
						policies = append(policies, p)
					}
				}
			}
		}
	}

	if config.GetString("Format") == "json" {
		JSONFormat(resp.Body(), os.Stdout)
	} else {
		w := new(tabwriter.Writer)
		w.Init(os.Stdout, 0, 8, 0, '\t', 0)
		if listOnly {
			fmt.Println("Policy List")
			fmt.Fprintln(w, "Policy Id\t",
				"Direction\t",
				"Applied to\t",
				"No of Peers\t",
				"No of Rules\t",
				"Description\t",
			)
		} else {
			fmt.Println("Policy Details")
		}
		for _, p := range policies {
			if listOnly {
				noOfPeers := 0
				noOfRules := 0
				for i := range p.Ingress {
					noOfPeers += len(p.Ingress[i].Peers)
					noOfRules += len(p.Ingress[i].Rules)
				}

				fmt.Fprintln(w, p.ID, "\t",
					p.Direction, "\t",
					len(p.AppliedTo), "\t",
					noOfPeers, "\t",
					noOfRules, "\t",
					p.Description, "\t",
				)
			} else {
				fmt.Fprint(w,
					"Policy Id:\t", p.ID, "\n",
					"Direction:\t", p.Direction, "\n",
					"Description:\t", p.Description, "\n",
				)
				if len(p.AppliedTo) > 0 {
					fmt.Fprintln(w, "Applied To:")
					for _, ato := range p.AppliedTo {
						fmt.Fprintln(w,
							"\tPeer:\t", ato.Peer, "\n",
							"\tCidr:\t", ato.Cidr, "\n",
							"\tDestination:\t", ato.Dest, "\n",
							"\tTenantID:\t", ato.TenantID, "\n",
							"\tSegmentID:\t", ato.SegmentID,
						)
					}
				}
				if len(p.Ingress) > 0 {
					for _, ingress := range p.Ingress {
						if len(ingress.Peers) > 0 {
							fmt.Fprintln(w, "Peers:")
							for _, peer := range ingress.Peers {
								fmt.Fprintln(w,
									"\tPeer:\t", peer.Peer, "\n",
									"\tCidr:\t", peer.Cidr, "\n",
									"\tDestination:\t", peer.Dest, "\n",
									"\tTenantID:\t", peer.TenantID, "\n",
									"\tSegmentID:\t", peer.SegmentID,
								)
							}
						}
						if len(ingress.Rules) > 0 {
							fmt.Fprintln(w, "Rules:")
							for _, rule := range ingress.Rules {
								fmt.Fprintln(w,
									"\tProtocol:\t", rule.Protocol, "\n",
									"\tIsStateful:\t", rule.IsStateful, "\n",
									"\tPorts:\t", rule.Ports, "\n",
									"\tPortRanges:\t", rule.PortRanges, "\n",
									"\tIcmpType:\t", rule.IcmpType, "\n",
									"\tIcmpCode:\t", rule.IcmpCode,
								)
							}
						}
					}
				}
				fmt.Fprintln(w, "")
			}
		}
		w.Flush()
	}

	return nil
}
<commit_msg>cli: update policy docs to reflect latest changes.<commit_after>// Copyright (c) 2016 Pani Networks
// All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

package commands

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"os"
	"text/tabwriter"

	"github.com/romana/core/cli/util"
	"github.com/romana/core/common"
	"github.com/romana/core/common/api"

	"github.com/go-resty/resty"
	ms "github.com/mitchellh/mapstructure"
	log "github.com/romana/rlog"
	cli "github.com/spf13/cobra"
	config "github.com/spf13/viper"
)

// Policies structure is used to keep track of
// security policies and their status, as to if
// they were applied successfully or not.
type Policies struct {
	SecurityPolicies    []api.Policy
	AppliedSuccessfully []bool
}

// policyCmd represents the policy commands
var policyCmd = &cli.Command{
	Use:   "policy [add|show|list|remove]",
	Short: "Add, Remove or Show policies for romana services.",
	Long: `Add, Remove or Show policies for romana services.

For more information, please check http://romana.io
`,
}

func init() {
	policyCmd.AddCommand(policyAddCmd)
	policyCmd.AddCommand(policyRemoveCmd)
	policyCmd.AddCommand(policyListCmd)
	policyCmd.AddCommand(policyShowCmd)
}

var policyAddCmd = &cli.Command{
	Use:   "add [policyFile][STDIN]",
	Short: "Add a new policy.",
	Long: `Add a new policy.

Romana policies can be added for a specific network
using the policyFile provided or through input pipe.
The features supported are:
 * Policy addition through file with single policy in it
 * Policy addition through file with multiple policies
   in it
 * Both the above formats but taking input from standard
   input (STDIN) instead of a file
 * Tabular and json output for indication of policy
   addition
`,
	RunE:         policyAdd,
	SilenceUsage: true,
}

var policyRemoveCmd = &cli.Command{
	Use:          "remove [policyID]",
	Short:        "Remove a specific policy.",
	Long:         `Remove a specific policy.`,
	RunE:         policyRemove,
	SilenceUsage: true,
}

var policyListCmd = &cli.Command{
	Use:          "list",
	Short:        "List all policies.",
	Long:         `List all policies.`,
	RunE:         policyList,
	SilenceUsage: true,
}

var policyShowCmd = &cli.Command{
	Use:          "show [PolicyID]",
	Short:        "Show details about a specific policy using policyID.",
	Long:         `Show details about a specific policy using policyID.`,
	RunE:         policyShow,
	SilenceUsage: true,
}

// policyAdd adds romana policy for a specific tenant
// using the policyFile provided or through input pipe.
// The features supported are:
//  * Policy addition through file with single policy in it
//  * Policy addition through file with multiple policies
//    in it
//  * Both the above formats but taking input from standard
//    input (STDIN) instead of a file
//  * Tabular and json output for indication of policy
//    addition
func policyAdd(cmd *cli.Command, args []string) error {
	var buf []byte
	var policyFile string
	var err error
	isFile := true
	isJSON := config.GetString("Format") == "json"

	if len(args) == 0 {
		isFile = false
		buf, err = ioutil.ReadAll(os.Stdin)
		if err != nil {
			util.UsageError(cmd,
				"POLICY FILE name or piped input from 'STDIN' expected.")
			return fmt.Errorf("Cannot read 'STDIN': %s\n", err)
		}
	} else if len(args) != 1 {
		return util.UsageError(cmd,
			"POLICY FILE name or piped input from 'STDIN' expected.")
	}

	if isFile {
		policyFile = args[0]
	}

	rootURL := config.GetString("RootURL")

	reqPolicies := Policies{}
	if isFile {
		pBuf, err := ioutil.ReadFile(policyFile)
		if err != nil {
			return fmt.Errorf("File error: %s\n", err)
		}
		err = json.Unmarshal(pBuf, &reqPolicies.SecurityPolicies)
		if err != nil || len(reqPolicies.SecurityPolicies) == 0 {
			reqPolicies.SecurityPolicies = make([]api.Policy, 1)
			err = json.Unmarshal(pBuf, &reqPolicies.SecurityPolicies[0])
			if err != nil {
				return err
			}
		}
	} else {
		err = json.Unmarshal(buf, &reqPolicies.SecurityPolicies)
		if err != nil || len(reqPolicies.SecurityPolicies) == 0 {
			reqPolicies.SecurityPolicies = make([]api.Policy, 1)
			err = json.Unmarshal(buf, &reqPolicies.SecurityPolicies[0])
			if err != nil {
				return err
			}
		}
	}

	result := make([]map[string]interface{}, len(reqPolicies.SecurityPolicies))
	reqPolicies.AppliedSuccessfully = make([]bool, len(reqPolicies.SecurityPolicies))
	for i, pol := range reqPolicies.SecurityPolicies {
		reqPolicies.AppliedSuccessfully[i] = false
		_, err := resty.R().SetBody(pol).Post(rootURL + "/policies")
		if err != nil {
			log.Printf("Error in applying policy: %v\n", err)
			continue
		}
		reqPolicies.AppliedSuccessfully[i] = true
	}

	if isJSON {
		for i := range reqPolicies.SecurityPolicies {
			// check if any of policy markers are present in the map.
			_, exOk := result[i]["external_id"]
			_, idOk := result[i]["id"]
			_, nmOk := result[i]["name"]
			if exOk || idOk || nmOk {
				var p api.Policy
				dc := &ms.DecoderConfig{TagName: "json", Result: &p}
				decoder, err := ms.NewDecoder(dc)
				if err != nil {
					continue
				}
				err = decoder.Decode(result[i])
				if err != nil {
					continue
				}
				body, err := json.MarshalIndent(p, "", "\t")
				if err != nil {
					continue
				}
				fmt.Println(string(body))
			} else {
				var h common.HttpError
				dc := &ms.DecoderConfig{TagName: "json", Result: &h}
				decoder, err := ms.NewDecoder(dc)
				if err != nil {
					continue
				}
				err = decoder.Decode(result[i])
				if err != nil {
					continue
				}
				status, _ := json.MarshalIndent(h, "", "\t")
				fmt.Println(string(status))
			}
		}
	} else {
		w := new(tabwriter.Writer)
		w.Init(os.Stdout, 0, 8, 0, '\t', 0)
		fmt.Println("New Policies Processed:")
		fmt.Fprintln(w, "Id\t",
			"Policy Name\t",
			"Direction\t",
			"Successful Applied?\t",
		)
		for i, pol := range reqPolicies.SecurityPolicies {
			// check if any of policy markers are present in the map.
			_, exOk := result[i]["external_id"]
			_, idOk := result[i]["id"]
			_, nmOk := result[i]["name"]
			if exOk || idOk || nmOk {
				var p api.Policy
				dc := &ms.DecoderConfig{TagName: "json", Result: &p}
				decoder, err := ms.NewDecoder(dc)
				if err != nil {
					continue
				}
				err = decoder.Decode(result[i])
				if err != nil {
					continue
				}
				fmt.Fprintf(w, "%s \t %s \t %t \n", p.ID,
					p.Direction, reqPolicies.AppliedSuccessfully[i])
			} else {
				fmt.Fprintf(w, "%s \t %s \t %t \n", pol.ID,
					pol.Direction, false)
			}
		}
		w.Flush()
	}

	return nil
}

// policyRemove removes policy using the policy name provided
// as argument through args. It returns error if policy is not
// found, or returns a list of policy ID's if multiple policies
// with same name are found.
func policyRemove(cmd *cli.Command, args []string) error {

	if len(args) != 1 {
		return fmt.Errorf("Policy remove takes exactly one argument i.e policy id.")
	}

	policyID := args[0]

	rootURL := config.GetString("RootURL")
	resp, err := resty.R().Delete(rootURL + "/policies/" + policyID)
	if err != nil {
		return err
	}

	if config.GetString("Format") == "json" {
		JSONFormat(resp.Body(), os.Stdout)
	} else {
		fmt.Printf("Policy (ID: %s) deleted successfully.\n", policyID)
	}

	return nil
}

// policyList lists policies in tabular or json format.
func policyList(cmd *cli.Command, args []string) error {
	if len(args) > 0 {
		return util.UsageError(cmd,
			"Policy listing takes no arguments.")
	}
	return policyListShow(true, nil)
}

// policyShow displays details about a specific policy
// in tabular or json format.
func policyShow(cmd *cli.Command, args []string) error {
	return policyListShow(false, args)
}

// policyListShow lists/shows policies in tabular or json format.
func policyListShow(listOnly bool, args []string) error {
	specificPolicies := false
	if len(args) > 0 {
		specificPolicies = true
	}

	if !listOnly && !specificPolicies {
		return fmt.Errorf("Policy show takes at-least one argument i.e policy id/s.")
	}

	rootURL := config.GetString("RootURL")
	resp, err := resty.R().Get(rootURL + "/policies")
	if err != nil {
		return err
	}

	allPolicies := []api.Policy{}
	policies := []api.Policy{}
	if listOnly {
		policies = allPolicies
	} else {
		if specificPolicies {
			for _, a := range args {
				for _, p := range allPolicies {
					if a == p.ID {
						policies = append(policies, p)
					}
				}
			}
		}
	}

	if config.GetString("Format") == "json" {
		JSONFormat(resp.Body(), os.Stdout)
	} else {
		w := new(tabwriter.Writer)
		w.Init(os.Stdout, 0, 8, 0, '\t', 0)
		if listOnly {
			fmt.Println("Policy List")
			fmt.Fprintln(w, "Policy Id\t",
				"Direction\t",
				"Applied to\t",
				"No of Peers\t",
				"No of Rules\t",
				"Description\t",
			)
		} else {
			fmt.Println("Policy Details")
		}
		for _, p := range policies {
			if listOnly {
				noOfPeers := 0
				noOfRules := 0
				for i := range p.Ingress {
					noOfPeers += len(p.Ingress[i].Peers)
					noOfRules += len(p.Ingress[i].Rules)
				}

				fmt.Fprintln(w, p.ID, "\t",
					p.Direction, "\t",
					len(p.AppliedTo), "\t",
					noOfPeers, "\t",
					noOfRules, "\t",
					p.Description, "\t",
				)
			} else {
				fmt.Fprint(w,
					"Policy Id:\t", p.ID, "\n",
					"Direction:\t", p.Direction, "\n",
					"Description:\t", p.Description, "\n",
				)
				if len(p.AppliedTo) > 0 {
					fmt.Fprintln(w, "Applied To:")
					for _, ato := range p.AppliedTo {
						fmt.Fprintln(w,
							"\tPeer:\t", ato.Peer, "\n",
							"\tCidr:\t", ato.Cidr, "\n",
							"\tDestination:\t", ato.Dest, "\n",
							"\tTenantID:\t", ato.TenantID, "\n",
							"\tSegmentID:\t", ato.SegmentID,
						)
					}
				}
				if len(p.Ingress) > 0 {
					for _, ingress := range p.Ingress {
						if len(ingress.Peers) > 0 {
							fmt.Fprintln(w, "Peers:")
							for _, peer := range ingress.Peers {
								fmt.Fprintln(w,
									"\tPeer:\t", peer.Peer, "\n",
									"\tCidr:\t", peer.Cidr, "\n",
									"\tDestination:\t", peer.Dest, "\n",
									"\tTenantID:\t", peer.TenantID, "\n",
									"\tSegmentID:\t", peer.SegmentID,
								)
							}
						}
						if len(ingress.Rules) > 0 {
							fmt.Fprintln(w, "Rules:")
							for _, rule := range ingress.Rules {
								fmt.Fprintln(w,
									"\tProtocol:\t", rule.Protocol, "\n",
									"\tIsStateful:\t", rule.IsStateful, "\n",
									"\tPorts:\t", rule.Ports, "\n",
									"\tPortRanges:\t", rule.PortRanges, "\n",
									"\tIcmpType:\t", rule.IcmpType, "\n",
									"\tIcmpCode:\t", rule.IcmpCode,
								)
							}
						}
					}
				}
				fmt.Fprintln(w, "")
			}
		}
		w.Flush()
	}

	return nil
}
<|endoftext|>


<commit_before>package exec

import (
	"archive/tar"
	"fmt"
	"io"
	"os"
	"path"
	"path/filepath"
	"strings"

	"code.cloudfoundry.org/clock"
	"code.cloudfoundry.org/garden"
	"code.cloudfoundry.org/lager"
	"github.com/concourse/atc"
	"github.com/concourse/atc/db"
	"github.com/concourse/atc/worker"
)

const taskProcessID = "task"
const taskExitStatusPropertyName = "concourse:exit-status"

// MissingInputsError is returned when any of the task's required inputs are
// missing.
type MissingInputsError struct {
	Inputs []string
}

// Error prints a human-friendly message listing the inputs that were missing.
func (err MissingInputsError) Error() string {
	return fmt.Sprintf("missing inputs: %s", strings.Join(err.Inputs, ", "))
}

type MissingTaskImageSourceError struct {
	SourceName string
}

func (err MissingTaskImageSourceError) Error() string {
	return fmt.Sprintf(`missing image artifact source: %s
make sure there's a corresponding 'get' step, or a task that produces it as an output`, err.SourceName)
}

// TaskStep executes a TaskConfig, whose inputs will be fetched from the
// worker.ArtifactRepository and outputs will be added to the worker.ArtifactRepository.
type TaskStep struct {
	logger            lager.Logger
	containerID       worker.Identifier
	metadata          worker.Metadata
	tags              atc.Tags
	teamID            int
	delegate          TaskDelegate
	privileged        Privileged
	configSource      TaskConfigSource
	workerPool        worker.Client
	artifactsRoot     string
	resourceTypes     atc.VersionedResourceTypes
	inputMapping      map[string]string
	outputMapping     map[string]string
	imageArtifactName string
	clock             clock.Clock
	repo              *worker.ArtifactRepository

	process garden.Process

	exitStatus int
}

func newTaskStep(
	logger lager.Logger,
	containerID worker.Identifier,
	metadata worker.Metadata,
	tags atc.Tags,
	teamID int,
	delegate TaskDelegate,
	privileged Privileged,
	configSource TaskConfigSource,
	workerPool worker.Client,
	artifactsRoot string,
	resourceTypes atc.VersionedResourceTypes,
	inputMapping map[string]string,
	outputMapping map[string]string,
	imageArtifactName string,
	clock clock.Clock,
) TaskStep {
	return TaskStep{
		logger:            logger,
		containerID:       containerID,
		metadata:          metadata,
		tags:              tags,
		teamID:            teamID,
		delegate:          delegate,
		privileged:        privileged,
		configSource:      configSource,
		workerPool:        workerPool,
		artifactsRoot:     artifactsRoot,
		resourceTypes:     resourceTypes,
		inputMapping:      inputMapping,
		outputMapping:     outputMapping,
		imageArtifactName: imageArtifactName,
		clock:             clock,
	}
}

// Using finishes construction of the TaskStep and returns a *TaskStep. If the
// *TaskStep errors, its error is reported to the delegate.
func (step TaskStep) Using(prev Step, repo *worker.ArtifactRepository) Step {
	step.repo = repo

	return errorReporter{
		Step:          &step,
		ReportFailure: step.delegate.Failed,
	}
}

// Run will first load the TaskConfig. A worker will be selected based on the
// TaskConfig's platform, the TaskStep's tags, and prioritized by availability
// of volumes for the TaskConfig's inputs. Inputs that did not have volumes
// available on the worker will be streamed in to the container.
//
// If any inputs are not available in the worker.ArtifactRepository, MissingInputsError
// is returned.
//
// Once all the inputs are satisfies, the task's script will be executed, and
// the RunStep indicates that it's ready, and any signals will be forwarded to
// the script.
//
// If the script exits successfully, the outputs specified in the TaskConfig
// are registered with the worker.ArtifactRepository. If no outputs are specified, the
// task's entire working directory is registered as an ArtifactSource under the
// name of the task.
func (step *TaskStep) Run(signals <-chan os.Signal, ready chan<- struct{}) error {
	processIO := garden.ProcessIO{
		Stdout: step.delegate.Stdout(),
		Stderr: step.delegate.Stderr(),
	}

	deprecationConfigSource := DeprecationConfigSource{
		Delegate: step.configSource,
		Stderr:   step.delegate.Stderr(),
	}

	config, err := deprecationConfigSource.FetchConfig(step.repo)
	if err != nil {
		return err
	}

	step.metadata.EnvironmentVariables = step.envForParams(config.Params)

	containerSpec, err := step.containerSpec(config)
	if err != nil {
		return err
	}

	runContainerID := step.containerID
	runContainerID.Stage = db.ContainerStageRun

	step.delegate.Initializing(config)

	container, err := step.workerPool.FindOrCreateBuildContainer(
		step.logger,
		signals,
		step.delegate,
		runContainerID,
		step.metadata,
		containerSpec,
		step.resourceTypes,
	)
	if err != nil {
		return err
	}

	exitStatusProp, err := container.Property(taskExitStatusPropertyName)
	if err == nil {
		step.logger.Info("already-exited", lager.Data{"status": exitStatusProp})

		_, err = fmt.Sscanf(exitStatusProp, "%d", &step.exitStatus)
		if err != nil {
			return err
		}

		step.registerSource(config, container)
		return nil
	}

	step.process, err = container.Attach(taskProcessID, processIO)
	if err == nil {
		step.logger.Info("already-running")
	} else {
		step.logger.Info("spawning")

		step.process, err = container.Run(garden.ProcessSpec{
			ID: taskProcessID,

			Path: config.Run.Path,
			Args: config.Run.Args,
			Env:  step.envForParams(config.Params),

			Dir: path.Join(step.artifactsRoot, config.Run.Dir),
			TTY: &garden.TTYSpec{},
		}, processIO)

		step.delegate.Started()
	}
	if err != nil {
		return err
	}

	step.logger.Info("attached")

	close(ready)

	exited := make(chan struct{})
	var processStatus int
	var processErr error

	go func() {
		processStatus, processErr = step.process.Wait()
		close(exited)
	}()

	select {
	case <-signals:
		step.registerSource(config, container)

		err = container.Stop(false)
		if err != nil {
			step.logger.Error("stopping-container", err)
		}

		<-exited

		return ErrInterrupted

	case <-exited:
		if processErr != nil {
			return processErr
		}

		step.registerSource(config, container)

		step.exitStatus = processStatus

		err := container.SetProperty(taskExitStatusPropertyName, fmt.Sprintf("%d", processStatus))
		if err != nil {
			return err
		}

		step.delegate.Finished(ExitStatus(processStatus))

		return nil
	}
}

func (step *TaskStep) containerSpec(config atc.TaskConfig) (worker.ContainerSpec, error) {
	imageSpec := worker.ImageSpec{
		Privileged: bool(step.privileged),
	}
	if step.imageArtifactName != "" {
		source, found := step.repo.SourceFor(worker.ArtifactName(step.imageArtifactName))
		if !found {
			return worker.ContainerSpec{}, MissingTaskImageSourceError{step.imageArtifactName}
		}

		imageSpec.ImageArtifactSource = source
		imageSpec.ImageArtifactName = worker.ArtifactName(step.imageArtifactName)
	} else {
		imageSpec.ImageURL = config.Image
		imageSpec.ImageResource = config.ImageResource
	}

	containerSpec := worker.ContainerSpec{
		Platform:  config.Platform,
		Tags:      step.tags,
		TeamID:    step.teamID,
		ImageSpec: imageSpec,
		User:      config.Run.User,
		Dir:       step.artifactsRoot,

		Inputs:  []worker.InputSource{},
		Outputs: worker.OutputPaths{},
	}

	var missingInputs []string
	for _, input := range config.Inputs {
		inputName := input.Name
		if sourceName, ok := step.inputMapping[inputName]; ok {
			inputName = sourceName
		}

		source, found := step.repo.SourceFor(worker.ArtifactName(inputName))
		if !found {
			missingInputs = append(missingInputs, inputName)
			continue
		}

		containerSpec.Inputs = append(containerSpec.Inputs, &taskInputSource{
			name:          worker.ArtifactName(inputName),
			config:        input,
			source:        source,
			artifactsRoot: step.artifactsRoot,
		})
	}

	if len(missingInputs) > 0 {
		return worker.ContainerSpec{}, MissingInputsError{missingInputs}
	}

	for _, output := range config.Outputs {
		path := artifactsPath(output, step.artifactsRoot)
		containerSpec.Outputs[output.Name] = path
	}

	return containerSpec, nil
}

func (step *TaskStep) registerSource(config atc.TaskConfig, container worker.Container) {
	volumeMounts := container.VolumeMounts()

	step.logger.Debug("registering-outputs", lager.Data{"config": config})

	for _, output := range config.Outputs {
		outputName := output.Name
		if destinationName, ok := step.outputMapping[output.Name]; ok {
			outputName = destinationName
		}

		outputPath := artifactsPath(output, step.artifactsRoot)

		for _, mount := range volumeMounts {
			if mount.MountPath == outputPath {
				source := newVolumeSource(step.logger, mount.Volume)
				step.repo.RegisterSource(worker.ArtifactName(outputName), source)
			}
		}
	}
}

// Result indicates Success as true if the script's exit status was 0.
//
// It also indicates ExitStatus as the exit status of the script.
//
// All other types are ignored.
func (step *TaskStep) Result(x interface{}) bool {
	switch v := x.(type) {
	case *Success:
		*v = step.exitStatus == 0
		return true

	case *ExitStatus:
		*v = ExitStatus(step.exitStatus)
		return true

	default:
		return false
	}
}

func (TaskStep) envForParams(params map[string]string) []string {
	env := make([]string, 0, len(params))

	for k, v := range params {
		env = append(env, k+"="+v)
	}

	return env
}

type volumeSource struct {
	logger lager.Logger
	volume worker.Volume
}

func newVolumeSource(
	logger lager.Logger,
	volume worker.Volume,
) *volumeSource {
	return &volumeSource{
		logger: logger,
		volume: volume,
	}
}

func (src *volumeSource) StreamTo(destination worker.ArtifactDestination) error {
	out, err := src.volume.StreamOut(".")
	if err != nil {
		return err
	}

	defer out.Close()

	return destination.StreamIn(".", out)
}

func (src *volumeSource) StreamFile(filename string) (io.ReadCloser, error) {
	out, err := src.volume.StreamOut(filename)
	if err != nil {
		return nil, err
	}

	tarReader := tar.NewReader(out)

	_, err = tarReader.Next()
	if err != nil {
		return nil, FileNotFoundError{Path: filename}
	}

	return fileReadCloser{
		Reader: tarReader,
		Closer: out,
	}, nil
}

func (src *volumeSource) VolumeOn(w worker.Worker) (worker.Volume, bool, error) {
	return w.LookupVolume(src.logger, src.volume.Handle())
}

type taskInputSource struct {
	name          worker.ArtifactName
	config        atc.TaskInputConfig
	source        worker.ArtifactSource
	artifactsRoot string
}

func (s *taskInputSource) Name() worker.ArtifactName     { return s.name }
func (s *taskInputSource) Source() worker.ArtifactSource { return s.source }

func (s *taskInputSource) DestinationPath() string {
	subdir := s.config.Path
	if s.config.Path == "" {
		subdir = s.config.Name
	}

	return filepath.Join(s.artifactsRoot, subdir)
}

func artifactsPath(outputConfig atc.TaskOutputConfig, artifactsRoot string) string {
	outputSrc := outputConfig.Path
	if len(outputSrc) == 0 {
		outputSrc = outputConfig.Name
	}

	return path.Join(artifactsRoot, outputSrc) + "/"
}
<commit_msg>start task delegate before running container process<commit_after>package exec

import (
	"archive/tar"
	"fmt"
	"io"
	"os"
	"path"
	"path/filepath"
	"strings"

	"code.cloudfoundry.org/clock"
	"code.cloudfoundry.org/garden"
	"code.cloudfoundry.org/lager"
	"github.com/concourse/atc"
	"github.com/concourse/atc/db"
	"github.com/concourse/atc/worker"
)

const taskProcessID = "task"
const taskExitStatusPropertyName = "concourse:exit-status"

// MissingInputsError is returned when any of the task's required inputs are
// missing.
type MissingInputsError struct {
	Inputs []string
}

// Error prints a human-friendly message listing the inputs that were missing.
func (err MissingInputsError) Error() string {
	return fmt.Sprintf("missing inputs: %s", strings.Join(err.Inputs, ", "))
}

type MissingTaskImageSourceError struct {
	SourceName string
}

func (err MissingTaskImageSourceError) Error() string {
	return fmt.Sprintf(`missing image artifact source: %s
make sure there's a corresponding 'get' step, or a task that produces it as an output`, err.SourceName)
}

// TaskStep executes a TaskConfig, whose inputs will be fetched from the
// worker.ArtifactRepository and outputs will be added to the worker.ArtifactRepository.
type TaskStep struct {
	logger            lager.Logger
	containerID       worker.Identifier
	metadata          worker.Metadata
	tags              atc.Tags
	teamID            int
	delegate          TaskDelegate
	privileged        Privileged
	configSource      TaskConfigSource
	workerPool        worker.Client
	artifactsRoot     string
	resourceTypes     atc.VersionedResourceTypes
	inputMapping      map[string]string
	outputMapping     map[string]string
	imageArtifactName string
	clock             clock.Clock
	repo              *worker.ArtifactRepository

	process garden.Process

	exitStatus int
}

func newTaskStep(
	logger lager.Logger,
	containerID worker.Identifier,
	metadata worker.Metadata,
	tags atc.Tags,
	teamID int,
	delegate TaskDelegate,
	privileged Privileged,
	configSource TaskConfigSource,
	workerPool worker.Client,
	artifactsRoot string,
	resourceTypes atc.VersionedResourceTypes,
	inputMapping map[string]string,
	outputMapping map[string]string,
	imageArtifactName string,
	clock clock.Clock,
) TaskStep {
	return TaskStep{
		logger:            logger,
		containerID:       containerID,
		metadata:          metadata,
		tags:              tags,
		teamID:            teamID,
		delegate:          delegate,
		privileged:        privileged,
		configSource:      configSource,
		workerPool:        workerPool,
		artifactsRoot:     artifactsRoot,
		resourceTypes:     resourceTypes,
		inputMapping:      inputMapping,
		outputMapping:     outputMapping,
		imageArtifactName: imageArtifactName,
		clock:             clock,
	}
}

// Using finishes construction of the TaskStep and returns a *TaskStep. If the
// *TaskStep errors, its error is reported to the delegate.
func (step TaskStep) Using(prev Step, repo *worker.ArtifactRepository) Step {
	step.repo = repo

	return errorReporter{
		Step:          &step,
		ReportFailure: step.delegate.Failed,
	}
}

// Run will first load the TaskConfig. A worker will be selected based on the
// TaskConfig's platform, the TaskStep's tags, and prioritized by availability
// of volumes for the TaskConfig's inputs. Inputs that did not have volumes
// available on the worker will be streamed in to the container.
//
// If any inputs are not available in the worker.ArtifactRepository, MissingInputsError
// is returned.
//
// Once all the inputs are satisfies, the task's script will be executed, and
// the RunStep indicates that it's ready, and any signals will be forwarded to
// the script.
//
// If the script exits successfully, the outputs specified in the TaskConfig
// are registered with the worker.ArtifactRepository. If no outputs are specified, the
// task's entire working directory is registered as an ArtifactSource under the
// name of the task.
func (step *TaskStep) Run(signals <-chan os.Signal, ready chan<- struct{}) error {
	processIO := garden.ProcessIO{
		Stdout: step.delegate.Stdout(),
		Stderr: step.delegate.Stderr(),
	}

	deprecationConfigSource := DeprecationConfigSource{
		Delegate: step.configSource,
		Stderr:   step.delegate.Stderr(),
	}

	config, err := deprecationConfigSource.FetchConfig(step.repo)
	if err != nil {
		return err
	}

	step.metadata.EnvironmentVariables = step.envForParams(config.Params)

	containerSpec, err := step.containerSpec(config)
	if err != nil {
		return err
	}

	runContainerID := step.containerID
	runContainerID.Stage = db.ContainerStageRun

	step.delegate.Initializing(config)

	container, err := step.workerPool.FindOrCreateBuildContainer(
		step.logger,
		signals,
		step.delegate,
		runContainerID,
		step.metadata,
		containerSpec,
		step.resourceTypes,
	)
	if err != nil {
		return err
	}

	exitStatusProp, err := container.Property(taskExitStatusPropertyName)
	if err == nil {
		step.logger.Info("already-exited", lager.Data{"status": exitStatusProp})

		_, err = fmt.Sscanf(exitStatusProp, "%d", &step.exitStatus)
		if err != nil {
			return err
		}

		step.registerSource(config, container)
		return nil
	}

	step.process, err = container.Attach(taskProcessID, processIO)
	if err == nil {
		step.logger.Info("already-running")
	} else {
		step.logger.Info("spawning")

		step.delegate.Started()

		step.process, err = container.Run(garden.ProcessSpec{
			ID: taskProcessID,

			Path: config.Run.Path,
			Args: config.Run.Args,
			Env:  step.envForParams(config.Params),

			Dir: path.Join(step.artifactsRoot, config.Run.Dir),
			TTY: &garden.TTYSpec{},
		}, processIO)
	}
	if err != nil {
		return err
	}

	step.logger.Info("attached")

	close(ready)

	exited := make(chan struct{})
	var processStatus int
	var processErr error

	go func() {
		processStatus, processErr = step.process.Wait()
		close(exited)
	}()

	select {
	case <-signals:
		step.registerSource(config, container)

		err = container.Stop(false)
		if err != nil {
			step.logger.Error("stopping-container", err)
		}

		<-exited

		return ErrInterrupted

	case <-exited:
		if processErr != nil {
			return processErr
		}

		step.registerSource(config, container)

		step.exitStatus = processStatus

		err := container.SetProperty(taskExitStatusPropertyName, fmt.Sprintf("%d", processStatus))
		if err != nil {
			return err
		}

		step.delegate.Finished(ExitStatus(processStatus))

		return nil
	}
}

func (step *TaskStep) containerSpec(config atc.TaskConfig) (worker.ContainerSpec, error) {
	imageSpec := worker.ImageSpec{
		Privileged: bool(step.privileged),
	}
	if step.imageArtifactName != "" {
		source, found := step.repo.SourceFor(worker.ArtifactName(step.imageArtifactName))
		if !found {
			return worker.ContainerSpec{}, MissingTaskImageSourceError{step.imageArtifactName}
		}

		imageSpec.ImageArtifactSource = source
		imageSpec.ImageArtifactName = worker.ArtifactName(step.imageArtifactName)
	} else {
		imageSpec.ImageURL = config.Image
		imageSpec.ImageResource = config.ImageResource
	}

	containerSpec := worker.ContainerSpec{
		Platform:  config.Platform,
		Tags:      step.tags,
		TeamID:    step.teamID,
		ImageSpec: imageSpec,
		User:      config.Run.User,
		Dir:       step.artifactsRoot,

		Inputs:  []worker.InputSource{},
		Outputs: worker.OutputPaths{},
	}

	var missingInputs []string
	for _, input := range config.Inputs {
		inputName := input.Name
		if sourceName, ok := step.inputMapping[inputName]; ok {
			inputName = sourceName
		}

		source, found := step.repo.SourceFor(worker.ArtifactName(inputName))
		if !found {
			missingInputs = append(missingInputs, inputName)
			continue
		}

		containerSpec.Inputs = append(containerSpec.Inputs, &taskInputSource{
			name:          worker.ArtifactName(inputName),
			config:        input,
			source:        source,
			artifactsRoot: step.artifactsRoot,
		})
	}

	if len(missingInputs) > 0 {
		return worker.ContainerSpec{}, MissingInputsError{missingInputs}
	}

	for _, output := range config.Outputs {
		path := artifactsPath(output, step.artifactsRoot)
		containerSpec.Outputs[output.Name] = path
	}

	return containerSpec, nil
}

func (step *TaskStep) registerSource(config atc.TaskConfig, container worker.Container) {
	volumeMounts := container.VolumeMounts()

	step.logger.Debug("registering-outputs", lager.Data{"config": config})

	for _, output := range config.Outputs {
		outputName := output.Name
		if destinationName, ok := step.outputMapping[output.Name]; ok {
			outputName = destinationName
		}

		outputPath := artifactsPath(output, step.artifactsRoot)

		for _, mount := range volumeMounts {
			if mount.MountPath == outputPath {
				source := newVolumeSource(step.logger, mount.Volume)
				step.repo.RegisterSource(worker.ArtifactName(outputName), source)
			}
		}
	}
}

// Result indicates Success as true if the script's exit status was 0.
//
// It also indicates ExitStatus as the exit status of the script.
//
// All other types are ignored.
func (step *TaskStep) Result(x interface{}) bool {
	switch v := x.(type) {
	case *Success:
		*v = step.exitStatus == 0
		return true

	case *ExitStatus:
		*v = ExitStatus(step.exitStatus)
		return true

	default:
		return false
	}
}

func (TaskStep) envForParams(params map[string]string) []string {
	env := make([]string, 0, len(params))

	for k, v := range params {
		env = append(env, k+"="+v)
	}

	return env
}

type volumeSource struct {
	logger lager.Logger
	volume worker.Volume
}

func newVolumeSource(
	logger lager.Logger,
	volume worker.Volume,
) *volumeSource {
	return &volumeSource{
		logger: logger,
		volume: volume,
	}
}

func (src *volumeSource) StreamTo(destination worker.ArtifactDestination) error {
	out, err := src.volume.StreamOut(".")
	if err != nil {
		return err
	}

	defer out.Close()

	return destination.StreamIn(".", out)
}

func (src *volumeSource) StreamFile(filename string) (io.ReadCloser, error) {
	out, err := src.volume.StreamOut(filename)
	if err != nil {
		return nil, err
	}

	tarReader := tar.NewReader(out)

	_, err = tarReader.Next()
	if err != nil {
		return nil, FileNotFoundError{Path: filename}
	}

	return fileReadCloser{
		Reader: tarReader,
		Closer: out,
	}, nil
}

func (src *volumeSource) VolumeOn(w worker.Worker) (worker.Volume, bool, error) {
	return w.LookupVolume(src.logger, src.volume.Handle())
}

type taskInputSource struct {
	name          worker.ArtifactName
	config        atc.TaskInputConfig
	source        worker.ArtifactSource
	artifactsRoot string
}

func (s *taskInputSource) Name() worker.ArtifactName     { return s.name }
func (s *taskInputSource) Source() worker.ArtifactSource { return s.source }

func (s *taskInputSource) DestinationPath() string {
	subdir := s.config.Path
	if s.config.Path == "" {
		subdir = s.config.Name
	}

	return filepath.Join(s.artifactsRoot, subdir)
}

func artifactsPath(outputConfig atc.TaskOutputConfig, artifactsRoot string) string {
	outputSrc := outputConfig.Path
	if len(outputSrc) == 0 {
		outputSrc = outputConfig.Name
	}

	return path.Join(artifactsRoot, outputSrc) + "/"
}
<|endoftext|>


<commit_before>package ln

import (
	"fmt"
	"io/ioutil"
	"strings"

	"github.com/fogleman/gg"
)

type Path []Vector

func (p Path) BoundingBox() Box {
	box := Box{p[0], p[0]}
	for _, v := range p {
		box = box.Extend(Box{v, v})
	}
	return box
}

func (p Path) Transform(matrix Matrix) Path {
	var result Path
	for _, v := range p {
		result = append(result, matrix.MulPosition(v))
	}
	return result
}

func (p Path) Chop(step float64) Path {
	var result Path
	for i := 0; i < len(p)-1; i++ {
		a := p[i]
		b := p[i+1]
		v := b.Sub(a)
		l := v.Length()
		if i == 0 {
			result = append(result, a)
		}
		d := step
		for d < l {
			result = append(result, a.Add(v.MulScalar(d/l)))
			d += step
		}
		result = append(result, b)
	}
	return result
}

func (p Path) Filter(f Filter) Paths {
	var result Paths
	var path Path
	for _, v := range p {
		v, ok := f.Filter(v)
		// ok = ok || i%8 < 4 // show hidden lines
		if ok {
			path = append(path, v)
		} else {
			if len(path) > 1 {
				result = append(result, path)
			}
			path = nil
		}
	}
	if len(path) > 1 {
		result = append(result, path)
	}
	return result
}

func (p Path) Simplify(threshold float64) Path {
	if len(p) < 3 {
		return p
	}
	a := p[0]
	b := p[len(p)-1]
	index := -1
	distance := 0.0
	for i := 1; i < len(p)-1; i++ {
		d := p[i].SegmentDistance(a, b)
		if d > distance {
			index = i
			distance = d
		}
	}
	if distance > threshold {
		r1 := p[:index+1].Simplify(threshold)
		r2 := p[index:].Simplify(threshold)
		return append(r1[:len(r1)-1], r2...)
	} else {
		return Path{a, b}
	}
}

func (p Path) Print() {
	for _, v := range p {
		fmt.Printf("%g,%g;", v.X, v.Y)
	}
	fmt.Println()
}

func (p Path) String() string {
	var parts []string
	for _, v := range p {
		parts = append(parts, fmt.Sprintf("%g,%g", v.X, v.Y))
	}
	return strings.Join(parts, ";")
}

func (p Path) ToSVG() string {
	var coords []string
	for _, v := range p {
		coords = append(coords, fmt.Sprintf("%f,%f", v.X, v.Y))
	}
	points := strings.Join(coords, " ")
	return fmt.Sprintf("<polyline stroke=\"black\" fill=\"none\" points=\"%s\" />", points)
}

type Paths []Path

func (p Paths) BoundingBox() Box {
	box := p[0].BoundingBox()
	for _, path := range p {
		box = box.Extend(path.BoundingBox())
	}
	return box
}

func (p Paths) Transform(matrix Matrix) Paths {
	var result Paths
	for _, path := range p {
		result = append(result, path.Transform(matrix))
	}
	return result
}

func (p Paths) Chop(step float64) Paths {
	var result Paths
	for _, path := range p {
		result = append(result, path.Chop(step))
	}
	return result
}

func (p Paths) Filter(f Filter) Paths {
	var result Paths
	for _, path := range p {
		result = append(result, path.Filter(f)...)
	}
	return result
}

func (p Paths) Simplify(threshold float64) Paths {
	var result Paths
	for _, path := range p {
		result = append(result, path.Simplify(threshold))
	}
	return result
}

func (p Paths) Print() {
	for _, path := range p {
		path.Print()
	}
}

func (p Paths) String() string {
	var parts []string
	for _, path := range p {
		parts = append(parts, path.String())
	}
	return strings.Join(parts, "\n")
}

func (p Paths) WriteToPNG(path string, width, height float64) {
	scale := 1.0
	w, h := int(width*scale), int(height*scale)
	dc := gg.NewContext(w, h)
	dc.SetRGB(1, 1, 1)
	dc.Clear()
	dc.SetRGB(0, 0, 0)
	dc.SetLineWidth(3)
	for _, path := range p {
		for i, v := range path {
			if i == 0 {
				dc.MoveTo(v.X*scale, float64(h)-v.Y*scale)
			} else {
				dc.LineTo(v.X*scale, float64(h)-v.Y*scale)
			}
		}
	}
	dc.Stroke()
	dc.SavePNG(path)
}

func (p Paths) ToSVG(width, height float64) string {
	var lines []string
	lines = append(lines, fmt.Sprintf("<svg width=\"%f\" height=\"%f\" version=\"1.1\" baseProfile=\"full\" xmlns=\"http://www.w3.org/2000/svg\">", width, height))
	lines = append(lines, fmt.Sprintf("<g transform=\"translate(0,%f) scale(1,-1)\">", height))
	for _, path := range p {
		lines = append(lines, path.ToSVG())
	}
	lines = append(lines, "</g></svg>")
	return strings.Join(lines, "\n")
}

func (p Paths) WriteToSVG(path string, width, height float64) error {
	return ioutil.WriteFile(path, []byte(p.ToSVG(width, height)), 0644)
}

func (p Paths) WriteToTXT(path string) error {
	return ioutil.WriteFile(path, []byte(p.String()), 0644)
}
<commit_msg>InvertY(), NewSubPath()<commit_after>package ln

import (
	"fmt"
	"io/ioutil"
	"strings"

	"github.com/fogleman/gg"
)

type Path []Vector

func (p Path) BoundingBox() Box {
	box := Box{p[0], p[0]}
	for _, v := range p {
		box = box.Extend(Box{v, v})
	}
	return box
}

func (p Path) Transform(matrix Matrix) Path {
	var result Path
	for _, v := range p {
		result = append(result, matrix.MulPosition(v))
	}
	return result
}

func (p Path) Chop(step float64) Path {
	var result Path
	for i := 0; i < len(p)-1; i++ {
		a := p[i]
		b := p[i+1]
		v := b.Sub(a)
		l := v.Length()
		if i == 0 {
			result = append(result, a)
		}
		d := step
		for d < l {
			result = append(result, a.Add(v.MulScalar(d/l)))
			d += step
		}
		result = append(result, b)
	}
	return result
}

func (p Path) Filter(f Filter) Paths {
	var result Paths
	var path Path
	for _, v := range p {
		v, ok := f.Filter(v)
		// ok = ok || i%8 < 4 // show hidden lines
		if ok {
			path = append(path, v)
		} else {
			if len(path) > 1 {
				result = append(result, path)
			}
			path = nil
		}
	}
	if len(path) > 1 {
		result = append(result, path)
	}
	return result
}

func (p Path) Simplify(threshold float64) Path {
	if len(p) < 3 {
		return p
	}
	a := p[0]
	b := p[len(p)-1]
	index := -1
	distance := 0.0
	for i := 1; i < len(p)-1; i++ {
		d := p[i].SegmentDistance(a, b)
		if d > distance {
			index = i
			distance = d
		}
	}
	if distance > threshold {
		r1 := p[:index+1].Simplify(threshold)
		r2 := p[index:].Simplify(threshold)
		return append(r1[:len(r1)-1], r2...)
	} else {
		return Path{a, b}
	}
}

func (p Path) Print() {
	for _, v := range p {
		fmt.Printf("%g,%g;", v.X, v.Y)
	}
	fmt.Println()
}

func (p Path) String() string {
	var parts []string
	for _, v := range p {
		parts = append(parts, fmt.Sprintf("%g,%g", v.X, v.Y))
	}
	return strings.Join(parts, ";")
}

func (p Path) ToSVG() string {
	var coords []string
	for _, v := range p {
		coords = append(coords, fmt.Sprintf("%f,%f", v.X, v.Y))
	}
	points := strings.Join(coords, " ")
	return fmt.Sprintf("<polyline stroke=\"black\" fill=\"none\" points=\"%s\" />", points)
}

type Paths []Path

func (p Paths) BoundingBox() Box {
	box := p[0].BoundingBox()
	for _, path := range p {
		box = box.Extend(path.BoundingBox())
	}
	return box
}

func (p Paths) Transform(matrix Matrix) Paths {
	var result Paths
	for _, path := range p {
		result = append(result, path.Transform(matrix))
	}
	return result
}

func (p Paths) Chop(step float64) Paths {
	var result Paths
	for _, path := range p {
		result = append(result, path.Chop(step))
	}
	return result
}

func (p Paths) Filter(f Filter) Paths {
	var result Paths
	for _, path := range p {
		result = append(result, path.Filter(f)...)
	}
	return result
}

func (p Paths) Simplify(threshold float64) Paths {
	var result Paths
	for _, path := range p {
		result = append(result, path.Simplify(threshold))
	}
	return result
}

func (p Paths) Print() {
	for _, path := range p {
		path.Print()
	}
}

func (p Paths) String() string {
	var parts []string
	for _, path := range p {
		parts = append(parts, path.String())
	}
	return strings.Join(parts, "\n")
}

func (p Paths) WriteToPNG(path string, width, height float64) {
	scale := 1.0
	w, h := int(width*scale), int(height*scale)
	dc := gg.NewContext(w, h)
	dc.InvertY()
	dc.SetRGB(1, 1, 1)
	dc.Clear()
	dc.SetRGB(0, 0, 0)
	dc.SetLineWidth(3)
	for _, path := range p {
		for _, v := range path {
			dc.LineTo(v.X*scale, v.Y*scale)
		}
		dc.NewSubPath()
	}
	dc.Stroke()
	dc.SavePNG(path)
}

func (p Paths) ToSVG(width, height float64) string {
	var lines []string
	lines = append(lines, fmt.Sprintf("<svg width=\"%f\" height=\"%f\" version=\"1.1\" baseProfile=\"full\" xmlns=\"http://www.w3.org/2000/svg\">", width, height))
	lines = append(lines, fmt.Sprintf("<g transform=\"translate(0,%f) scale(1,-1)\">", height))
	for _, path := range p {
		lines = append(lines, path.ToSVG())
	}
	lines = append(lines, "</g></svg>")
	return strings.Join(lines, "\n")
}

func (p Paths) WriteToSVG(path string, width, height float64) error {
	return ioutil.WriteFile(path, []byte(p.ToSVG(width, height)), 0644)
}

func (p Paths) WriteToTXT(path string) error {
	return ioutil.WriteFile(path, []byte(p.String()), 0644)
}
<|endoftext|>


<commit_before>package log

import (
	"fmt"
	"os"
	"runtime"
	"time"
)

const (
	LevelTrace = iota
	LevelDebug
	LevelInfo
	LevelWarn
	LevelError
	LevelFatal
)

const (
	Ltime  = iota << 1 //time format "2006/01/02 15:04:05"
	Lfile              //file.go:123
	Llevel             //[Trace|Debug|Info...]
)

var LevelName [6]string = [6]string{"Trace", "Debug", "Info", "Warn", "Error", "Fatal"}

const TimeFormat = "2006/01/02 15:04:05"

type Logger struct {
	level int
	flag  int

	handler Handler

	quit chan struct{}
	msg  chan []byte
}

func New(handler Handler, flag int) *Logger {
	var l = new(Logger)

	l.level = LevelInfo
	l.handler = handler

	l.flag = flag

	l.quit = make(chan struct{})

	l.msg = make(chan []byte, 1024)

	go l.run()

	return l
}

func NewDefault(handler Handler) *Logger {
	return New(handler, Ltime|Lfile|Llevel)
}

func newStdHandler() *StreamHandler {
	h, _ := NewStreamHandler(os.Stdout)
	return h
}

var std = NewDefault(newStdHandler())

func (l *Logger) run() {
	for {
		select {
		case msg := <-l.msg:
			l.handler.Write(msg)
		case <-l.quit:
			l.handler.Close()
		}
	}
}

func (l *Logger) Close() {
	if l.quit == nil {
		return
	}

	close(l.quit)
	l.quit = nil
}

func (l *Logger) SetLevel(level int) {
	l.level = level
}

func (l *Logger) Output(callDepth int, level int, format string, v ...interface{}) {
	if l.level > level {
		return
	}

	buf := make([]byte, 0, 1024)

	if l.flag&Ltime > 0 {
		now := time.Now().Format(TimeFormat)
		buf = append(buf, now...)
		buf = append(buf, " "...)
	}

	if l.flag&Lfile > 0 {
		_, file, line, ok := runtime.Caller(callDepth)
		if !ok {
			file = "???"
			line = 0
		} else {
			for i := len(file) - 1; i > 0; i-- {
				if file[i] == '/' {
					file = file[i+1:]
					break
				}
			}
		}

		buf = append(buf, fmt.Sprintf("%s:%d ", file, line)...)
	}

	if l.flag&Llevel > 0 {
		buf = append(buf, fmt.Sprintf("[%s] ", LevelName[level])...)
	}

	s := fmt.Sprintf(format, v...)

	buf = append(buf, s...)

	if s[len(s)-1] != '\n' {
		buf = append(buf, "\n"...)
	}

	l.msg <- buf
}

func (l *Logger) Trace(format string, v ...interface{}) {
	l.Output(2, LevelTrace, format, v...)
}

func (l *Logger) Debug(format string, v ...interface{}) {
	l.Output(2, LevelDebug, format, v...)
}

func (l *Logger) Info(format string, v ...interface{}) {
	l.Output(2, LevelInfo, format, v...)
}

func (l *Logger) Warn(format string, v ...interface{}) {
	l.Output(2, LevelWarn, format, v...)
}

func (l *Logger) Error(format string, v ...interface{}) {
	l.Output(2, LevelError, format, v...)
}

func (l *Logger) Fatal(format string, v ...interface{}) {
	l.Output(2, LevelFatal, format, v...)
}

func SetLevel(level int) {
	std.SetLevel(level)
}

func Trace(format string, v ...interface{}) {
	std.Output(2, LevelTrace, format, v...)
}

func Debug(format string, v ...interface{}) {
	std.Output(2, LevelDebug, format, v...)
}

func Info(format string, v ...interface{}) {
	std.Output(2, LevelInfo, format, v...)
}

func Warn(format string, v ...interface{}) {
	std.Output(2, LevelWarn, format, v...)
}

func Error(format string, v ...interface{}) {
	std.Output(2, LevelError, format, v...)
}

func Fatal(format string, v ...interface{}) {
	std.Output(2, LevelFatal, format, v...)
}
<commit_msg>log time bug fix<commit_after>package log

import (
	"fmt"
	"os"
	"runtime"
	"strconv"
	"time"
)

const (
	LevelTrace = iota
	LevelDebug
	LevelInfo
	LevelWarn
	LevelError
	LevelFatal
)

const (
	Ltime  = 0x01 //time format "2006/01/02 15:04:05"
	Lfile  = 0x02 //file.go:123
	Llevel = 0x04 //[Trace|Debug|Info...]
)

var LevelName [6]string = [6]string{"Trace", "Debug", "Info", "Warn", "Error", "Fatal"}

const TimeFormat = "2006/01/02 15:04:05"

type Logger struct {
	level int
	flag  int

	handler Handler

	quit chan struct{}
	msg  chan []byte
}

func New(handler Handler, flag int) *Logger {
	var l = new(Logger)

	l.level = LevelInfo
	l.handler = handler

	l.flag = flag

	l.quit = make(chan struct{})

	l.msg = make(chan []byte, 1024)

	go l.run()

	return l
}

func NewDefault(handler Handler) *Logger {
	return New(handler, Ltime|Lfile|Llevel)
}

func newStdHandler() *StreamHandler {
	h, _ := NewStreamHandler(os.Stdout)
	return h
}

var std = NewDefault(newStdHandler())

func (l *Logger) run() {
	for {
		select {
		case msg := <-l.msg:
			l.handler.Write(msg)
		case <-l.quit:
			l.handler.Close()
		}
	}
}

func (l *Logger) Close() {
	if l.quit == nil {
		return
	}

	close(l.quit)
	l.quit = nil
}

func (l *Logger) SetLevel(level int) {
	l.level = level
}

func (l *Logger) Output(callDepth int, level int, format string, v ...interface{}) {
	if l.level > level {
		return
	}

	buf := make([]byte, 0, 1024)

	if l.flag&Ltime > 0 {
		now := time.Now().Format(TimeFormat)
		buf = append(buf, '[')
		buf = append(buf, now...)
		buf = append(buf, "] "...)
	}

	if l.flag&Lfile > 0 {
		_, file, line, ok := runtime.Caller(callDepth)
		if !ok {
			file = "???"
			line = 0
		} else {
			for i := len(file) - 1; i > 0; i-- {
				if file[i] == '/' {
					file = file[i+1:]
					break
				}
			}
		}

		buf = append(buf, file...)
		buf = append(buf, ':')

		strconv.AppendInt(buf, int64(line), 10)
	}

	if l.flag&Llevel > 0 {
		buf = append(buf, '[')
		buf = append(buf, LevelName[level]...)
		buf = append(buf, "] "...)
	}

	s := fmt.Sprintf(format, v...)

	buf = append(buf, s...)

	if s[len(s)-1] != '\n' {
		buf = append(buf, '\n')
	}

	l.msg <- buf
}

func (l *Logger) Trace(format string, v ...interface{}) {
	l.Output(2, LevelTrace, format, v...)
}

func (l *Logger) Debug(format string, v ...interface{}) {
	l.Output(2, LevelDebug, format, v...)
}

func (l *Logger) Info(format string, v ...interface{}) {
	l.Output(2, LevelInfo, format, v...)
}

func (l *Logger) Warn(format string, v ...interface{}) {
	l.Output(2, LevelWarn, format, v...)
}

func (l *Logger) Error(format string, v ...interface{}) {
	l.Output(2, LevelError, format, v...)
}

func (l *Logger) Fatal(format string, v ...interface{}) {
	l.Output(2, LevelFatal, format, v...)
}

func SetLevel(level int) {
	std.SetLevel(level)
}

func Trace(format string, v ...interface{}) {
	std.Output(2, LevelTrace, format, v...)
}

func Debug(format string, v ...interface{}) {
	std.Output(2, LevelDebug, format, v...)
}

func Info(format string, v ...interface{}) {
	std.Output(2, LevelInfo, format, v...)
}

func Warn(format string, v ...interface{}) {
	std.Output(2, LevelWarn, format, v...)
}

func Error(format string, v ...interface{}) {
	std.Output(2, LevelError, format, v...)
}

func Fatal(format string, v ...interface{}) {
	std.Output(2, LevelFatal, format, v...)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"time"
)

//Logger is the logging object that is used to produce log outputs
var Logger *log.Logger

var file os.File

func startLogger(logAmount int, logLocation string, rotationPeriod time.Duration) {
	logRotator(logAmount, logLocation)

	newLogFile(logLocation)

	ticker := time.NewTicker(rotationPeriod)
	go func() {
		for _ = range ticker.C {
			Logger.Println("poo")

			Logger = log.New(os.Stdout,
				"", //"PREFIX: ",
				log.Ldate|log.Ltime|log.Lshortfile)

			logRotator(logAmount, logLocation)

			newLogFile(logLocation)
			Logger.Println("wee")

		}
	}()
}

func newLogFile(logLocation string) {
	file, err := os.OpenFile(logLocation+"0.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		log.Fatal("Failed to open Logger file", err)
	}

	multi := io.MultiWriter(file, os.Stdout)

	Logger = log.New(multi,
		"", //"PREFIX: ",
		log.Ldate|log.Ltime|log.Lshortfile)
}

func logRotator(logAmount int, logLocation string) {
	//if log file number <logAmount> exists, delete it
	if _, err := os.Stat(logLocation + strconv.Itoa(logAmount) + ".log"); os.IsNotExist(err) {
		os.Remove(logLocation + strconv.Itoa(logAmount) + ".log")
	}

	//shift all of the other logs along by +1
	for i := 2; i != -1; i-- {
		fmt.Println(logLocation + strconv.Itoa(i) + ".log")
		if _, err := os.Stat(logLocation + strconv.Itoa(i) + ".log"); err == nil {
			os.Rename(logLocation+strconv.Itoa(i)+".log", logLocation+strconv.Itoa(i+1)+".log")
		}
	}
}
<commit_msg>updated package name and added option for no log rotation<commit_after>package rotaryLogger

import (
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"time"
)

//Logger is the logging object that is used to produce log outputs
var Logger *log.Logger

var file os.File

//StartLoggerWRotation starts the rotary logger. logAmount is the amount of
//log files that will be retained on a rotation. logLocation is the file and
//name (minus the .log prefix) of the logs, i.e. log/mylog. rotationPeriod
//is the time duration between log rotations
func StartLoggerWRotation(logAmount int, logLocation string, rotationPeriod time.Duration) {
	logRotator(logAmount, logLocation)

	StartLogger(logLocation)

	ticker := time.NewTicker(rotationPeriod)
	go func() {
		for _ = range ticker.C {
			Logger.Println("Rotating Logs")

			Logger = log.New(os.Stdout,
				"", //"PREFIX: ",
				log.Ldate|log.Ltime|log.Lshortfile)

			logRotator(logAmount, logLocation)

			StartLogger(logLocation)

		}
	}()
}

//StartLogger starts the Logger without any log rotation. logLocation is the
//file and folder location of the log, i.e. log/myAppLogs.
func StartLogger(logLocation string) {
	file, err := os.OpenFile(logLocation+"0.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
	if err != nil {
		log.Fatal("Failed to open Logger file", err)
	}

	multi := io.MultiWriter(file, os.Stdout)

	Logger = log.New(multi,
		"", //"PREFIX: ",
		log.Ldate|log.Ltime|log.Lshortfile)
}

//logRotator is a function that deletes the latermost log and shifts all the
//rest of the logs by +1.
func logRotator(logAmount int, logLocation string) {
	//if log file number <logAmount> exists, delete it
	if _, err := os.Stat(logLocation + strconv.Itoa(logAmount) + ".log"); os.IsNotExist(err) {
		os.Remove(logLocation + strconv.Itoa(logAmount) + ".log")
	}

	//shift all of the other logs along by +1
	for i := 2; i != -1; i-- {
		fmt.Println(logLocation + strconv.Itoa(i) + ".log")
		if _, err := os.Stat(logLocation + strconv.Itoa(i) + ".log"); err == nil {
			os.Rename(logLocation+strconv.Itoa(i)+".log", logLocation+strconv.Itoa(i+1)+".log")
		}
	}
}
<|endoftext|>


<commit_before>package gitmedia

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"runtime/debug"
	"strings"
	"time"
)

var (
	Debugging   = false
	ErrorBuffer = &bytes.Buffer{}
	ErrorWriter = io.MultiWriter(os.Stderr, ErrorBuffer)
)

func Print(format string, args ...interface{}) {
	line := fmt.Sprintf(format, args...)
	fmt.Fprintln(ErrorWriter, line)
}

func Exit(format string, args ...interface{}) {
	Print(format, args...)
	os.Exit(2)
}

func Panic(err error, format string, args ...interface{}) {
	Print(format, args...)
	handlePanic(err)
	os.Exit(2)
}

func Debug(format string, args ...interface{}) {
	if !Debugging {
		return
	}
	log.Printf(format, args...)
}

func SetupDebugging(flagset *flag.FlagSet) {
	if flagset == nil {
		flag.BoolVar(&Debugging, "debug", false, "Turns debugging on")
	} else {
		flagset.BoolVar(&Debugging, "debug", false, "Turns debugging on")
	}
}

func handlePanic(err error) {
	if err == nil {
		return
	}

	Debug(err.Error())
	logErr := logPanic(err)
	if logErr != nil {
		fmt.Fprintln(os.Stderr, "Unable to log panic:")
		panic(logErr)
	}
}

func logPanic(loggedError error) error {
	if err := os.MkdirAll(LocalLogDir, 0744); err != nil {
		return err
	}

	now := time.Now()
	name := now.Format("2006-01-02T15:04:05.999999999")
	full := filepath.Join(LocalLogDir, name+".log")

	file, err := os.Create(full)
	if err != nil {
		return err
	}

	defer file.Close()

	fmt.Fprintf(file, "> %s", filepath.Base(os.Args[0]))
	if len(os.Args) > 0 {
		fmt.Fprintf(file, " %s", strings.Join(os.Args[1:], " "))
	}
	fmt.Fprintln(file, "")
	fmt.Fprintln(file, "")

	file.Write(ErrorBuffer.Bytes())
	fmt.Fprintln(file, "")

	fmt.Fprintln(file, loggedError.Error())
	file.Write(debug.Stack())

	return nil
}

func init() {
	log.SetOutput(ErrorWriter)
}
<commit_msg>docs on the logging functions<commit_after>package gitmedia

import (
	"bytes"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"path/filepath"
	"runtime/debug"
	"strings"
	"time"
)

var (
	Debugging   = false
	ErrorBuffer = &bytes.Buffer{}
	ErrorWriter = io.MultiWriter(os.Stderr, ErrorBuffer)
)

// Print prints a formatted message to Stderr.  It also gets printed to the
// panic log if one is created for this command.
func Print(format string, args ...interface{}) {
	line := fmt.Sprintf(format, args...)
	fmt.Fprintln(ErrorWriter, line)
}

// Exit prints a formatted message and exits.
func Exit(format string, args ...interface{}) {
	Print(format, args...)
	os.Exit(2)
}

// Panic prints a formatted message, and writes a stack trace for the error to
// a log file before exiting.
func Panic(err error, format string, args ...interface{}) {
	Print(format, args...)
	handlePanic(err)
	os.Exit(2)
}

// Debug prints a formatted message if debugging is enabled.  The formatted
// message also shows up in the panic log, if created.
func Debug(format string, args ...interface{}) {
	if !Debugging {
		return
	}
	log.Printf(format, args...)
}

func SetupDebugging(flagset *flag.FlagSet) {
	if flagset == nil {
		flag.BoolVar(&Debugging, "debug", false, "Turns debugging on")
	} else {
		flagset.BoolVar(&Debugging, "debug", false, "Turns debugging on")
	}
}

func handlePanic(err error) {
	if err == nil {
		return
	}

	Debug(err.Error())
	logErr := logPanic(err)
	if logErr != nil {
		fmt.Fprintln(os.Stderr, "Unable to log panic:")
		panic(logErr)
	}
}

func logPanic(loggedError error) error {
	if err := os.MkdirAll(LocalLogDir, 0744); err != nil {
		return err
	}

	now := time.Now()
	name := now.Format("2006-01-02T15:04:05.999999999")
	full := filepath.Join(LocalLogDir, name+".log")

	file, err := os.Create(full)
	if err != nil {
		return err
	}

	defer file.Close()

	fmt.Fprintf(file, "> %s", filepath.Base(os.Args[0]))
	if len(os.Args) > 0 {
		fmt.Fprintf(file, " %s", strings.Join(os.Args[1:], " "))
	}
	fmt.Fprintln(file, "")
	fmt.Fprintln(file, "")

	file.Write(ErrorBuffer.Bytes())
	fmt.Fprintln(file, "")

	fmt.Fprintln(file, loggedError.Error())
	file.Write(debug.Stack())

	return nil
}

func init() {
	log.SetOutput(ErrorWriter)
}
<|endoftext|>


<commit_before>package drouter

import (
	"net"
	"strconv"
	"errors"
	"strings"
	//"os/exec"
	//"fmt"
	"time"
	"os"
	"bufio"
	//"os/signal"
	//"syscall"
	//"bytes"
	//"io/ioutil"

	log "github.com/Sirupsen/logrus"
	//"github.com/samalba/dockerclient"
	dockerclient "github.com/docker/engine-api/client"
	dockertypes "github.com/docker/engine-api/types"
	dockerfilters "github.com/docker/engine-api/types/filters"
	dockernetworks "github.com/docker/engine-api/types/network"
	"golang.org/x/net/context"
	"github.com/vishvananda/netlink"
	"github.com/vishvananda/netns"
	"github.com/ziutek/utils/netaddr"
)

var (
	docker                *dockerclient.Client
	self_container        dockertypes.ContainerJSON
	networks              = make(map[string]bool)
	host_ns_h             *netlink.Handle
	self_ns_h             *netlink.Handle
	host_route_link_index int
	host_route_gw		    net.IP
	my_pid                = os.Getpid()
)

func init() {
	var err error

	if my_pid == 1 {
		log.Fatal("Running as Pid 1. drouter must be run with --pid=host")
	}

	defaultHeaders := map[string]string{"User-Agent": "engine-api-cli-1.0"}
	docker, err = dockerclient.NewClient("unix:///var/run/docker.sock", "v1.22", nil, defaultHeaders)
	if err != nil {
		log.Fatal(err)
	}
	self_container, err = getSelf()
	if err != nil {
		log.Error("Error getting self container. Is this processs running in a container? Is the docker socket passed through?")
		log.Fatal(err)
	}

	// Prepopulate networks that this container is a member of
	log.Infof("Self_container-info: %v", self_container)
	log.Infof("Self_container-info.networksettings.networks: %v", self_container.NetworkSettings.Networks)
	for _, settings := range self_container.NetworkSettings.Networks {
		networks[settings.NetworkID] = true
	}

	log.Infof("Member networks on startup: %v", networks)

	self_ns, err := netns.GetFromPid(my_pid)
	if err != nil {
		log.Error("Error getting self namespace.")
		log.Fatal(err)
	}
	self_ns_h, err = netlink.NewHandleAt(self_ns)
	if err != nil {
		log.Error("Error getting handle at self namespace.")
		log.Fatal(err)
	}
	host_ns, err := netns.GetFromPid(1)
	if err != nil {
		log.Error("Error getting host namespace. Is this container running in priveleged mode?")
		log.Fatal(err)
	}
	host_ns_h, err = netlink.NewHandleAt(host_ns)
	if err != nil {
		log.Error("Error getting handle at host namespace.")
		log.Fatal(err)
	}
}

// Loop to watch for new networks created and create interfaces when needed
func WatchNetworks() {
	log.Info("Watching Networks")
	for {
		nets, err := docker.NetworkList(context.Background(), dockertypes.NetworkListOptions{ Filters: dockerfilters.NewArgs(), })
		if err != nil {
			log.Error(err)
		}
		for i := range nets {
			//log.Debugf("Checking network %v", nets[i])
			drouter_str := nets[i].Options["drouter"]
			drouter := false
			if drouter_str != "" {
				drouter, err = strconv.ParseBool(drouter_str)
				if err != nil {
					log.Error(err)
				}
			}

			if drouter && !networks[nets[i].ID] {
				log.Debugf("Creating Net: %+v", nets[i])
				err := joinNet(&nets[i])
				if err != nil {
					log.Error(err)
				}
			} else if !drouter && networks[nets[i].ID] {
				log.Debugf("Leaving Net: %+v", nets[i])
				err := leaveNet(&nets[i])
				if err != nil {
					log.Error(err)
				}
			}
		}
		time.Sleep(5 * time.Second)
	}
}

func WatchEvents() {
	for {
		time.Sleep(1 * time.Second)
	}
}

func joinNet(net *dockertypes.NetworkResource) error {
	err := docker.NetworkConnect(context.Background(), net.ID, self_container.ID, &dockernetworks.EndpointSettings{})
	if err != nil {
		return err
	}
	networks[net.ID] = true
	return nil
}

func leaveNet(net *dockertypes.NetworkResource) error {
	err := docker.NetworkDisconnect(context.Background(), net.ID, self_container.ID, true)
	if err != nil {
		return err
	}
	networks[net.ID] = false
	return nil
}

func getSelf() (dockertypes.ContainerJSON, error) {
	cgroup, err := os.Open("/proc/self/cgroup")
	if err != nil {
		return dockertypes.ContainerJSON{}, err
	}
	defer cgroup.Close()

	scanner := bufio.NewScanner(cgroup)
	for scanner.Scan() {
		line := strings.Split(scanner.Text(), "/")
		id := line[len(line) - 1]
		containerInfo, err := docker.ContainerInspect(context.Background(), id)
		if err != nil {
			log.Warn(err)
			continue
		}
		return containerInfo, nil
	}
	return dockertypes.ContainerJSON{}, errors.New("Container not found")
}

func MakeP2PLink(p2p_addr string) error {
	host_link_veth := &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{Name: "drouter_veth0"},
		PeerName:  "drouter_veth1",
	}
	err := host_ns_h.LinkAdd(host_link_veth)
	if err != nil {
		return err
	}
	host_link, err := host_ns_h.LinkByName("drouter_veth0")
	if err != nil {
		return err
	}
	host_route_link_index = host_link.Attrs().Index

	int_link, err := host_ns_h.LinkByName("drouter_veth1")
	if err != nil {
		return err
	}
	err = host_ns_h.LinkSetNsPid(int_link, my_pid)
	if err != nil {
		return err
	}
	int_link, err = self_ns_h.LinkByName("drouter_veth1")
	if err != nil {
		return err
	}

	_, p2p_net, err := net.ParseCIDR(p2p_addr)
	if err != nil {
		return err
	}

	host_addr := p2p_net
	host_addr.IP = netaddr.IPAdd(host_addr.IP, 1)
	host_netlink_addr := &netlink.Addr{
		IPNet: host_addr,
		Label: "",
	}
	err = host_ns_h.AddrAdd(host_link, host_netlink_addr)
	if err != nil {
		return err
	}

	int_addr := p2p_net
	int_addr.IP = netaddr.IPAdd(int_addr.IP, 2)
	int_netlink_addr := &netlink.Addr{
		IPNet: int_addr,
		Label: "",
	}
	err = self_ns_h.AddrAdd(int_link, int_netlink_addr)
	if err != nil {
		return err
	}
	host_route_gw = int_addr.IP

	err = self_ns_h.LinkSetUp(int_link)
	if err != nil {
		return err
	}

	err = self_ns_h.LinkSetUp(host_link)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>log getting namespace<commit_after>package drouter

import (
	"net"
	"strconv"
	"errors"
	"strings"
	//"os/exec"
	//"fmt"
	"time"
	"os"
	"bufio"
	//"os/signal"
	//"syscall"
	//"bytes"
	//"io/ioutil"

	log "github.com/Sirupsen/logrus"
	//"github.com/samalba/dockerclient"
	dockerclient "github.com/docker/engine-api/client"
	dockertypes "github.com/docker/engine-api/types"
	dockerfilters "github.com/docker/engine-api/types/filters"
	dockernetworks "github.com/docker/engine-api/types/network"
	"golang.org/x/net/context"
	"github.com/vishvananda/netlink"
	"github.com/vishvananda/netns"
	"github.com/ziutek/utils/netaddr"
)

var (
	docker                *dockerclient.Client
	self_container        dockertypes.ContainerJSON
	networks              = make(map[string]bool)
	host_ns_h             *netlink.Handle
	self_ns_h             *netlink.Handle
	host_route_link_index int
	host_route_gw		    net.IP
	my_pid                = os.Getpid()
)

func init() {
	var err error

	if my_pid == 1 {
		log.Fatal("Running as Pid 1. drouter must be run with --pid=host")
	}

	defaultHeaders := map[string]string{"User-Agent": "engine-api-cli-1.0"}
	docker, err = dockerclient.NewClient("unix:///var/run/docker.sock", "v1.22", nil, defaultHeaders)
	if err != nil {
		log.Fatal(err)
	}
	self_container, err = getSelf()
	if err != nil {
		log.Error("Error getting self container. Is this processs running in a container? Is the docker socket passed through?")
		log.Fatal(err)
	}

	// Prepopulate networks that this container is a member of
	log.Infof("Self_container-info: %v", self_container)
	log.Infof("Self_container-info.networksettings.networks: %v", self_container.NetworkSettings.Networks)
	for _, settings := range self_container.NetworkSettings.Networks {
		networks[settings.NetworkID] = true
	}

	log.Infof("Member networks on startup: %v", networks)

	self_ns, err := netns.GetFromPid(my_pid)
	if err != nil {
		log.Error("Error getting self namespace.")
		log.Fatal(err)
	}
	log.Infof("self_ns: %v", self_ns)
	self_ns_h, err = netlink.NewHandleAt(self_ns)
	if err != nil {
		log.Error("Error getting handle at self namespace.")
		log.Fatal(err)
	}
	host_ns, err := netns.GetFromPid(1)
	if err != nil {
		log.Error("Error getting host namespace. Is this container running in priveleged mode?")
		log.Fatal(err)
	}
	log.Infof("host_ns: %v", self_ns)
	host_ns_h, err = netlink.NewHandleAt(host_ns)
	if err != nil {
		log.Error("Error getting handle at host namespace.")
		log.Fatal(err)
	}
}

// Loop to watch for new networks created and create interfaces when needed
func WatchNetworks() {
	log.Info("Watching Networks")
	for {
		nets, err := docker.NetworkList(context.Background(), dockertypes.NetworkListOptions{ Filters: dockerfilters.NewArgs(), })
		if err != nil {
			log.Error(err)
		}
		for i := range nets {
			//log.Debugf("Checking network %v", nets[i])
			drouter_str := nets[i].Options["drouter"]
			drouter := false
			if drouter_str != "" {
				drouter, err = strconv.ParseBool(drouter_str)
				if err != nil {
					log.Error(err)
				}
			}

			if drouter && !networks[nets[i].ID] {
				log.Debugf("Creating Net: %+v", nets[i])
				err := joinNet(&nets[i])
				if err != nil {
					log.Error(err)
				}
			} else if !drouter && networks[nets[i].ID] {
				log.Debugf("Leaving Net: %+v", nets[i])
				err := leaveNet(&nets[i])
				if err != nil {
					log.Error(err)
				}
			}
		}
		time.Sleep(5 * time.Second)
	}
}

func WatchEvents() {
	for {
		time.Sleep(1 * time.Second)
	}
}

func joinNet(net *dockertypes.NetworkResource) error {
	err := docker.NetworkConnect(context.Background(), net.ID, self_container.ID, &dockernetworks.EndpointSettings{})
	if err != nil {
		return err
	}
	networks[net.ID] = true
	return nil
}

func leaveNet(net *dockertypes.NetworkResource) error {
	err := docker.NetworkDisconnect(context.Background(), net.ID, self_container.ID, true)
	if err != nil {
		return err
	}
	networks[net.ID] = false
	return nil
}

func getSelf() (dockertypes.ContainerJSON, error) {
	cgroup, err := os.Open("/proc/self/cgroup")
	if err != nil {
		return dockertypes.ContainerJSON{}, err
	}
	defer cgroup.Close()

	scanner := bufio.NewScanner(cgroup)
	for scanner.Scan() {
		line := strings.Split(scanner.Text(), "/")
		id := line[len(line) - 1]
		containerInfo, err := docker.ContainerInspect(context.Background(), id)
		if err != nil {
			log.Warn(err)
			continue
		}
		return containerInfo, nil
	}
	return dockertypes.ContainerJSON{}, errors.New("Container not found")
}

func MakeP2PLink(p2p_addr string) error {
	host_link_veth := &netlink.Veth{
		LinkAttrs: netlink.LinkAttrs{Name: "drouter_veth0"},
		PeerName:  "drouter_veth1",
	}
	err := host_ns_h.LinkAdd(host_link_veth)
	if err != nil {
		return err
	}
	host_link, err := host_ns_h.LinkByName("drouter_veth0")
	if err != nil {
		return err
	}
	host_route_link_index = host_link.Attrs().Index

	int_link, err := host_ns_h.LinkByName("drouter_veth1")
	if err != nil {
		return err
	}
	err = host_ns_h.LinkSetNsPid(int_link, my_pid)
	if err != nil {
		return err
	}
	int_link, err = self_ns_h.LinkByName("drouter_veth1")
	if err != nil {
		return err
	}

	_, p2p_net, err := net.ParseCIDR(p2p_addr)
	if err != nil {
		return err
	}

	host_addr := p2p_net
	host_addr.IP = netaddr.IPAdd(host_addr.IP, 1)
	host_netlink_addr := &netlink.Addr{
		IPNet: host_addr,
		Label: "",
	}
	err = host_ns_h.AddrAdd(host_link, host_netlink_addr)
	if err != nil {
		return err
	}

	int_addr := p2p_net
	int_addr.IP = netaddr.IPAdd(int_addr.IP, 2)
	int_netlink_addr := &netlink.Addr{
		IPNet: int_addr,
		Label: "",
	}
	err = self_ns_h.AddrAdd(int_link, int_netlink_addr)
	if err != nil {
		return err
	}
	host_route_gw = int_addr.IP

	err = self_ns_h.LinkSetUp(int_link)
	if err != nil {
		return err
	}

	err = self_ns_h.LinkSetUp(host_link)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package expr

import (
	"testing"

	"github.com/StackExchange/scollector/opentsdb"
)

func TestExprSimple(t *testing.T) {
	var exprTests = []struct {
		input  string
		output Scalar
	}{
		{"!1", 0},
		{"-2", -2},
		{"1.444-010+2*3e2-4/5+0xff", 847.644},
		{"1>2", 0},
		{"3>2", 1},
		{"1==1", 1},
		{"1==2", 0},
		{"1!=01", 0},
		{"1!=2", 1},
		{"1<2", 1},
		{"2<1", 0},
		{"1||0", 1},
		{"0||0", 0},
		{"1&&0", 0},
		{"1&&2", 1},
		{"1<=0", 0},
		{"1<=1", 1},
		{"1<=2", 1},
		{"1>=0", 1},
		{"1>=1", 1},
		{"1>=2", 0},
		{"-1 > 0", 0},
		{"-1 < 0", 1},
	}

	for _, et := range exprTests {
		e, err := New(et.input)
		if err != nil {
			t.Error(err)
			break
		}
		r, _, err := e.Execute(opentsdb.Host(""), nil)
		if err != nil {
			t.Error(err)
			break
		} else if len(r) != 1 {
			t.Error("bad r len", len(r))
			break
		} else if len(r[0].Group) != 0 {
			t.Error("bad group len", r[0].Group)
			break
		} else if r[0].Value != et.output {
			t.Errorf("expected %v, got %v: %v\nast: %v", et.output, r[0].Value, et.input, e)
		}
	}
}

func TestExprParse(t *testing.T) {
	var exprTests = []struct {
		input string
		valid bool
	}{
		{`avg(q("test", "1m", 1))`, false},
	}

	for _, et := range exprTests {
		_, err := New(et.input)
		if et.valid && err != nil {
			t.Error(err)
		} else if !et.valid && err == nil {
			t.Errorf("expected invalid, but no error: %v", et.input)
		}
	}
}

const TSDBHost = "ny-devtsdb04:4242"

func TestExprQuery(t *testing.T) {
	e, err := New(`forecastlr(q("avg:os.cpu{host=ny-lb05}", "1m"), -10)`)
	if err != nil {
		t.Fatal(err)
	}
	_, _, err = e.Execute(opentsdb.Host(TSDBHost), nil)
	if err != nil {
		t.Fatal(err)
	}
}
<commit_msg>Fix expr test with third q arg<commit_after>package expr

import (
	"testing"

	"github.com/StackExchange/scollector/opentsdb"
)

func TestExprSimple(t *testing.T) {
	var exprTests = []struct {
		input  string
		output Scalar
	}{
		{"!1", 0},
		{"-2", -2},
		{"1.444-010+2*3e2-4/5+0xff", 847.644},
		{"1>2", 0},
		{"3>2", 1},
		{"1==1", 1},
		{"1==2", 0},
		{"1!=01", 0},
		{"1!=2", 1},
		{"1<2", 1},
		{"2<1", 0},
		{"1||0", 1},
		{"0||0", 0},
		{"1&&0", 0},
		{"1&&2", 1},
		{"1<=0", 0},
		{"1<=1", 1},
		{"1<=2", 1},
		{"1>=0", 1},
		{"1>=1", 1},
		{"1>=2", 0},
		{"-1 > 0", 0},
		{"-1 < 0", 1},
	}

	for _, et := range exprTests {
		e, err := New(et.input)
		if err != nil {
			t.Error(err)
			break
		}
		r, _, err := e.Execute(opentsdb.Host(""), nil)
		if err != nil {
			t.Error(err)
			break
		} else if len(r) != 1 {
			t.Error("bad r len", len(r))
			break
		} else if len(r[0].Group) != 0 {
			t.Error("bad group len", r[0].Group)
			break
		} else if r[0].Value != et.output {
			t.Errorf("expected %v, got %v: %v\nast: %v", et.output, r[0].Value, et.input, e)
		}
	}
}

func TestExprParse(t *testing.T) {
	var exprTests = []struct {
		input string
		valid bool
	}{
		{`avg(q("test", "1m", 1))`, false},
	}

	for _, et := range exprTests {
		_, err := New(et.input)
		if et.valid && err != nil {
			t.Error(err)
		} else if !et.valid && err == nil {
			t.Errorf("expected invalid, but no error: %v", et.input)
		}
	}
}

const TSDBHost = "ny-devtsdb04:4242"

func TestExprQuery(t *testing.T) {
	e, err := New(`forecastlr(q("avg:os.cpu{host=ny-lb05}", "1m", ""), -10)`)
	if err != nil {
		t.Fatal(err)
	}
	_, _, err = e.Execute(opentsdb.Host(TSDBHost), nil)
	if err != nil {
		t.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package gobls

import (
	"bytes"
	"testing"
)

func TestNoEOF(t *testing.T) {
	bb := bytes.NewBufferString("")
	s := NewScanner(bb)
	for s.Scan() {
		t.Errorf("Actual: scan returned true; Expected: false")
	}
	if s.Err() != nil {
		t.Errorf("Actual: %#v; Expected: %#v", s.Err(), nil)
	}
}

func TestFoo(t *testing.T) {
	bb := bytes.NewBufferString("flubber\nblubber\nfoo")
	s := NewScanner(bb)
	expectedLines := []string{"flubber", "blubber", "foo"}
	actualLines := make([]string, 0)
	for s.Scan() {
		actualLines = append(actualLines, s.String())
	}
	if s.Err() != nil {
		t.Errorf("Actual: %#v; Expected: %#v", s.Err(), nil)
	}
	if len(actualLines) != len(expectedLines) {
		t.Fatalf("Actual: %#v; Expected: %#v", len(actualLines), len(expectedLines))
	}
	for i := 0; i < len(expectedLines); i++ {
		if actualLines[i] != expectedLines[i] {
			t.Errorf("Actual: %#v; Expected: %#v",
				actualLines[i], expectedLines[i])
		}
	}
}
<commit_msg>test ensures scanner handles lines longer than 4096 characters<commit_after>package gobls

import (
	"bytes"
	"testing"
)

func TestNoEOF(t *testing.T) {
	bb := bytes.NewBufferString("")
	s := NewScanner(bb)
	for s.Scan() {
		t.Errorf("Actual: scan returned true; Expected: false")
	}
	if s.Err() != nil {
		t.Errorf("Actual: %#v; Expected: %#v", s.Err(), nil)
	}
}

func TestSequencesThroughEntireBuffer(t *testing.T) {
	bb := bytes.NewBufferString("flubber\nblubber\nfoo")
	s := NewScanner(bb)
	expectedLines := []string{"flubber", "blubber", "foo"}
	actualLines := make([]string, 0)
	for s.Scan() {
		actualLines = append(actualLines, s.String())
	}
	if s.Err() != nil {
		t.Errorf("Actual: %#v; Expected: %#v", s.Err(), nil)
	}
	if len(actualLines) != len(expectedLines) {
		t.Fatalf("Actual: %#v; Expected: %#v", len(actualLines), len(expectedLines))
	}
	for i := 0; i < len(expectedLines); i++ {
		if actualLines[i] != expectedLines[i] {
			t.Errorf("Actual: %#v; Expected: %#v",
				actualLines[i], expectedLines[i])
		}
	}
}

func TestHandlesVeryLargeLines(t *testing.T) {
	line := "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
	bb := bytes.NewBufferString(line)
	s := NewScanner(bb)
	lines := make([]string, 0)
	for s.Scan() {
		lines = append(lines, s.String())
	}
	if s.Err() != nil {
		t.Errorf("Actual: %#v; Expected: %#v", s.Err(), nil)
	}
	if len(lines) != 1 {
		t.Fatalf("Actual: %#v; Expected: %#v", len(lines), 1)
	}
	if lines[0] != line {
		t.Errorf("Actual: %#v; Expected: %#v", lines[0], line)
	}
}
<|endoftext|>