<commit_before>// Copyright 2017 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package repositories

import (
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"net/http"
	"net/url"
	"os"
	"sort"
	"strings"
)

type Group struct {
	Name  string
	Teams []string
	Pools []string
}

func FetchGroup(name string) (*Group, error) {
	url := fmt.Sprintf("%s/api/teamgroups/%s", apiHost, name)
	response, err := Client.Get(url)
	if err != nil {
		errMsg := fmt.Sprintf("Error fetching %s: %s", url, err.Error())
		log.Printf(errMsg)
		return nil, errors.New(errMsg)
	}
	status := response.StatusCode
	if status != http.StatusOK && status != http.StatusNotFound {
		errMsg := fmt.Sprintf("Error fetching %s: HTTP %d", url, status)
		log.Printf(errMsg)
		return nil, errors.New(errMsg)
	}
	if status == http.StatusNotFound {
		return nil, nil
	}
	defer response.Body.Close()
	var group Group
	err = json.NewDecoder(response.Body).Decode(&group)
	if err != nil {
		errMsg := fmt.Sprintf("Error decoding response body: %s", err.Error())
		log.Printf(errMsg)
		return nil, errors.New(errMsg)
	}
	return &group, nil
}

func FetchGroups() ([]Group, error) {
	host := os.Getenv("API_HOST")
	url := fmt.Sprintf("%s/api/teamgroups", host)
	response, err := Client.Get(url)
	if err != nil {
		errMsg := fmt.Sprintf("Error fetching %s: %s", url, err.Error())
		log.Printf(errMsg)
		return nil, errors.New(errMsg)
	}
	status := response.StatusCode
	if status != http.StatusOK {
		errMsg := fmt.Sprintf("Error fetching %s: HTTP %d", url, status)
		log.Printf(errMsg)
		return nil, errors.New(errMsg)
	}
	defer response.Body.Close()
	var groups []Group
	err = json.NewDecoder(response.Body).Decode(&groups)
	if err != nil {
		errMsg := fmt.Sprintf("Error decoding response body: %s", err.Error())
		log.Printf(errMsg)
		return nil, errors.New(errMsg)
	}
	sort.Slice(groups, func(i, j int) bool {
		return groups[i].Name < groups[j].Name
	})
	return groups, nil
}

func UpdateGroup(group Group) error {
	addr := fmt.Sprintf("%s/api/teamgroups/%s", apiHost, group.Name)
	v := url.Values{"teams": group.Teams, "pools": group.Pools}
	req, err := http.NewRequest(http.MethodPut, addr, strings.NewReader(v.Encode()))
	if err != nil {
		errMsg := fmt.Sprintf("Error in PUT %s: %s", addr, err.Error())
		log.Printf(errMsg)
		return errors.New(errMsg)
	}
	response, err := Client.Do(req)
	if err != nil {
		errMsg := fmt.Sprintf("Error in PUT %s: %s", addr, err.Error())
		log.Printf(errMsg)
		return errors.New(errMsg)
	}
	status := response.StatusCode
	if status != http.StatusOK && status != http.StatusCreated {
		errMsg := fmt.Sprintf("Error in PUT %s: HTTP %d", addr, status)
		log.Printf(errMsg)
		return errors.New(errMsg)
	}
	return nil
}
<commit_msg>web: add header to update group request<commit_after>// Copyright 2017 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package repositories

import (
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"net/http"
	"net/url"
	"os"
	"sort"
	"strings"
)

type Group struct {
	Name  string
	Teams []string
	Pools []string
}

func FetchGroup(name string) (*Group, error) {
	url := fmt.Sprintf("%s/api/teamgroups/%s", apiHost, name)
	response, err := Client.Get(url)
	if err != nil {
		errMsg := fmt.Sprintf("Error fetching %s: %s", url, err.Error())
		log.Printf(errMsg)
		return nil, errors.New(errMsg)
	}
	status := response.StatusCode
	if status != http.StatusOK && status != http.StatusNotFound {
		errMsg := fmt.Sprintf("Error fetching %s: HTTP %d", url, status)
		log.Printf(errMsg)
		return nil, errors.New(errMsg)
	}
	if status == http.StatusNotFound {
		return nil, nil
	}
	defer response.Body.Close()
	var group Group
	err = json.NewDecoder(response.Body).Decode(&group)
	if err != nil {
		errMsg := fmt.Sprintf("Error decoding response body: %s", err.Error())
		log.Printf(errMsg)
		return nil, errors.New(errMsg)
	}
	return &group, nil
}

func FetchGroups() ([]Group, error) {
	host := os.Getenv("API_HOST")
	url := fmt.Sprintf("%s/api/teamgroups", host)
	response, err := Client.Get(url)
	if err != nil {
		errMsg := fmt.Sprintf("Error fetching %s: %s", url, err.Error())
		log.Printf(errMsg)
		return nil, errors.New(errMsg)
	}
	status := response.StatusCode
	if status != http.StatusOK {
		errMsg := fmt.Sprintf("Error fetching %s: HTTP %d", url, status)
		log.Printf(errMsg)
		return nil, errors.New(errMsg)
	}
	defer response.Body.Close()
	var groups []Group
	err = json.NewDecoder(response.Body).Decode(&groups)
	if err != nil {
		errMsg := fmt.Sprintf("Error decoding response body: %s", err.Error())
		log.Printf(errMsg)
		return nil, errors.New(errMsg)
	}
	sort.Slice(groups, func(i, j int) bool {
		return groups[i].Name < groups[j].Name
	})
	return groups, nil
}

func UpdateGroup(group Group) error {
	addr := fmt.Sprintf("%s/api/teamgroups/%s", apiHost, group.Name)
	v := url.Values{"teams": group.Teams, "pools": group.Pools}
	req, err := http.NewRequest(http.MethodPut, addr, strings.NewReader(v.Encode()))
	if err != nil {
		errMsg := fmt.Sprintf("Error in PUT %s: %s", addr, err.Error())
		log.Printf(errMsg)
		return errors.New(errMsg)
	}
	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
	response, err := Client.Do(req)
	if err != nil {
		errMsg := fmt.Sprintf("Error in PUT %s: %s", addr, err.Error())
		log.Printf(errMsg)
		return errors.New(errMsg)
	}
	status := response.StatusCode
	if status != http.StatusOK && status != http.StatusCreated {
		errMsg := fmt.Sprintf("Error in PUT %s: HTTP %d", addr, status)
		log.Printf(errMsg)
		return errors.New(errMsg)
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2017 The OpenSDS Authors.
//
// 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.
/*
This module implements a entry into the OpenSDS service.

*/

package cli

import (
	"log"
	"os"
	"strconv"

	"github.com/opensds/opensds/pkg/model"
	"github.com/spf13/cobra"
)

var volumeCommand = &cobra.Command{
	Use:   "volume",
	Short: "manage volumes in the cluster",
	Run:   volumeAction,
}

var volumeCreateCommand = &cobra.Command{
	Use:   "create <size>",
	Short: "create a volume in the cluster",
	Run:   volumeCreateAction,
}

var volumeShowCommand = &cobra.Command{
	Use:   "show <id>",
	Short: "show a volume in the cluster",
	Run:   volumeShowAction,
}

var volumeListCommand = &cobra.Command{
	Use:   "list",
	Short: "list all volumes in the cluster",
	Run:   volumeListAction,
}

var volumeDeleteCommand = &cobra.Command{
	Use:   "delete <id>",
	Short: "delete a volume in the cluster",
	Run:   volumeDeleteAction,
}

var volumeUpdateCommand = &cobra.Command{
	Use:   "update <id>",
	Short: "update a volume in the cluster",
	Run:   volumeUpdateAction,
}

var volumeExtendCommand = &cobra.Command{
	Use:   "extend <id> <new size>",
	Short: "extend a volume in the cluster",
	Run:   volumeExtendAction,
}

var (
	profileId string
	volName   string
	volDesp   string
	volAz     string
	volSnap   string
)

var (
	volLimit          string
	volOffset         string
	volSortDir        string
	volSortKey        string
	volId             string
	volTenantId       string
	volUserId         string
	volStatus         string
	volPoolId         string
	volProfileId      string
	volGroupId        string
	snapshotFromCloud bool
)

func init() {
	volumeListCommand.Flags().StringVarP(&volLimit, "limit", "", "50", "the number of ertries displayed per page")
	volumeListCommand.Flags().StringVarP(&volOffset, "offset", "", "0", "all requested data offsets")
	volumeListCommand.Flags().StringVarP(&volSortDir, "sortDir", "", "desc", "the sort direction of all requested data. supports asc or desc(default)")
	volumeListCommand.Flags().StringVarP(&volSortKey, "sortKey", "", "id",
		"the sort key of all requested data. supports id(default), name, status, availabilityzone, profileid, tenantid, size, poolid, description")
	volumeListCommand.Flags().StringVarP(&volId, "id", "", "", "list volume by id")
	volumeListCommand.Flags().StringVarP(&volName, "name", "", "", "list volume by name")
	volumeListCommand.Flags().StringVarP(&volDesp, "description", "", "", "list volume by description")
	volumeListCommand.Flags().StringVarP(&volTenantId, "tenantId", "", "", "list volume by tenantId")
	volumeListCommand.Flags().StringVarP(&volUserId, "userId", "", "", "list volume by storage userId")
	volumeListCommand.Flags().StringVarP(&volStatus, "status", "", "", "list volume by status")
	volumeListCommand.Flags().StringVarP(&volPoolId, "poolId", "", "", "list volume by poolId")
	volumeListCommand.Flags().StringVarP(&volAz, "availabilityZone", "", "", "list volume by availability zone")
	volumeListCommand.Flags().StringVarP(&volProfileId, "profileId", "", "", "list volume by profile id")
	volumeListCommand.Flags().StringVarP(&volGroupId, "groupId", "", "", "list volume by volume group id")

	volumeCommand.PersistentFlags().StringVarP(&profileId, "profile", "p", "", "the id of profile configured by admin")

	volumeCommand.AddCommand(volumeCreateCommand)
	volumeCreateCommand.Flags().StringVarP(&volName, "name", "n", "", "the name of created volume")
	volumeCreateCommand.Flags().StringVarP(&volDesp, "description", "d", "", "the description of created volume")
	volumeCreateCommand.Flags().StringVarP(&volAz, "az", "a", "", "the availability zone of created volume")
	volumeCreateCommand.Flags().StringVarP(&volSnap, "snapshot", "s", "", "the snapshot to create volume")
	volumeCreateCommand.Flags().BoolVarP(&snapshotFromCloud, "snapshotFromCloud", "c", false, "download snapshot from cloud")
	volumeCommand.AddCommand(volumeShowCommand)
	volumeCommand.AddCommand(volumeListCommand)
	volumeCommand.AddCommand(volumeDeleteCommand)
	volumeCommand.AddCommand(volumeUpdateCommand)
	volumeUpdateCommand.Flags().StringVarP(&volName, "name", "n", "", "the name of updated volume")
	volumeUpdateCommand.Flags().StringVarP(&volDesp, "description", "d", "", "the description of updated volume")
	volumeCommand.AddCommand(volumeExtendCommand)

	volumeCommand.AddCommand(volumeSnapshotCommand)
	volumeCommand.AddCommand(volumeAttachmentCommand)
	volumeCommand.AddCommand(volumeGroupCommand)
	volumeCommand.AddCommand(replicationCommand)
}

func volumeAction(cmd *cobra.Command, args []string) {
	cmd.Usage()
	os.Exit(1)
}

var volFormatters = FormatterList{"Metadata": JsonFormatter}

func volumeCreateAction(cmd *cobra.Command, args []string) {
	ArgsNumCheck(cmd, args, 1)
	size, err := strconv.Atoi(args[0])
	if err != nil {
		log.Fatalf("error parsing size %s: %+v", args[0], err)
	}

	vol := &model.VolumeSpec{
		Name:              volName,
		Description:       volDesp,
		AvailabilityZone:  volAz,
		Size:              int64(size),
		ProfileId:         profileId,
		SnapshotId:        volSnap,
		SnapshotFromCloud: snapshotFromCloud,
	}

	resp, err := client.CreateVolume(vol)
	if err != nil {
		Fatalln(HttpErrStrip(err))
	}

	keys := KeyList{"Id", "CreatedAt", "Name", "Description", "Size", "AvailabilityZone",
		"Status", "PoolId", "ProfileId", "Metadata", "GroupId", "MultiAttach"}
	PrintDict(resp, keys, volFormatters)
}

func volumeShowAction(cmd *cobra.Command, args []string) {
	ArgsNumCheck(cmd, args, 1)
	resp, err := client.GetVolume(args[0])
	if err != nil {
		Fatalln(HttpErrStrip(err))
	}
	keys := KeyList{"Id", "CreatedAt", "UpdatedAt", "Name", "Description", "Size",
		"AvailabilityZone", "Status", "PoolId", "ProfileId", "Metadata", "GroupId", "SnapshotId",
		"MultiAttach"}
	PrintDict(resp, keys, volFormatters)
}

func volumeListAction(cmd *cobra.Command, args []string) {
	ArgsNumCheck(cmd, args, 0)

	var opts = map[string]string{"limit": volLimit, "offset": volOffset, "sortDir": volSortDir,
		"sortKey": volSortKey, "Id": volId,
		"Name": volName, "Description": volDesp, "UserId": volUserId, "AvailabilityZone": volAz,
		"Status": volStatus, "PoolId": volPoolId, "ProfileId": volProfileId, "GroupId": volGroupId}

	resp, err := client.ListVolumes(opts)
	if err != nil {
		Fatalln(HttpErrStrip(err))
	}
	keys := KeyList{"Id", "Name", "Description", "Size", "Status", "ProfileId", "AvailabilityZone"}
	PrintList(resp, keys, volFormatters)
}

func volumeDeleteAction(cmd *cobra.Command, args []string) {
	ArgsNumCheck(cmd, args, 1)
	vol := &model.VolumeSpec{
		ProfileId: profileId,
	}
	err := client.DeleteVolume(args[0], vol)
	if err != nil {
		Fatalln(HttpErrStrip(err))
	}
}

func volumeUpdateAction(cmd *cobra.Command, args []string) {
	ArgsNumCheck(cmd, args, 1)
	vol := &model.VolumeSpec{
		Name:        volName,
		Description: volDesp,
	}

	resp, err := client.UpdateVolume(args[0], vol)
	if err != nil {
		Fatalln(HttpErrStrip(err))
	}
	keys := KeyList{"Id", "UpdatedAt", "Name", "Description", "Size", "AvailabilityZone",
		"Status", "PoolId", "ProfileId", "Metadata", "GroupId", "MultiAttach"}
	PrintDict(resp, keys, volFormatters)
}

func volumeExtendAction(cmd *cobra.Command, args []string) {
	ArgsNumCheck(cmd, args, 2)
	newSize, err := strconv.Atoi(args[1])
	if err != nil {
		log.Fatalf("error parsing new size %s: %+v", args[1], err)
	}

	body := &model.ExtendVolumeSpec{
		NewSize: int64(newSize),
	}

	resp, err := client.ExtendVolume(args[0], body)
	if err != nil {
		Fatalln(HttpErrStrip(err))
	}
	keys := KeyList{"Id", "CreatedAt", "UpdatedAt", "Name", "Description", "Size",
		"AvailabilityZone", "Status", "PoolId", "ProfileId", "Metadata", "GroupId", "MultiAttach"}
	PrintDict(resp, keys, volFormatters)
}
<commit_msg>Fix for CLI issue:1208,1218 and few more CLI improvment<commit_after>// Copyright 2017 The OpenSDS Authors.
//
// 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.
/*
This module implements a entry into the OpenSDS service.

*/

package cli

import (
	"log"
	"os"
	"strconv"

	"github.com/opensds/opensds/pkg/model"
	"github.com/spf13/cobra"
)

var volumeCommand = &cobra.Command{
	Use:   "volume",
	Short: "manage volumes in the cluster",
	Run:   volumeAction,
}

var volumeCreateCommand = &cobra.Command{
	Use:   "create <size>",
	Short: "create a volume in the cluster",
	Example: "osdsctl volume create 1 --name vol-name",
	Run:   volumeCreateAction,
}

var volumeShowCommand = &cobra.Command{
	Use:   "show <id>",
	Short: "show a volume in the cluster",
	Run:   volumeShowAction,
}

var volumeListCommand = &cobra.Command{
	Use:   "list",
	Short: "list all volumes in the cluster",
	Run:   volumeListAction,
}

var volumeDeleteCommand = &cobra.Command{
	Use:   "delete <id>",
	Short: "delete a volume in the cluster",
	Run:   volumeDeleteAction,
}

var volumeUpdateCommand = &cobra.Command{
	Use:   "update <id>",
	Short: "update a volume in the cluster",
	Run:   volumeUpdateAction,
}

var volumeExtendCommand = &cobra.Command{
	Use:   "extend <id> <new size>",
	Short: "extend a volume in the cluster",
	Run:   volumeExtendAction,
}

var (
	profileId string
	//poolId    string
	volName   string
	volDesp   string
	volAz     string
	volSnap   string
)

var (
	volLimit          string
	volOffset         string
	volSortDir        string
	volSortKey        string
	volId             string
	volTenantId       string
	volUserId         string
	volStatus         string
	volPoolId         string
	volProfileId      string
	volGroupId        string
	snapshotFromCloud bool
)

func init() {
	volumeListCommand.Flags().StringVarP(&volLimit, "limit", "", "50", "the number of entries displayed per page")
	volumeListCommand.Flags().StringVarP(&volOffset, "offset", "", "0", "all requested data offsets")
	volumeListCommand.Flags().StringVarP(&volSortDir, "sortDir", "", "desc", "the sort direction of all requested data. supports asc or desc(default)")
	volumeListCommand.Flags().StringVarP(&volSortKey, "sortKey", "", "id",
		"the sort key of all requested data. supports id(default), name, status, availabilityzone, profileid, tenantid, size, poolid, description")
	volumeListCommand.Flags().StringVarP(&volId, "id", "", "", "list volume by id")
	volumeListCommand.Flags().StringVarP(&volName, "name", "", "", "list volume by name")
	volumeListCommand.Flags().StringVarP(&volDesp, "description", "", "", "list volume by description")
	volumeListCommand.Flags().StringVarP(&volTenantId, "tenantId", "", "", "list volume by tenantId")
	volumeListCommand.Flags().StringVarP(&volUserId, "userId", "", "", "list volume by storage userId")
	volumeListCommand.Flags().StringVarP(&volStatus, "status", "", "", "list volume by status")
	volumeListCommand.Flags().StringVarP(&volPoolId, "poolId", "", "", "list volume by poolId")
	volumeListCommand.Flags().StringVarP(&volAz, "availabilityZone", "", "", "list volume by availability zone")
	volumeListCommand.Flags().StringVarP(&volProfileId, "profileId", "", "", "list volume by profile id")
	volumeListCommand.Flags().StringVarP(&volGroupId, "groupId", "", "", "list volume by volume group id")

	volumeCommand.PersistentFlags().StringVarP(&profileId, "profile", "", "", "the id of profile configured by admin")

	volumeCommand.AddCommand(volumeCreateCommand)
	volumeCreateCommand.Flags().StringVarP(&volName, "name", "n", "", "the name of created volume")
	volumeCreateCommand.Flags().StringVarP(&volDesp, "description", "d", "", "the description of created volume")
	volumeCreateCommand.Flags().StringVarP(&volAz, "az", "a", "", "the availability zone of created volume")
	volumeCreateCommand.Flags().StringVarP(&volSnap, "snapshot", "s", "", "the snapshot to create volume")
	volumeCreateCommand.Flags().StringVarP(&poolId, "pool", "p", "", "the pool to create volume")
	volumeCreateCommand.Flags().BoolVarP(&snapshotFromCloud, "snapshotFromCloud", "c", false, "download snapshot from cloud")
	volumeCommand.AddCommand(volumeShowCommand)
	volumeCommand.AddCommand(volumeListCommand)
	volumeCommand.AddCommand(volumeDeleteCommand)
	volumeCommand.AddCommand(volumeUpdateCommand)
	volumeUpdateCommand.Flags().StringVarP(&volName, "name", "n", "", "the name of updated volume")
	volumeUpdateCommand.Flags().StringVarP(&volDesp, "description", "d", "", "the description of updated volume")
	volumeCommand.AddCommand(volumeExtendCommand)

	volumeCommand.AddCommand(volumeSnapshotCommand)
	volumeCommand.AddCommand(volumeAttachmentCommand)
	volumeCommand.AddCommand(volumeGroupCommand)
	volumeCommand.AddCommand(replicationCommand)
}

func volumeAction(cmd *cobra.Command, args []string) {
	cmd.Usage()
	os.Exit(1)
}

var volFormatters = FormatterList{"Metadata": JsonFormatter}

func volumeCreateAction(cmd *cobra.Command, args []string) {
	ArgsNumCheck(cmd, args, 1)
	size, err := strconv.Atoi(args[0])
	if err != nil {
		Fatalln("input size is not valid. It only support integer.")
		log.Fatalf("error parsing size %s: %+v", args[0], err)
	}

	vol := &model.VolumeSpec{
		Name:              volName,
		Description:       volDesp,
		AvailabilityZone:  volAz,
		Size:              int64(size),
		ProfileId:         profileId,
		PoolId:            poolId,
		SnapshotId:        volSnap,
		SnapshotFromCloud: snapshotFromCloud,
	}

	resp, err := client.CreateVolume(vol)
	if err != nil {
		Fatalln(HttpErrStrip(err))
	}

	keys := KeyList{"Id", "CreatedAt", "Name", "Description", "Size", "AvailabilityZone",
		"Status", "PoolId", "ProfileId", "Metadata", "GroupId", "MultiAttach"}
	PrintDict(resp, keys, volFormatters)
}

func volumeShowAction(cmd *cobra.Command, args []string) {
	ArgsNumCheck(cmd, args, 1)
	resp, err := client.GetVolume(args[0])
	if err != nil {
		Fatalln(HttpErrStrip(err))
	}
	keys := KeyList{"Id", "CreatedAt", "UpdatedAt", "Name", "Description", "Size",
		"AvailabilityZone", "Status", "PoolId", "ProfileId", "Metadata", "GroupId", "SnapshotId",
		"MultiAttach"}
	PrintDict(resp, keys, volFormatters)
}

func volumeListAction(cmd *cobra.Command, args []string) {
	ArgsNumCheck(cmd, args, 0)

	var opts = map[string]string{"limit": volLimit, "offset": volOffset, "sortDir": volSortDir,
		"sortKey": volSortKey, "Id": volId,
		"Name": volName, "Description": volDesp, "UserId": volUserId, "AvailabilityZone": volAz,
		"Status": volStatus, "PoolId": volPoolId, "ProfileId": volProfileId, "GroupId": volGroupId}

	resp, err := client.ListVolumes(opts)
	if err != nil {
		Fatalln(HttpErrStrip(err))
	}
	keys := KeyList{"Id", "Name", "Description", "Size", "Status", "ProfileId", "AvailabilityZone"}
	PrintList(resp, keys, volFormatters)
}

func volumeDeleteAction(cmd *cobra.Command, args []string) {
	ArgsNumCheck(cmd, args, 1)
	vol := &model.VolumeSpec{
		ProfileId: profileId,
	}
	err := client.DeleteVolume(args[0], vol)
	if err != nil {
		Fatalln(HttpErrStrip(err))
	}
}

func volumeUpdateAction(cmd *cobra.Command, args []string) {
	ArgsNumCheck(cmd, args, 1)
	vol := &model.VolumeSpec{
		Name:        volName,
		Description: volDesp,
	}

	resp, err := client.UpdateVolume(args[0], vol)
	if err != nil {
		Fatalln(HttpErrStrip(err))
	}
	keys := KeyList{"Id", "UpdatedAt", "Name", "Description", "Size", "AvailabilityZone",
		"Status", "PoolId", "ProfileId", "Metadata", "GroupId", "MultiAttach"}
	PrintDict(resp, keys, volFormatters)
}

func volumeExtendAction(cmd *cobra.Command, args []string) {
	ArgsNumCheck(cmd, args, 2)
	newSize, err := strconv.Atoi(args[1])
	if err != nil {
		log.Fatalf("error parsing new size %s: %+v", args[1], err)
	}

	body := &model.ExtendVolumeSpec{
		NewSize: int64(newSize),
	}

	resp, err := client.ExtendVolume(args[0], body)
	if err != nil {
		Fatalln(HttpErrStrip(err))
	}
	keys := KeyList{"Id", "CreatedAt", "UpdatedAt", "Name", "Description", "Size",
		"AvailabilityZone", "Status", "PoolId", "ProfileId", "Metadata", "GroupId", "MultiAttach"}
	PrintDict(resp, keys, volFormatters)
}
<|endoftext|>


<commit_before>package tent

import (
	"encoding/json"

	"github.com/tent/http-link-go"
)

type PostMention struct {
	Entity         string `json:"entity,omitempty"`
	OriginalEntity string `json:"original_entity,omitempty"`
	Post           string `json:"post,omitempty"`
	Version        string `json:"version,omitempty"`
	Type           string `json:"type,omitempty"`
	Public         *bool  `json:"public"`
}

type PostAttachment struct {
	Name        string `json:"name"`
	Category    string `json:"category"`
	ContentType string `json:"content_type"`
	Size        int64  `json:"size"`
	Digest      string `json:"digest"`
}

type PostPermissions struct {
	Public   bool     `json:"public"`
	Groups   []string `json:"groups,omitempty"`
	Entities []string `json:"entities,omitempty"`
}

type PostApp struct {
	Name string `json:"name,omitempty"`
	URL  string `json:"url,omitempty"`
	ID   string `json:"id,omitempty"`
}

type PostVersionParent struct {
	Entity         string `json:"entity,omitempty"`
	OriginalEntity string `json:"original_entity,omitempty"`
	Post           string `json:"post,omitempty"`
	Version        string `json:"version"`
}

type PostVersion struct {
	ID          string              `json:"id,omitempty"`
	Parents     []PostVersionParent `json:"parents,omitempty"`
	Message     string              `json:"message,omitempty"`
	PublishedAt UnixTime            `json:"published_at"`
	ReceivedAt  UnixTime            `json:"received_at"`

	// Used in post version and children lists
	Type   string `json:"type,omitempty"`
	Entity string `json:"entity,omitempty"`
	Post   string `json:"post,omitempty"`
}

type Post struct {
	ID string `json:"id"`

	Entity         string `json:"entity"`
	OriginalEntity string `json:"original_entity,omitempty"`

	Type    string          `json:"type"`
	Content json.RawMessage `json:"content,omitempty"`

	Version PostVersion `json:"version"`

	Mentions    []PostMention     `json:"mentions,omitempty"`
	Licenses    []string          `json:"licenses,omitempty"`
	Attachments []*PostAttachment `json:"attachments,omitempty"`
	Permissions PostPermissions   `json:"permissions"`

	App PostApp `json:"app,omitempty"`

	ReceivedAt  UnixTime `json:"received_at"`
	PublishedAt UnixTime `json:"published_at"`

	Links []link.Link `json:"-"`
}
<commit_msg>No need for pointers in attachments slice<commit_after>package tent

import (
	"encoding/json"

	"github.com/tent/http-link-go"
)

type PostMention struct {
	Entity         string `json:"entity,omitempty"`
	OriginalEntity string `json:"original_entity,omitempty"`
	Post           string `json:"post,omitempty"`
	Version        string `json:"version,omitempty"`
	Type           string `json:"type,omitempty"`
	Public         *bool  `json:"public"`
}

type PostAttachment struct {
	Name        string `json:"name"`
	Category    string `json:"category"`
	ContentType string `json:"content_type"`
	Size        int64  `json:"size"`
	Digest      string `json:"digest"`
}

type PostPermissions struct {
	Public   bool     `json:"public"`
	Groups   []string `json:"groups,omitempty"`
	Entities []string `json:"entities,omitempty"`
}

type PostApp struct {
	Name string `json:"name,omitempty"`
	URL  string `json:"url,omitempty"`
	ID   string `json:"id,omitempty"`
}

type PostVersionParent struct {
	Entity         string `json:"entity,omitempty"`
	OriginalEntity string `json:"original_entity,omitempty"`
	Post           string `json:"post,omitempty"`
	Version        string `json:"version"`
}

type PostVersion struct {
	ID          string              `json:"id,omitempty"`
	Parents     []PostVersionParent `json:"parents,omitempty"`
	Message     string              `json:"message,omitempty"`
	PublishedAt UnixTime            `json:"published_at"`
	ReceivedAt  UnixTime            `json:"received_at"`

	// Used in post version and children lists
	Type   string `json:"type,omitempty"`
	Entity string `json:"entity,omitempty"`
	Post   string `json:"post,omitempty"`
}

type Post struct {
	ID string `json:"id"`

	Entity         string `json:"entity"`
	OriginalEntity string `json:"original_entity,omitempty"`

	Type    string          `json:"type"`
	Content json.RawMessage `json:"content,omitempty"`

	Version PostVersion `json:"version"`

	Mentions    []PostMention    `json:"mentions,omitempty"`
	Licenses    []string         `json:"licenses,omitempty"`
	Attachments []PostAttachment `json:"attachments,omitempty"`
	Permissions PostPermissions  `json:"permissions"`

	App PostApp `json:"app,omitempty"`

	ReceivedAt  UnixTime `json:"received_at"`
	PublishedAt UnixTime `json:"published_at"`

	Links []link.Link `json:"-"`
}
<|endoftext|>


<commit_before>package magina

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

type PubSubExchanger struct {
	TopicQueue map[string]string
	TopicChan  map[string]chan ExchangeMessage
	MessageIds MessageIds
	Channel    *amqp.Channel
}

func NewPubSubExchanger(channel *amqp.Channel) *PubSubExchanger {
	return &PubSubExchanger{
		Channel: channel,
	}
}

func (pubsub *PubSubExchanger) Init() error {
	if pubsub.TopicQueue == nil {
		pubsub.TopicQueue = make(map[string]string)
	}

	if pubsub.TopicChan == nil {
		pubsub.TopicChan = make(map[string]chan ExchangeMessage)
	}

	return pubsub.Channel.ExchangeDeclare(
		defaultPubsubExchange, // name
		"topic",               // type
		true,                  // durable
		false,                 // auto-deleted
		false,                 // internal
		false,                 // no-wait
		nil,                   // arguments
	)
}

func (pubsub *PubSubExchanger) Publish(msg ExchangeMessage) error {
	if pubsub.Channel == nil {
		return fmt.Errorf("client channel not ready")
	}
	err := pubsub.Channel.Publish(defaultPubsubExchange,
		msg.Topic, false, false,
		amqp.Publishing{
			ContentType: "text/plain",
			Body:        msg.Payload,
		})
	return err
}

func (pubsub *PubSubExchanger) Subscribe(topic string) (chan ExchangeMessage, error) {

	if pubsub.Channel == nil {
		return nil, fmt.Errorf("client channel not ready")
	}
	q, err := pubsub.Channel.QueueDeclare(
		"",    // name
		true,  // durable
		true,  // delete when usused
		true,  // exclusive
		false, // no-wait
		nil,   // arguments
	)
	if err != nil {
		return nil, err
	}

	err = pubsub.Channel.QueueBind(
		q.Name, // queue name
		topic,  // routing key
		defaultPubsubExchange, // exchange
		false,
		nil,
	)
	if err != nil {
		return nil, err
	}

	pubsub.TopicQueue[topic] = q.Name

	msgs, err := pubsub.Channel.Consume(
		q.Name, // queue
		"",     // consumer
		true,   // auto ack
		false,  // exclusive
		false,  // no local
		false,  // no wait
		nil,    // args
	)
	if err != nil {
		return nil, err
	}

	msgChan := make(chan ExchangeMessage)
	pubsub.TopicChan[topic] = msgChan
	go func() {
		for d := range msgs {
			msgChan <- ExchangeMessage{d.RoutingKey, d.Body}
		}
		close(msgChan)
	}()
	return pubsub.TopicChan[topic], nil
}

func (pubsub *PubSubExchanger) Unsubscribe(topic string) error {

	if pubsub.Channel == nil {
		return fmt.Errorf("client channel not ready")
	}

	if queueName, exist := pubsub.TopicQueue[topic]; exist {
		err := pubsub.Channel.QueueUnbind(queueName, topic, defaultPubsubExchange, nil)
		delete(pubsub.TopicQueue, topic)

		close(pubsub.TopicChan[topic])
		delete(pubsub.TopicChan, topic)

		if err != nil {
			return err
		}
	}

	return nil
}
<commit_msg>convert mqtt topic seperator and wildcards to amqp.<commit_after>package magina

import (
	"fmt"
	"strings"

	"github.com/streadway/amqp"
)

type PubSubExchanger struct {
	TopicQueue map[string]string
	TopicChan  map[string]chan ExchangeMessage
	MessageIds MessageIds
	Channel    *amqp.Channel
}

func NewPubSubExchanger(channel *amqp.Channel) *PubSubExchanger {
	return &PubSubExchanger{
		Channel: channel,
	}
}

func (pubsub *PubSubExchanger) Init() error {
	if pubsub.TopicQueue == nil {
		pubsub.TopicQueue = make(map[string]string)
	}

	if pubsub.TopicChan == nil {
		pubsub.TopicChan = make(map[string]chan ExchangeMessage)
	}

	return pubsub.Channel.ExchangeDeclare(
		defaultPubsubExchange, // name
		"topic",               // type
		true,                  // durable
		false,                 // auto-deleted
		false,                 // internal
		false,                 // no-wait
		nil,                   // arguments
	)
}

func (pubsub *PubSubExchanger) convMQTTTopic2AMQP(topic string) string {
	return strings.Replace(strings.Replace(topic, "/", ".", -1), "+", "*", -1)
}

func (pubsub *PubSubExchanger) convAMQPopic2MQTT(topic string) string {
	return strings.Replace(strings.Replace(topic, ".", "/", -1), "*", "+", -1)
}

func (pubsub *PubSubExchanger) Publish(msg ExchangeMessage) error {
	if pubsub.Channel == nil {
		return fmt.Errorf("client channel not ready")
	}
	err := pubsub.Channel.Publish(defaultPubsubExchange,
		pubsub.convMQTTTopic2AMQP(msg.Topic), false, false,
		amqp.Publishing{
			ContentType: "text/plain",
			Body:        msg.Payload,
		})
	return err
}

func (pubsub *PubSubExchanger) Subscribe(topic string) (chan ExchangeMessage, error) {

	if pubsub.Channel == nil {
		return nil, fmt.Errorf("client channel not ready")
	}
	q, err := pubsub.Channel.QueueDeclare(
		"",    // name
		true,  // durable
		true,  // delete when usused
		true,  // exclusive
		false, // no-wait
		nil,   // arguments
	)
	if err != nil {
		return nil, err
	}

	err = pubsub.Channel.QueueBind(
		q.Name, // queue name
		pubsub.convMQTTTopic2AMQP(topic), // routing key
		defaultPubsubExchange,            // exchange
		false,
		nil,
	)
	if err != nil {
		return nil, err
	}

	pubsub.TopicQueue[topic] = q.Name

	msgs, err := pubsub.Channel.Consume(
		q.Name, // queue
		"",     // consumer
		true,   // auto ack
		false,  // exclusive
		false,  // no local
		false,  // no wait
		nil,    // args
	)
	if err != nil {
		return nil, err
	}

	msgChan := make(chan ExchangeMessage)
	pubsub.TopicChan[topic] = msgChan
	go func() {
		for d := range msgs {
			msgChan <- ExchangeMessage{d.RoutingKey, d.Body}
		}
		close(msgChan)
	}()
	return pubsub.TopicChan[topic], nil
}

func (pubsub *PubSubExchanger) Unsubscribe(topic string) error {

	if pubsub.Channel == nil {
		return fmt.Errorf("client channel not ready")
	}

	if queueName, exist := pubsub.TopicQueue[topic]; exist {
		err := pubsub.Channel.QueueUnbind(queueName, pubsub.convMQTTTopic2AMQP(topic), defaultPubsubExchange, nil)
		delete(pubsub.TopicQueue, topic)

		close(pubsub.TopicChan[topic])
		delete(pubsub.TopicChan, topic)

		if err != nil {
			return err
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package proc

import (
	"debug/gosym"
	"fmt"
	"path/filepath"

	"github.com/derekparker/delve/dwarf/frame"
	"github.com/derekparker/delve/source"
	sys "golang.org/x/sys/unix"
)

// Thread represents a single thread in the traced process
// Id represents the thread id or port, Process holds a reference to the
// Process struct that contains info on the process as
// a whole, and Status represents the last result of a `wait` call
// on this thread.
type Thread struct {
	Id                int             // Thread ID or mach port
	Status            *sys.WaitStatus // Status returned from last wait call
	CurrentBreakpoint *Breakpoint     // Breakpoint thread is currently stopped at

	dbp            *Process
	singleStepping bool
	running        bool
	os             *OSSpecificDetails
}

// Represents the location of a thread.
// Holds information on the current instruction
// address, the source file:line, and the function.
type Location struct {
	PC   uint64
	File string
	Line int
	Fn   *gosym.Func
}

// Continue the execution of this thread.
//
// If we are currently at a breakpoint, we'll clear it
// first and then resume execution. Thread will continue until
// it hits a breakpoint or is signaled.
func (thread *Thread) Continue() error {
	pc, err := thread.PC()
	if err != nil {
		return err
	}

	// Check whether we are stopped at a breakpoint, and
	// if so, single step over it before continuing.
	if _, ok := thread.dbp.Breakpoints[pc]; ok {
		if err := thread.Step(); err != nil {
			return err
		}
	}
	return thread.resume()
}

// Step a single instruction.
//
// Executes exactly one instruction and then returns.
// If the thread is at a breakpoint, we first clear it,
// execute the instruction, and then replace the breakpoint.
// Otherwise we simply execute the next instruction.
func (thread *Thread) Step() (err error) {
	thread.running = true
	thread.singleStepping = true
	defer func() {
		thread.singleStepping = false
		thread.running = false
	}()
	pc, err := thread.PC()
	if err != nil {
		return err
	}

	bp, ok := thread.dbp.Breakpoints[pc]
	if ok {
		// Clear the breakpoint so that we can continue execution.
		_, err = bp.Clear(thread)
		if err != nil {
			return err
		}

		// Restore breakpoint now that we have passed it.
		defer func() {
			if bp.hardware {
				err = thread.dbp.setHardwareBreakpoint(bp.reg, thread.Id, bp.Addr)
			} else {
				err = thread.dbp.writeSoftwareBreakpoint(thread, bp.Addr)
			}
		}()
	}

	err = thread.singleStep()
	if err != nil {
		return fmt.Errorf("step failed: %s", err.Error())
	}
	return nil
}

// Returns the threads location, including the file:line
// of the corresponding source code, the function we're in
// and the current instruction address.
func (thread *Thread) Location() (*Location, error) {
	pc, err := thread.PC()
	if err != nil {
		return nil, err
	}
	f, l, fn := thread.dbp.PCToLine(pc)
	return &Location{PC: pc, File: f, Line: l, Fn: fn}, nil
}

// Set breakpoints for potential next lines.
//
// There are two modes of operation for this method. First,
// if we are executing Go code, we can use the stdlib AST
// information to determine which lines we could potentially
// end up at. Parsing the source file into an AST and traversing
// it lets us gain insight into whether we're at a branch, and
// where that branch could end up at, etc...
//
// However, if we are executing C code, we use the DWARF
// debug_line information and essentially set a breakpoint
// at every single line within the current function, and
// another at the functions return address, in case we're at
// the end.
func (thread *Thread) SetNextBreakpoints() (err error) {
	curpc, err := thread.PC()
	if err != nil {
		return err
	}

	// Grab info on our current stack frame. Used to determine
	// whether we may be stepping outside of the current function.
	fde, err := thread.dbp.frameEntries.FDEForPC(curpc)
	if err != nil {
		return err
	}

	// Get current file/line.
	loc, err := thread.Location()
	if err != nil {
		return err
	}
	if filepath.Ext(loc.File) == ".go" {
		if err = thread.next(curpc, fde, loc.File, loc.Line); err != nil {
			return err
		}
	} else {
		if err = thread.cnext(curpc, fde); err != nil {
			return err
		}
	}
	return nil
}

// Go routine is exiting.
type GoroutineExitingError struct {
	goid int
}

func (ge GoroutineExitingError) Error() string {
	return fmt.Sprintf("goroutine %d is exiting", ge.goid)
}

// Use the AST to determine potential next lines.
func (thread *Thread) next(curpc uint64, fde *frame.FrameDescriptionEntry, file string, line int) error {
	lines, err := thread.dbp.ast.NextLines(file, line)
	if err != nil {
		if _, ok := err.(source.NoNodeError); !ok {
			return err
		}
	}

	ret, err := thread.ReturnAddress()
	if err != nil {
		return err
	}

	pcs := make([]uint64, 0, len(lines))
	for i := range lines {
		pcs = append(pcs, thread.dbp.lineInfo.AllPCsForFileLine(file, lines[i])...)
	}

	var covered bool
	for i := range pcs {
		if fde.Cover(pcs[i]) {
			covered = true
			break
		}
	}

	if !covered {
		fn := thread.dbp.goSymTable.PCToFunc(ret)
		if fn != nil && fn.Name == "runtime.goexit" {
			g, err := thread.getG()
			if err != nil {
				return err
			}
			return GoroutineExitingError{goid: g.Id}
		}
	}
	pcs = append(pcs, ret)
	return thread.setNextTempBreakpoints(curpc, pcs)
}

// Set a breakpoint at every reachable location, as well as the return address. Without
// the benefit of an AST we can't be sure we're not at a branching statement and thus
// cannot accurately predict where we may end up.
func (thread *Thread) cnext(curpc uint64, fde *frame.FrameDescriptionEntry) error {
	pcs := thread.dbp.lineInfo.AllPCsBetween(fde.Begin(), fde.End())
	ret, err := thread.ReturnAddress()
	if err != nil {
		return err
	}
	pcs = append(pcs, ret)
	return thread.setNextTempBreakpoints(curpc, pcs)
}

func (thread *Thread) setNextTempBreakpoints(curpc uint64, pcs []uint64) error {
	for i := range pcs {
		if pcs[i] == curpc || pcs[i] == curpc-1 {
			continue
		}
		if _, err := thread.dbp.SetTempBreakpoint(pcs[i]); err != nil {
			if _, ok := err.(BreakpointExistsError); !ok {
				return err
			}
		}
	}
	return nil
}

// Sets the PC for this thread.
func (thread *Thread) SetPC(pc uint64) error {
	regs, err := thread.Registers()
	if err != nil {
		return err
	}
	return regs.SetPC(thread, pc)
}

// Returns information on the G (goroutine) that is executing on this thread.
//
// The G structure for a thread is stored in thread local memory. Execute instructions
// that move the *G structure into a CPU register, and then grab
// the new registers and parse the G structure.
//
// We cannot simply use the allg linked list in order to find the M that represents
// the given OS thread and follow its G pointer because on Darwin mach ports are not
// universal, so our port for this thread would not map to the `id` attribute of the M
// structure. Also, when linked against libc, Go prefers the libc version of clone as
// opposed to the runtime version. This has the consequence of not setting M.id for
// any thread, regardless of OS.
//
// In order to get around all this craziness, we write the instructions to retrieve the G
// structure running on this thread (which is stored in thread local memory) into the
// current instruction stream. The instructions are obviously arch/os dependant, as they
// vary on how thread local storage is implemented, which MMU register is used and
// what the offset into thread local storage is.
func (thread *Thread) getG() (g *G, err error) {
	var pcInt uint64
	pcInt, err = thread.PC()
	if err != nil {
		return
	}
	pc := uintptr(pcInt)
	// Read original instructions.
	originalInstructions := make([]byte, len(thread.dbp.arch.CurgInstructions()))
	if _, err = readMemory(thread, pc, originalInstructions); err != nil {
		return
	}
	// Write new instructions.
	if _, err = writeMemory(thread, pc, thread.dbp.arch.CurgInstructions()); err != nil {
		return
	}
	// We're going to be intentionally modifying the registers
	// once we execute the code we inject into the instruction stream,
	// so save them off here so we can restore them later.
	if _, err = thread.saveRegisters(); err != nil {
		return
	}
	// Ensure original instructions and PC are both restored.
	defer func() {
		// Do not shadow previous error, if there was one.
		originalErr := err
		// Restore the original instructions and register contents.
		if _, err = writeMemory(thread, pc, originalInstructions); err != nil {
			return
		}
		if err = thread.restoreRegisters(); err != nil {
			return
		}
		err = originalErr
		return
	}()
	// Execute new instructions.
	if err = thread.resume(); err != nil {
		return
	}
	// Set the halt flag so that trapWait will ignore the fact that
	// we hit a breakpoint that isn't captured in our list of
	// known breakpoints.
	thread.dbp.halt = true
	defer func(dbp *Process) { dbp.halt = false }(thread.dbp)
	if _, err = thread.dbp.trapWait(-1); err != nil {
		return
	}
	// Grab *G from RCX.
	regs, err := thread.Registers()
	if err != nil {
		return nil, err
	}
	g, err = parseG(thread, regs.CX(), false)
	if err == nil {
		g.thread = thread
	}
	return
}
<commit_msg>Check thread.CurrentBreakpoint instead of PC lookup<commit_after>package proc

import (
	"debug/gosym"
	"fmt"
	"path/filepath"

	"github.com/derekparker/delve/dwarf/frame"
	"github.com/derekparker/delve/source"
	sys "golang.org/x/sys/unix"
)

// Thread represents a single thread in the traced process
// Id represents the thread id or port, Process holds a reference to the
// Process struct that contains info on the process as
// a whole, and Status represents the last result of a `wait` call
// on this thread.
type Thread struct {
	Id                int             // Thread ID or mach port
	Status            *sys.WaitStatus // Status returned from last wait call
	CurrentBreakpoint *Breakpoint     // Breakpoint thread is currently stopped at

	dbp            *Process
	singleStepping bool
	running        bool
	os             *OSSpecificDetails
}

// Represents the location of a thread.
// Holds information on the current instruction
// address, the source file:line, and the function.
type Location struct {
	PC   uint64
	File string
	Line int
	Fn   *gosym.Func
}

// Continue the execution of this thread.
//
// If we are currently at a breakpoint, we'll clear it
// first and then resume execution. Thread will continue until
// it hits a breakpoint or is signaled.
func (thread *Thread) Continue() error {
	// Check whether we are stopped at a breakpoint, and
	// if so, single step over it before continuing.
	if thread.CurrentBreakpoint != nil {
		if !thread.CurrentBreakpoint.hardware {
			if err := thread.Step(); err != nil {
				return err
			}
		}
	}
	return thread.resume()
}

// Step a single instruction.
//
// Executes exactly one instruction and then returns.
// If the thread is at a breakpoint, we first clear it,
// execute the instruction, and then replace the breakpoint.
// Otherwise we simply execute the next instruction.
func (thread *Thread) Step() (err error) {
	thread.running = true
	thread.singleStepping = true
	defer func() {
		thread.singleStepping = false
		thread.running = false
	}()
	pc, err := thread.PC()
	if err != nil {
		return err
	}

	bp, ok := thread.dbp.Breakpoints[pc]
	if ok {
		// Clear the breakpoint so that we can continue execution.
		_, err = bp.Clear(thread)
		if err != nil {
			return err
		}

		// Restore breakpoint now that we have passed it.
		defer func() {
			if bp.hardware {
				err = thread.dbp.setHardwareBreakpoint(bp.reg, thread.Id, bp.Addr)
			} else {
				err = thread.dbp.writeSoftwareBreakpoint(thread, bp.Addr)
			}
		}()
	}

	err = thread.singleStep()
	if err != nil {
		return fmt.Errorf("step failed: %s", err.Error())
	}
	return nil
}

// Returns the threads location, including the file:line
// of the corresponding source code, the function we're in
// and the current instruction address.
func (thread *Thread) Location() (*Location, error) {
	pc, err := thread.PC()
	if err != nil {
		return nil, err
	}
	f, l, fn := thread.dbp.PCToLine(pc)
	return &Location{PC: pc, File: f, Line: l, Fn: fn}, nil
}

// Set breakpoints for potential next lines.
//
// There are two modes of operation for this method. First,
// if we are executing Go code, we can use the stdlib AST
// information to determine which lines we could potentially
// end up at. Parsing the source file into an AST and traversing
// it lets us gain insight into whether we're at a branch, and
// where that branch could end up at, etc...
//
// However, if we are executing C code, we use the DWARF
// debug_line information and essentially set a breakpoint
// at every single line within the current function, and
// another at the functions return address, in case we're at
// the end.
func (thread *Thread) SetNextBreakpoints() (err error) {
	curpc, err := thread.PC()
	if err != nil {
		return err
	}

	// Grab info on our current stack frame. Used to determine
	// whether we may be stepping outside of the current function.
	fde, err := thread.dbp.frameEntries.FDEForPC(curpc)
	if err != nil {
		return err
	}

	// Get current file/line.
	loc, err := thread.Location()
	if err != nil {
		return err
	}
	if filepath.Ext(loc.File) == ".go" {
		if err = thread.next(curpc, fde, loc.File, loc.Line); err != nil {
			return err
		}
	} else {
		if err = thread.cnext(curpc, fde); err != nil {
			return err
		}
	}
	return nil
}

// Go routine is exiting.
type GoroutineExitingError struct {
	goid int
}

func (ge GoroutineExitingError) Error() string {
	return fmt.Sprintf("goroutine %d is exiting", ge.goid)
}

// Use the AST to determine potential next lines.
func (thread *Thread) next(curpc uint64, fde *frame.FrameDescriptionEntry, file string, line int) error {
	lines, err := thread.dbp.ast.NextLines(file, line)
	if err != nil {
		if _, ok := err.(source.NoNodeError); !ok {
			return err
		}
	}

	ret, err := thread.ReturnAddress()
	if err != nil {
		return err
	}

	pcs := make([]uint64, 0, len(lines))
	for i := range lines {
		pcs = append(pcs, thread.dbp.lineInfo.AllPCsForFileLine(file, lines[i])...)
	}

	var covered bool
	for i := range pcs {
		if fde.Cover(pcs[i]) {
			covered = true
			break
		}
	}

	if !covered {
		fn := thread.dbp.goSymTable.PCToFunc(ret)
		if fn != nil && fn.Name == "runtime.goexit" {
			g, err := thread.getG()
			if err != nil {
				return err
			}
			return GoroutineExitingError{goid: g.Id}
		}
	}
	pcs = append(pcs, ret)
	return thread.setNextTempBreakpoints(curpc, pcs)
}

// Set a breakpoint at every reachable location, as well as the return address. Without
// the benefit of an AST we can't be sure we're not at a branching statement and thus
// cannot accurately predict where we may end up.
func (thread *Thread) cnext(curpc uint64, fde *frame.FrameDescriptionEntry) error {
	pcs := thread.dbp.lineInfo.AllPCsBetween(fde.Begin(), fde.End())
	ret, err := thread.ReturnAddress()
	if err != nil {
		return err
	}
	pcs = append(pcs, ret)
	return thread.setNextTempBreakpoints(curpc, pcs)
}

func (thread *Thread) setNextTempBreakpoints(curpc uint64, pcs []uint64) error {
	for i := range pcs {
		if pcs[i] == curpc || pcs[i] == curpc-1 {
			continue
		}
		if _, err := thread.dbp.SetTempBreakpoint(pcs[i]); err != nil {
			if _, ok := err.(BreakpointExistsError); !ok {
				return err
			}
		}
	}
	return nil
}

// Sets the PC for this thread.
func (thread *Thread) SetPC(pc uint64) error {
	regs, err := thread.Registers()
	if err != nil {
		return err
	}
	return regs.SetPC(thread, pc)
}

// Returns information on the G (goroutine) that is executing on this thread.
//
// The G structure for a thread is stored in thread local memory. Execute instructions
// that move the *G structure into a CPU register, and then grab
// the new registers and parse the G structure.
//
// We cannot simply use the allg linked list in order to find the M that represents
// the given OS thread and follow its G pointer because on Darwin mach ports are not
// universal, so our port for this thread would not map to the `id` attribute of the M
// structure. Also, when linked against libc, Go prefers the libc version of clone as
// opposed to the runtime version. This has the consequence of not setting M.id for
// any thread, regardless of OS.
//
// In order to get around all this craziness, we write the instructions to retrieve the G
// structure running on this thread (which is stored in thread local memory) into the
// current instruction stream. The instructions are obviously arch/os dependant, as they
// vary on how thread local storage is implemented, which MMU register is used and
// what the offset into thread local storage is.
func (thread *Thread) getG() (g *G, err error) {
	var pcInt uint64
	pcInt, err = thread.PC()
	if err != nil {
		return
	}
	pc := uintptr(pcInt)
	// Read original instructions.
	originalInstructions := make([]byte, len(thread.dbp.arch.CurgInstructions()))
	if _, err = readMemory(thread, pc, originalInstructions); err != nil {
		return
	}
	// Write new instructions.
	if _, err = writeMemory(thread, pc, thread.dbp.arch.CurgInstructions()); err != nil {
		return
	}
	// We're going to be intentionally modifying the registers
	// once we execute the code we inject into the instruction stream,
	// so save them off here so we can restore them later.
	if _, err = thread.saveRegisters(); err != nil {
		return
	}
	// Ensure original instructions and PC are both restored.
	defer func() {
		// Do not shadow previous error, if there was one.
		originalErr := err
		// Restore the original instructions and register contents.
		if _, err = writeMemory(thread, pc, originalInstructions); err != nil {
			return
		}
		if err = thread.restoreRegisters(); err != nil {
			return
		}
		err = originalErr
		return
	}()
	// Execute new instructions.
	if err = thread.resume(); err != nil {
		return
	}
	// Set the halt flag so that trapWait will ignore the fact that
	// we hit a breakpoint that isn't captured in our list of
	// known breakpoints.
	thread.dbp.halt = true
	defer func(dbp *Process) { dbp.halt = false }(thread.dbp)
	if _, err = thread.dbp.trapWait(-1); err != nil {
		return
	}
	// Grab *G from RCX.
	regs, err := thread.Registers()
	if err != nil {
		return nil, err
	}
	g, err = parseG(thread, regs.CX(), false)
	if err == nil {
		g.thread = thread
	}
	return
}
<|endoftext|>


<commit_before>package main

import (
	"testing"

	"encoding/json"
	"os"
)

func TestIsLooseJSONTrue(t *testing.T) {
	uffile, err := os.Open("test_data/test_unformatted.json")
	if err != nil {
		return
	}
	defer uffile.Close()
	// Expect unformatted json to return true
	loose, err := IsLooseJSON(uffile)
	if err != nil {
		t.Error("Error returned, not expected: ", err)
	} else if !loose {
		t.Error("Expected loose, but was not loose")
	}
}

func TestIsLooseJSONFalse(t *testing.T) {
	ffile, err := os.Open("test_data/test_formatted.json")
	if err != nil {
		return
	}
	defer ffile.Close()
	// Expect formatted json to return false
	loose, err := IsLooseJSON(ffile)
	if err != nil {
		t.Error("Error returned, not expected: ", err)
	} else if loose {
		t.Error("Expected not loose, but was loose")
	}
}

func TestStrictifyJSONSmall(t *testing.T) {
	uffile, err := os.Open("test_data/test_unformatted_small.json")
	if err != nil {
		return
	}
	defer uffile.Close()
	ffile, err := os.Open("test_data/test_processed_small.json")
	if err != nil {
		return
	}
	defer ffile.Close()

	var desired interface{}
	if err = json.NewDecoder(ffile).Decode(&desired); err != nil {
		t.Error("Error returned decoding json, not expected: ", err)
	}

	check, err := ProcessJSON(uffile)
	if err != nil {
		t.Error("Error returned, not expected: ", err)
	}
	temp1, _ := json.Marshal(&check)
	temp2, _ := json.Marshal(&desired)

	if string(temp1) != string(temp2) {
		t.Error("StrictifyJSON did not work on a small file")
	}
}

func TestStrictifyJSONLarge(t *testing.T) {
	uffile, err := os.Open("test_data/test_unformatted.json")
	if err != nil {
		return
	}
	defer uffile.Close()
	ffile, err := os.Open("test_data/test_processed.json")
	if err != nil {
		return
	}
	defer ffile.Close()

	var desired interface{}
	if err = json.NewDecoder(ffile).Decode(&desired); err != nil {
		t.Error("Error returned decoding json, not expected: ", err)
	}

	check, err := ProcessJSON(uffile)
	if err != nil {
		t.Error("Error returned, not expected: ", err)
	}
	temp1, _ := json.Marshal(&check)
	temp2, _ := json.Marshal(&desired)

	if string(temp1) != string(temp2) {
		t.Error("StrictifyJSON did not work on a large file")
	}
}

func BenchmarkJSONFull(b *testing.B) {
	// NOTE: hk_feedback.json is a local file containing all Home and Kitchen review
	// data from Amazon (see README), which I did not commit because of file size.
	hk, err := os.Open("test_data/hk_feedback.json")
	if err != nil {
		return
	}
	defer hk.Close()

	b.StartTimer()
	out, err := ProcessJSON(hk)
	b.StopTimer()
	if err != nil {
		b.Error("ProcessJSON did not work on a yuge file")
	}

	if err := WriteCSVToStdOut(out); err != nil {
		return
	}

}
<commit_msg>sift-50 reformatted benchmark of full hk_feedback.json so stdout doesn't print unless specified<commit_after>package main

import (
	"testing"

	"encoding/json"
	"os"
)

func TestIsLooseJSONTrue(t *testing.T) {
	uffile, err := os.Open("test_data/test_unformatted.json")
	if err != nil {
		return
	}
	defer uffile.Close()
	// Expect unformatted json to return true
	loose, err := IsLooseJSON(uffile)
	if err != nil {
		t.Error("Error returned, not expected: ", err)
	} else if !loose {
		t.Error("Expected loose, but was not loose")
	}
}

func TestIsLooseJSONFalse(t *testing.T) {
	ffile, err := os.Open("test_data/test_formatted.json")
	if err != nil {
		return
	}
	defer ffile.Close()
	// Expect formatted json to return false
	loose, err := IsLooseJSON(ffile)
	if err != nil {
		t.Error("Error returned, not expected: ", err)
	} else if loose {
		t.Error("Expected not loose, but was loose")
	}
}

func TestStrictifyJSONSmall(t *testing.T) {
	uffile, err := os.Open("test_data/test_unformatted_small.json")
	if err != nil {
		return
	}
	defer uffile.Close()
	ffile, err := os.Open("test_data/test_processed_small.json")
	if err != nil {
		return
	}
	defer ffile.Close()

	var desired interface{}
	if err = json.NewDecoder(ffile).Decode(&desired); err != nil {
		t.Error("Error returned decoding json, not expected: ", err)
	}

	check, err := ProcessJSON(uffile)
	if err != nil {
		t.Error("Error returned, not expected: ", err)
	}
	temp1, _ := json.Marshal(&check)
	temp2, _ := json.Marshal(&desired)

	if string(temp1) != string(temp2) {
		t.Error("StrictifyJSON did not work on a small file")
	}
}

func TestStrictifyJSONLarge(t *testing.T) {
	uffile, err := os.Open("test_data/test_unformatted.json")
	if err != nil {
		return
	}
	defer uffile.Close()
	ffile, err := os.Open("test_data/test_processed.json")
	if err != nil {
		return
	}
	defer ffile.Close()

	var desired interface{}
	if err = json.NewDecoder(ffile).Decode(&desired); err != nil {
		t.Error("Error returned decoding json, not expected: ", err)
	}

	check, err := ProcessJSON(uffile)
	if err != nil {
		t.Error("Error returned, not expected: ", err)
	}
	temp1, _ := json.Marshal(&check)
	temp2, _ := json.Marshal(&desired)

	if string(temp1) != string(temp2) {
		t.Error("StrictifyJSON did not work on a large file")
	}
}

func BenchmarkJSONFull(b *testing.B) {
	// NOTE: hk_feedback.json is a local file containing all Home and Kitchen review
	// data from Amazon (see README), which I did not commit because of file size.
	b.StopTimer()
	hk, err := os.Open("test_data/hk_feedback.json")
	if err != nil {
		return
	}
	defer hk.Close()

	b.StartTimer()
	// Uncomment following two commented sections to write data to stdout as csv
	// out, err := ProcessJSON(hk)
	_, err = ProcessJSON(hk)
	b.StopTimer()
	if err != nil {
		b.Error("ProcessJSON did not work on a yuge file")
	}

	// if err := WriteCSVToStdOut(out); err != nil {
	// 	return
	// }

}
<|endoftext|>


<commit_before>package bamstats

import (
	"bytes"
	"os"
	"runtime"
	"testing"

	"github.com/guigolab/bamstats/stats"
	"github.com/guigolab/bamstats/utils"
	// . "github.com/guigolab/bamstats/stats"
	// . "github.com/guigolab/bamstats/utils"
)

func checkTest(err error, t *testing.T) {
	if err != nil {
		t.Error(err)
	}
}

var (
	bamFile                  = "data/process-test.bam"
	expectedGeneralJSON      = "data/expected-general.json"
	expectedCoverageJSON     = "data/expected-coverage.json"
	expectedCoverageUniqJSON = "data/expected-coverage-uniq.json"
	annotationFiles          = []string{"data/coverage-test.bed", "data/coverage-test.gtf.gz"}
	maxBuf                   = 1000000
	reads                    = -1
)

func readExpected(path string, t *testing.T) []byte {
	f, err := os.Open(path)
	checkTest(err, t)
	var b bytes.Buffer
	_, err = b.ReadFrom(f)
	checkTest(err, t)
	return b.Bytes()
}

func TestGeneral(t *testing.T) {
	var b bytes.Buffer
	out, err := Process(bamFile, "", runtime.GOMAXPROCS(-1), maxBuf, reads, false)
	checkTest(err, t)
	l := len(out)
	if l > 1 {
		t.Errorf("(Process) Expected StatsMap of length 1, got %d", l)
	}
	_, ok := out["general"].(*stats.GeneralStats)
	if !ok {
		t.Errorf("(Process) Wrong return type - expected GeneralStats, got %T", out["general"])
	}
	utils.OutputJSON(&b, out)
	stats := readExpected(expectedGeneralJSON, t)
	if len(b.Bytes()) != len(stats) {
		t.Error("(Process) GeneralStats are different")
	}
}

func TestCoverage(t *testing.T) {
	var b bytes.Buffer
	for _, annotationFile := range annotationFiles {
		b.Reset()
		out, err := Process(bamFile, annotationFile, runtime.GOMAXPROCS(-1), maxBuf, reads, false)
		checkTest(err, t)
		l := len(out)
		if l > 2 {
			t.Errorf("(Process) Expected StatsMap of length 2, got %d", l)
		}
		_, ok := out["general"].(*stats.GeneralStats)
		if !ok {
			t.Errorf("(Process) Wrong return type - expected GeneralStats, got %T", out["general"])
		}
		_, ok = out["coverage"].(*stats.CoverageStats)
		if !ok {
			t.Errorf("(Process) Wrong return type - expected CoverageStats, got %T", out["coverage"])
		}
		utils.OutputJSON(&b, out)
		stats := readExpected(expectedCoverageJSON, t)
		if len(b.Bytes()) != len(stats) {
			t.Error("(Process) CoverageStats are different")
		}
	}
}

func TestCoverageUniq(t *testing.T) {
	var b bytes.Buffer
	for _, annotationFile := range annotationFiles {
		b.Reset()
		out, err := Process(bamFile, annotationFile, runtime.GOMAXPROCS(-1), maxBuf, reads, true)
		checkTest(err, t)
		l := len(out)
		if l > 3 {
			t.Errorf("(Process) Expected StatsMap of length 3, got %d", l)
		}
		_, ok := out["general"].(*stats.GeneralStats)
		if !ok {
			t.Errorf("(Process) Wrong return type - expected GeneralStats, got %T", out["general"])
		}
		_, ok = out["coverage"].(*stats.CoverageStats)
		if !ok {
			t.Errorf("(Process) Wrong return type - expected CoverageStats, got %T", out["coverage"])
		}
		utils.OutputJSON(&b, out)
		stats := readExpected(expectedCoverageUniqJSON, t)
		if len(b.Bytes()) != len(stats) {
			t.Error("(Process) CoverageStats are different")
		}
	}
}

func BenchmarkGeneral(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Process(bamFile, "", runtime.GOMAXPROCS(-1), maxBuf, reads, false)
	}
}

func BenchmarkCoverage(b *testing.B) {
	for _, annotationFile := range annotationFiles {
		for i := 0; i < b.N; i++ {
			Process(bamFile, annotationFile, runtime.GOMAXPROCS(-1), maxBuf, reads, false)
		}
	}
}
<commit_msg>Add code for dumping JSON stats to file if test failing<commit_after>package bamstats

import (
	"bytes"
	"os"
	"runtime"
	"testing"

	"github.com/guigolab/bamstats/stats"
	"github.com/guigolab/bamstats/utils"
)

func checkTest(err error, t *testing.T) {
	if err != nil {
		t.Error(err)
	}
}

var (
	bamFile                  = "data/process-test.bam"
	expectedGeneralJSON      = "data/expected-general.json"
	expectedCoverageJSON     = "data/expected-coverage.json"
	expectedCoverageUniqJSON = "data/expected-coverage-uniq.json"
	annotationFiles          = []string{"data/coverage-test.bed", "data/coverage-test.gtf.gz"}
	maxBuf                   = 1000000
	reads                    = -1
)

func readExpected(path string, t *testing.T) []byte {
	f, err := os.Open(path)
	checkTest(err, t)
	var b bytes.Buffer
	_, err = b.ReadFrom(f)
	checkTest(err, t)
	return b.Bytes()
}

func TestGeneral(t *testing.T) {
	var b bytes.Buffer
	out, err := Process(bamFile, "", runtime.GOMAXPROCS(-1), maxBuf, reads, false)
	checkTest(err, t)
	l := len(out)
	if l > 1 {
		t.Errorf("(Process) Expected StatsMap of length 1, got %d", l)
	}
	_, ok := out["general"].(*stats.GeneralStats)
	if !ok {
		t.Errorf("(Process) Wrong return type - expected GeneralStats, got %T", out["general"])
	}
	utils.OutputJSON(&b, out)
	stats := readExpected(expectedGeneralJSON, t)
	if len(b.Bytes()) != len(stats) {
		err := dump(b, "observed-general.json")
		if err != nil {
			t.Errorf("(Process) Debug dump error: %s", err)
		}
		t.Error("(Process) GeneralStats are different")
	}
}

func TestCoverage(t *testing.T) {
	var b bytes.Buffer
	for _, annotationFile := range annotationFiles {
		b.Reset()
		out, err := Process(bamFile, annotationFile, runtime.GOMAXPROCS(-1), maxBuf, reads, false)
		checkTest(err, t)
		l := len(out)
		if l > 2 {
			t.Errorf("(Process) Expected StatsMap of length 2, got %d", l)
		}
		_, ok := out["general"].(*stats.GeneralStats)
		if !ok {
			t.Errorf("(Process) Wrong return type - expected GeneralStats, got %T", out["general"])
		}
		_, ok = out["coverage"].(*stats.CoverageStats)
		if !ok {
			t.Errorf("(Process) Wrong return type - expected CoverageStats, got %T", out["coverage"])
		}
		utils.OutputJSON(&b, out)
		stats := readExpected(expectedCoverageJSON, t)
		if len(b.Bytes()) != len(stats) {
			err := dump(b, "observed-coverage.json")
			if err != nil {
				t.Errorf("(Process) Debug dump error: %s", err)
			}
			t.Error("(Process) CoverageStats are different")
		}
	}
}

func TestCoverageUniq(t *testing.T) {
	var b bytes.Buffer
	for _, annotationFile := range annotationFiles {
		b.Reset()
		out, err := Process(bamFile, annotationFile, runtime.GOMAXPROCS(-1), maxBuf, reads, true)
		checkTest(err, t)
		l := len(out)
		if l > 3 {
			t.Errorf("(Process) Expected StatsMap of length 3, got %d", l)
		}
		_, ok := out["general"].(*stats.GeneralStats)
		if !ok {
			t.Errorf("(Process) Wrong return type - expected GeneralStats, got %T", out["general"])
		}
		_, ok = out["coverage"].(*stats.CoverageStats)
		if !ok {
			t.Errorf("(Process) Wrong return type - expected CoverageStats, got %T", out["coverage"])
		}
		utils.OutputJSON(&b, out)
		stats := readExpected(expectedCoverageUniqJSON, t)
		if len(b.Bytes()) != len(stats) {
			err := dump(b, "observed-coverage-uniq.json")
			if err != nil {
				t.Errorf("(Process) Debug dump error: %s", err)
			}
			t.Error("(Process) CoverageStats are different")
		}
	}
}

func BenchmarkGeneral(b *testing.B) {
	for i := 0; i < b.N; i++ {
		Process(bamFile, "", runtime.GOMAXPROCS(-1), maxBuf, reads, false)
	}
}

func BenchmarkCoverage(b *testing.B) {
	for _, annotationFile := range annotationFiles {
		for i := 0; i < b.N; i++ {
			Process(bamFile, annotationFile, runtime.GOMAXPROCS(-1), maxBuf, reads, false)
		}
	}
}

func dump(b bytes.Buffer, fname string) error {
	s, err := os.Create(fname)
	if err != nil {
		return err
	}
	defer s.Close()
	_, err = s.Write(b.Bytes())
	return err
}
<|endoftext|>


<commit_before>package producer

// TODO:
<commit_msg>init nsq plugin<commit_after>// Package producer push decoded messages to messaging queue
//: ----------------------------------------------------------------------------
//: Copyright (C) 2017 Verizon.  All Rights Reserved.
//: All Rights Reserved
//:
//: file:    kafka.go
//: details: TODO
//: author:  Mehrdad Arshad Rad
//: date:    02/01/2017
//:
//: 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 producer

import (
	"encoding/json"
	"io/ioutil"
	"log"

	"github.com/bitly/go-nsq"
)

// NSQ represents nsq producer
type NSQ struct {
	producer *nsq.Producer
	config   NSQConfig
	logger   *log.Logger
}

type NSQConfig struct {
	Broker string `json:"broker"`
}

func (n *NSQ) setup(configFile string, logger *log.Logger) error {
	n.producer, _ = nsq.NewProducer("127.0.0.1:4150", nil)
	// TODO

	return nil
}

func (n *NSQ) inputMsg(topic string, mCh chan string) {
	// TODO
}

func (n *NSQ) load(f string) error {
	b, err := ioutil.ReadFile(f)
	if err != nil {
		return err
	}

	err = json.Unmarshal(b, &n.config)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package profile_test

import (
	"os"

	"github.com/pkg/profile"
)

func ExampleStart() {
	// start a simple CPU profile and register
	// a defer to Stop (flush) the profiling data.
	defer profile.Start().Stop()
}

func ExampleCPUProfile() {
	// CPU profiling is the default profiling mode, but you can specify it
	// explicitly for completeness.
	defer profile.Start(profile.CPUProfile).Stop()
}

func ExampleMemProfile() {
	// use memory profiling, rather than the default cpu profiling.
	defer profile.Start(profile.MemProfile).Stop()
}

func ExampleMemProfileRate() {
	// use memory profiling with custom rate and set output folder to current one.
	defer profile.Start(profile.MemProfileRate(2048), profile.ProfilePath(".")).Stop()
}

func ExampleProfilePath() {
	// set the location that the profile will be written to
	defer profile.Start(profile.ProfilePath(os.Getenv("HOME")))
}

func ExampleNoShutdownHook() {
	// disable the automatic shutdown hook.
	defer profile.Start(profile.NoShutdownHook).Stop()
}
<commit_msg>Rephrased comment<commit_after>package profile_test

import (
	"os"

	"github.com/pkg/profile"
)

func ExampleStart() {
	// start a simple CPU profile and register
	// a defer to Stop (flush) the profiling data.
	defer profile.Start().Stop()
}

func ExampleCPUProfile() {
	// CPU profiling is the default profiling mode, but you can specify it
	// explicitly for completeness.
	defer profile.Start(profile.CPUProfile).Stop()
}

func ExampleMemProfile() {
	// use memory profiling, rather than the default cpu profiling.
	defer profile.Start(profile.MemProfile).Stop()
}

func ExampleMemProfileRate() {
	// use memory profiling with custom rate and output to current directory.
	defer profile.Start(profile.MemProfileRate(2048), profile.ProfilePath(".")).Stop()
}

func ExampleProfilePath() {
	// set the location that the profile will be written to
	defer profile.Start(profile.ProfilePath(os.Getenv("HOME")))
}

func ExampleNoShutdownHook() {
	// disable the automatic shutdown hook.
	defer profile.Start(profile.NoShutdownHook).Stop()
}
<|endoftext|>


<commit_before>package main

import (
  "fmt"
	"syscall"
	"git.apache.org/thrift.git/lib/go/thrift"
	"./lib/AgentVsAgent"
	"errors"
)

type passCardFn func(Round) []*AgentVsAgent.Card
type playCardFn func(Trick) *AgentVsAgent.Card

type options struct {
	ticket *AgentVsAgent.Ticket
	client *AgentVsAgent.HeartsClient
	doPassCards *passCardFn
	doPlayCard *playCardFn
}

type Trick struct {
	number int
	round *Round
	leader string
	played []*AgentVsAgent.Card
}

func (trick *Trick) run(opts *options) (err error) {
	trick.log("Starting trick")
	currentTrick, ex, err := opts.client.GetTrick(opts.ticket)
	if err != nil { return err }
	if ex != nil { return errors.New((*ex).String()) }
	trick.leader = string(currentTrick.Leader)
	trick.played = currentTrick.Played

	cardToPlay := (*opts.doPlayCard)(*trick)

	var remainingCards []*AgentVsAgent.Card
	for _, heldCard := range trick.round.held {
		if !(heldCard.Suit == cardToPlay.Suit && heldCard.Rank == cardToPlay.Rank) {
			remainingCards = append(remainingCards, heldCard)
		}
	}
	trick.round.held = remainingCards

	trickResult, ex, err := opts.client.PlayCard(opts.ticket, cardToPlay)
	if err != nil { return err }
	if ex != nil { return errors.New((*ex).String()) }

	trick.log("trick: result", trickResult)
	trick.played = trickResult.Played
	return
}

func (trick *Trick) log(message ...interface{}) {
	newMessage := append([]interface{}{"T:", trick.number}, message...)
	trick.round.log(newMessage...)
}

type Round struct {
	number int
	tricks []*Trick
	dealt []*AgentVsAgent.Card
	held []*AgentVsAgent.Card
	game *Game
}

func (round *Round) createTrick() Trick {
	trick := Trick{number: len(round.tricks) + 1, round: round}
	round.tricks = append(round.tricks, &trick)
	return trick
}

func (round *Round) run(opts *options) (err error) {
	hand, ex, err := opts.client.GetHand(opts.ticket)
	if err != nil { return err }
	if ex != nil { return errors.New((*ex).String()) }
	round.log("You were dealt:", hand)
	round.dealt = hand
	round.held = hand

	err = round.passCards(opts)
	if err != nil { return err }
	return round.playTrick(opts)
}

func (round *Round) passCards(opts *options) (err error) {
	if round.number % 4 == 0 {
		round.log("Not passing cards")
	} else {
		round.log("About to pass cards")
		cardsToPass := (*opts.doPassCards)(*round)

		var newHeld []*AgentVsAgent.Card
		for _, heldCard := range round.held {
			toRemove := false

			for _, cardToPass := range cardsToPass {
				if cardToPass == heldCard {
					toRemove = true
				}
			}

			if !toRemove {
				newHeld = append(newHeld, heldCard)
			}
		}

		receivedCards, ex, err := opts.client.PassCards(opts.ticket, cardsToPass)
		if err != nil { return err }
		if ex != nil { return errors.New((*ex).String()) }
		round.log("Received cards:", receivedCards)
		round.held = append(newHeld, receivedCards...)
	}
	return err
}

func (round *Round) playTrick(opts *options) (err error) {
	trick := round.createTrick()
	err = trick.run(opts)
	if err != nil { return err }

	if len(round.tricks) < 13 {
		err = round.playTrick(opts)
	}
	return err
}

func (round *Round) log(message ...interface{}) {
	newMessage := append([]interface{}{"R:", round.number}, message...)
	round.game.log(newMessage...)
}

type Game struct {
	rounds []*Round
	info *AgentVsAgent.GameInfo
}

func (game *Game) createRound() *Round {
	round := Round{number: len(game.rounds) + 1, game: game}
	game.rounds = append(game.rounds, &round)
	return &round
}

func (game *Game) run(opts *options) (err error) {
	game.log("Starting game")

	round := game.createRound()

	err = round.run(opts)
	if err != nil { return err }

	roundResult, ex, err := opts.client.GetRoundResult(opts.ticket)
	if err != nil { return err }
	if ex != nil { return errors.New((*ex).String()) }

	game.log("round result:", roundResult)
	if roundResult.Status == AgentVsAgent.GameStatus_NEXT_ROUND {
		err = game.run(opts)
	}
	// get round result
	//if status not next round
	return err
}

func (game Game) log(message ...interface{}) {
	newMessage := append([]interface{}{"P:", game.info.Position}, message...)
	fmt.Println(newMessage...)
}

func play(doPassCards passCardFn, doPlayCard playCardFn) {
	host, hostFound := syscall.Getenv("AVA_HOST")
	port, portFound := syscall.Getenv("AVA_PORT")
	if !hostFound { host = "localhost" }
	if !portFound { port = "4001" }
	var addr string = host + ":" + port

	var transportFactory thrift.TTransportFactory
	var protocolFactory thrift.TProtocolFactory
	protocolFactory = thrift.NewTBinaryProtocolFactoryDefault()
	transportFactory = thrift.NewTTransportFactory()
	transportFactory = thrift.NewTFramedTransportFactory(transportFactory)

	var transport thrift.TTransport
	transport, err := thrift.NewTSocket(addr)
	if err != nil {
		fmt.Println("Error opening socket:", err)
		return
	}
	transport = transportFactory.GetTransport(transport)
	defer transport.Close()
	if err := transport.Open(); err != nil {
		fmt.Println("Error opening transport:", err)
		return
	}

	client := AgentVsAgent.NewHeartsClientFactory(transport, protocolFactory)

	request := AgentVsAgent.NewEntryRequest()
	fmt.Println("Entering arena", request)
	response, err := client.EnterArena(request)
	if err != nil {
		fmt.Println("Error", err)
		return
	}
	ticket := response.Ticket
	if ticket != nil {
		fmt.Println("playing")
		gameInfo, _, _ := client.GetGameInfo(ticket)
		fmt.Println("game info:", gameInfo)

		game := Game{info: gameInfo}
		err = game.run(&options{ticket: ticket, client: client, doPassCards: &doPassCards, doPlayCard: &doPlayCard})
		if err != nil {
			fmt.Println("ERROR:", err)
			return
		}
		fmt.Println("Game is over")
		gameResult, _, _ := client.GetGameResult(ticket)
		fmt.Println("game result:", gameResult)
	} else {
		fmt.Println("No ticket")
		return
	}
}
<commit_msg>another pointer issue in the go agent<commit_after>package main

import (
  "fmt"
	"syscall"
	"git.apache.org/thrift.git/lib/go/thrift"
	"./lib/AgentVsAgent"
	"errors"
)

type passCardFn func(Round) []*AgentVsAgent.Card
type playCardFn func(Trick) *AgentVsAgent.Card

type options struct {
	ticket *AgentVsAgent.Ticket
	client *AgentVsAgent.HeartsClient
	doPassCards *passCardFn
	doPlayCard *playCardFn
}

type Trick struct {
	number int
	round *Round
	leader string
	played []*AgentVsAgent.Card
}

func (trick *Trick) run(opts *options) (err error) {
	trick.log("Starting trick")
	currentTrick, ex, err := opts.client.GetTrick(opts.ticket)
	if err != nil { return err }
	if ex != nil { return errors.New((*ex).String()) }
	trick.leader = string(currentTrick.Leader)
	trick.played = currentTrick.Played

	cardToPlay := (*opts.doPlayCard)(*trick)

	var remainingCards []*AgentVsAgent.Card
	for _, heldCard := range trick.round.held {
		if !(heldCard.Suit == cardToPlay.Suit && heldCard.Rank == cardToPlay.Rank) {
			remainingCards = append(remainingCards, heldCard)
		}
	}
	trick.round.held = remainingCards

	trickResult, ex, err := opts.client.PlayCard(opts.ticket, cardToPlay)
	if err != nil { return err }
	if ex != nil { return errors.New((*ex).String()) }

	trick.log("trick: result", trickResult)
	trick.played = trickResult.Played
	return
}

func (trick *Trick) log(message ...interface{}) {
	newMessage := append([]interface{}{"T:", trick.number}, message...)
	trick.round.log(newMessage...)
}

type Round struct {
	number int
	tricks []*Trick
	dealt []*AgentVsAgent.Card
	held []*AgentVsAgent.Card
	game *Game
}

func (round *Round) createTrick() *Trick {
	trick := Trick{number: len(round.tricks) + 1, round: round}
	round.tricks = append(round.tricks, &trick)
	return &trick
}

func (round *Round) run(opts *options) (err error) {
	hand, ex, err := opts.client.GetHand(opts.ticket)
	if err != nil { return err }
	if ex != nil { return errors.New((*ex).String()) }
	round.log("You were dealt:", hand)
	round.dealt = hand
	round.held = hand

	err = round.passCards(opts)
	if err != nil { return err }
	return round.playTrick(opts)
}

func (round *Round) passCards(opts *options) (err error) {
	if round.number % 4 == 0 {
		round.log("Not passing cards")
	} else {
		round.log("About to pass cards")
		cardsToPass := (*opts.doPassCards)(*round)

		var newHeld []*AgentVsAgent.Card
		for _, heldCard := range round.held {
			toRemove := false

			for _, cardToPass := range cardsToPass {
				if cardToPass == heldCard {
					toRemove = true
				}
			}

			if !toRemove {
				newHeld = append(newHeld, heldCard)
			}
		}

		receivedCards, ex, err := opts.client.PassCards(opts.ticket, cardsToPass)
		if err != nil { return err }
		if ex != nil { return errors.New((*ex).String()) }
		round.log("Received cards:", receivedCards)
		round.held = append(newHeld, receivedCards...)
	}
	return err
}

func (round *Round) playTrick(opts *options) (err error) {
	trick := round.createTrick()
	err = trick.run(opts)
	if err != nil { return err }

	if len(round.tricks) < 13 {
		err = round.playTrick(opts)
	}
	return err
}

func (round *Round) log(message ...interface{}) {
	newMessage := append([]interface{}{"R:", round.number}, message...)
	round.game.log(newMessage...)
}

type Game struct {
	rounds []*Round
	info *AgentVsAgent.GameInfo
}

func (game *Game) createRound() *Round {
	round := Round{number: len(game.rounds) + 1, game: game}
	game.rounds = append(game.rounds, &round)
	return &round
}

func (game *Game) run(opts *options) (err error) {
	game.log("Starting game")

	round := game.createRound()

	err = round.run(opts)
	if err != nil { return err }

	roundResult, ex, err := opts.client.GetRoundResult(opts.ticket)
	if err != nil { return err }
	if ex != nil { return errors.New((*ex).String()) }

	game.log("round result:", roundResult)
	if roundResult.Status == AgentVsAgent.GameStatus_NEXT_ROUND {
		err = game.run(opts)
	}
	// get round result
	//if status not next round
	return err
}

func (game Game) log(message ...interface{}) {
	newMessage := append([]interface{}{"P:", game.info.Position}, message...)
	fmt.Println(newMessage...)
}

func play(doPassCards passCardFn, doPlayCard playCardFn) {
	host, hostFound := syscall.Getenv("AVA_HOST")
	port, portFound := syscall.Getenv("AVA_PORT")
	if !hostFound { host = "localhost" }
	if !portFound { port = "4001" }
	var addr string = host + ":" + port

	var transportFactory thrift.TTransportFactory
	var protocolFactory thrift.TProtocolFactory
	protocolFactory = thrift.NewTBinaryProtocolFactoryDefault()
	transportFactory = thrift.NewTTransportFactory()
	transportFactory = thrift.NewTFramedTransportFactory(transportFactory)

	var transport thrift.TTransport
	transport, err := thrift.NewTSocket(addr)
	if err != nil {
		fmt.Println("Error opening socket:", err)
		return
	}
	transport = transportFactory.GetTransport(transport)
	defer transport.Close()
	if err := transport.Open(); err != nil {
		fmt.Println("Error opening transport:", err)
		return
	}

	client := AgentVsAgent.NewHeartsClientFactory(transport, protocolFactory)

	request := AgentVsAgent.NewEntryRequest()
	fmt.Println("Entering arena", request)
	response, err := client.EnterArena(request)
	if err != nil {
		fmt.Println("Error", err)
		return
	}
	ticket := response.Ticket
	if ticket != nil {
		fmt.Println("playing")
		gameInfo, _, _ := client.GetGameInfo(ticket)
		fmt.Println("game info:", gameInfo)

		game := Game{info: gameInfo}
		err = game.run(&options{ticket: ticket, client: client, doPassCards: &doPassCards, doPlayCard: &doPlayCard})
		if err != nil {
			fmt.Println("ERROR:", err)
			return
		}
		fmt.Println("Game is over")
		gameResult, _, _ := client.GetGameResult(ticket)
		fmt.Println("game result:", gameResult)
	} else {
		fmt.Println("No ticket")
		return
	}
}
<|endoftext|>


<commit_before>// Copyright 2013 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main

/*
dd is modeled after dd. Each step in the chain is a goroutine that
reads a block and writes a block.
There are two always-the goroutines, in and out. They're actually
the same thing save they have, maybe, different block sizes.
*/
import (
	"flag"
	"fmt"
	"io"
	"math"
	"os"
	"strings"
)

type passer func(r io.Reader, w io.Writer, ibs, obs int)

var (
	ibs     = flag.Int("ibs", 1, "Default input block size")
	obs     = flag.Int("obs", 1, "Default output block size")
	skip    = flag.Int64("skip", 0, "skip n bytes before reading")
	seek    = flag.Int64("seek", 0, "seek output when writing")
	count   = flag.Int64("count", math.MaxInt64, "Max output of data to copy")
	inName  = flag.String("if", "", "Input file")
	outName = flag.String("of", "", "Output file")
)

// The 'close' thing is a real hack, but needed for proper
// operation in single-process mode.
func pass(r io.Reader, w io.WriteCloser, ibs, obs int, close bool) {
	b := make([]byte, ibs)
	defer func() {
		if close {
			w.Close()
		}
	}()
	for {
		bs := 0
		for bs < ibs {
			n, err := r.Read(b[bs:])
			if err != nil && err != io.EOF {
				return
			}
			if n == 0 {
				break
			}
			bs += n
		}
		if bs == 0 {
			return
		}
		tot := 0
		for tot < bs {
			nn, err := w.Write(b[tot : tot+obs])
			if err != nil {
				fmt.Fprintf(os.Stderr, "pass: %v\n", err)
				return
			}
			if nn == 0 {
				return
			}
			tot += nn
		}
	}
}

func fatal(err error) {
	fmt.Fprintf(os.Stderr, "%v", err)
	os.Exit(1)
}

// rather than, in essence, recreating all the apparatus of flag.xxxx with the if= bits,
// including dup checking, conversion, etc. we just convert the arguments and then
// run flag.Parse. Gross, but hey, it works.
func main() {
	inFile := os.Stdin
	outFile := os.Stdout
	var err error
	// EVERYTHING in dd follows x=y. So blindly split and convert and sleep well.
	arg := []string{}
	for _, v := range os.Args {
		l := strings.SplitN(v, "=", 2)
		// We only fix the exact case for x=y.
		if len(l) == 2 {
			l[0] = "-" + l[0]
			arg = append(arg, l...)
		} else {
			arg = append(arg, l...)
		}
	}
	os.Args = arg
	flag.Parse()
	if *inName != "" {
		inFile, err = os.Open(*inName)
		if err != nil {
			fatal(err)
		}
	}
	if *outName != "" {
		outFile, err = os.OpenFile(*outName, os.O_CREATE|os.O_WRONLY, 0644)
		if err != nil {
			fatal(err)
		}
	}

	r, w := io.Pipe()
	// position things.
	if *skip > 0 {
		if _, err = inFile.Seek(*skip, 0); err != nil {
			fatal(err)
		}
	}
	if *seek > 0 {
		if _, err = outFile.Seek(*seek, 0); err != nil {
			fatal(err)
		}
	}
	go pass(inFile, w, *ibs, *ibs, true)
	// push other filters here as needed.
	pass(r, outFile, *obs, *obs, false)
}
<commit_msg>Split main(); conv=lcase,ucase; bs<commit_after>// Copyright 2013 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main

/*
dd is modeled after dd. Each step in the chain is a goroutine that
reads a block and writes a block.
There are two always-the goroutines, in and out. They're actually
the same thing save they have, maybe, different block sizes.
*/
import (
	"flag"
	"fmt"
	"io"
	"math"
	"os"
	"strings"
)

type passer func(r io.Reader, w io.Writer, ibs, obs int, conv string)

var (
	ibs     = flag.Int("ibs", 1, "Default input block size")
	obs     = flag.Int("obs", 1, "Default output block size")
	bs      = flag.Int("bs", 0, "Default input and output block size")
	skip    = flag.Int64("skip", 0, "skip n bytes before reading")
	seek    = flag.Int64("seek", 0, "seek output when writing")
	conv    = flag.String("conv", "", "Convert the file on a specific way, like notrunc")
	count   = flag.Int64("count", math.MaxInt64, "Max output of data to copy")
	inName  = flag.String("if", "", "Input file")
	outName = flag.String("of", "", "Output file")
)

// The 'close' thing is a real hack, but needed for proper
// operation in single-process mode.
func pass(r io.Reader, w io.WriteCloser, ibs, obs int, conv string, close bool) {
	var err error
	var nn int
	b := make([]byte, ibs)
	defer func() {
		if close {
			w.Close()
		}
	}()
	for {
		bsc := 0
		for bsc < ibs {
			n, err := r.Read(b[bsc:])
			if err != nil && err != io.EOF {
				return
			}
			if n == 0 {
				break
			}
			bsc += n
		}
		if bsc == 0 {
			return
		}
		for tot := 0; tot < bsc; tot += nn {
			switch conv {
			case "ucase":
				nn, err = w.Write([]byte(strings.ToUpper(string(b[tot : tot+obs]))))
			case "lcase":
				nn, err = w.Write([]byte(strings.ToLower(string(b[tot : tot+obs]))))
			default:
				nn, err = w.Write(b[tot : tot+obs])
			}

			if err != nil {
				fmt.Fprintf(os.Stderr, "pass: %v\n", err)
				return
			}
			if nn == 0 {
				return
			}
		}
	}
}

func fatal(err error) {
	fmt.Fprintf(os.Stderr, "%v", err)
	os.Exit(1)
}

func SplitArgs() []string {
	// EVERYTHING in dd follows x=y. So blindly split and convert sleep well
	arg := []string{}
	for _, v := range os.Args {
		l := strings.SplitN(v, "=", 2)
		// We only fix the exact case for x=y.
		if len(l) == 2 {
			l[0] = "-" + l[0]
			arg = append(arg, l...)
		} else {
			arg = append(arg, l...)
		}
	}
	return arg
}

func OpenFiles() (os.File, os.File) {
	inFile := os.Stdin
	outFile := os.Stdout
	var err error

	if *inName != "" {
		inFile, err = os.Open(*inName)
		if err != nil {
			fatal(err)
		}
	}
	if *outName != "" {
		outFile, err = os.OpenFile(*outName, os.O_CREATE|os.O_WRONLY, 0644)
		if err != nil {
			fatal(err)
		}
	}

	// position things.
	if *skip > 0 {
		if _, err = inFile.Seek(*skip, 0); err != nil {
			fatal(err)
		}
	}
	if *seek > 0 {
		if _, err = outFile.Seek(*seek, 0); err != nil {
			fatal(err)
		}
	}
	// bs = both 'ibs' and 'obs' (IEEE Std 1003.1 - 2013)
	if *bs > 0 {
		*ibs = *bs
		*obs = *bs
	}

	return *inFile, *outFile
}

func InOut(inFile, outFile *os.File) {
	r, w := io.Pipe()
	go pass(inFile, w, *ibs, *ibs, *conv, true)
	// push other filters here as needed.
	pass(r, outFile, *obs, *obs, *conv, false)
}

// rather than, in essence, recreating all the apparatus of flag.xxxx with the if= bits,
// including dup checking, conversion, etc. we just convert the arguments and then
// run flag.Parse. Gross, but hey, it works.
func main() {
	os.Args = SplitArgs()
	flag.Parse()
	inFile, outFile := OpenFiles()
	InOut(&inFile, &outFile)
}
<|endoftext|>


<commit_before>package testflight_test

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/ginkgomon"

	"github.com/concourse/atc/postgresrunner"
	"github.com/concourse/testflight/gitserver"
	"github.com/concourse/testflight/guidserver"
)

var _ = Describe("A job with a git resource", func() {
	var postgresRunner postgresrunner.Runner
	var dbProcess ifrit.Process

	var atcConfigFilePath string

	var atcProcess ifrit.Process

	BeforeEach(func() {
		var err error

		postgresRunner = postgresrunner.Runner{
			Port: 5433 + GinkgoParallelNode(),
		}

		dbProcess = ifrit.Envoke(postgresRunner)
		postgresRunner.CreateTestDB()

		guidserver.Start(helperRootfs, wardenClient)
		gitserver.Start(helperRootfs, wardenClient)

		gitserver.Commit()

		atcConfigFile, err := ioutil.TempFile("", "atc-config")
		Ω(err).ShouldNot(HaveOccurred())

		atcConfigFilePath = atcConfigFile.Name()

		_, err = fmt.Fprintf(atcConfigFile, `---
resources:
  - name: some-git-resource
    type: git
    source:
      uri: %[1]s

  - name: some-git-resource-success
    type: git
    source:
      uri: %[1]s
      branch: success

  - name: some-git-resource-failure
    type: git
    source:
      uri: %[1]s
      branch: failure

jobs:
  - name: some-job
    inputs:
      - resource: some-git-resource
    outputs:
      - resource: some-git-resource-success
        params:
          repository: some-git-resource
    config:
      image: %[2]s
      run:
        path: bash
        args: ["-c", "tail -1 some-git-resource/guids | %[3]s"]

  - name: some-failing-job
    inputs:
      - resource: some-git-resource
    outputs:
      - resource: some-git-resource-failure
        params:
          repository: some-git-resource
    config:
      image: %[2]s
      run:
        path: bash
        args: ["-c", "exit 1"]
`, gitserver.URI(), helperRootfs, guidserver.CurlCommand())
		Ω(err).ShouldNot(HaveOccurred())

		err = atcConfigFile.Close()
		Ω(err).ShouldNot(HaveOccurred())

		atcProcess = ifrit.Envoke(&ginkgomon.Runner{
			Name:          "atc",
			AnsiColorCode: "34m",
			Command: exec.Command(
				builtComponents["atc"],
				"-peerAddr", externalAddr+":8081",
				"-config", atcConfigFilePath,
				"-templates", filepath.Join(atcDir, "server", "templates"),
				"-public", filepath.Join(atcDir, "server", "public"),
				"-sqlDataSource", postgresRunner.DataSourceName(),
				"-checkInterval", "5s",
			),
			StartCheck:        "listening",
			StartCheckTimeout: 5 * time.Second,
		})

		Consistently(atcProcess.Wait(), 1*time.Second).ShouldNot(Receive())
	})

	AfterEach(func() {
		atcProcess.Signal(syscall.SIGINT)
		Eventually(atcProcess.Wait(), 10*time.Second).Should(Receive())

		gitserver.Stop(wardenClient)
		guidserver.Stop(wardenClient)

		postgresRunner.DropTestDB()

		dbProcess.Signal(os.Interrupt)
		Eventually(dbProcess.Wait(), 10*time.Second).Should(Receive())

		err := os.Remove(atcConfigFilePath)
		Ω(err).ShouldNot(HaveOccurred())
	})

	It("builds a repo's initial and later commits", func() {
		Eventually(guidserver.ReportingGuids, 5*time.Minute, 10*time.Second).Should(HaveLen(1))
		Ω(guidserver.ReportingGuids()).Should(Equal(gitserver.CommittedGuids()))

		gitserver.Commit()

		Eventually(guidserver.ReportingGuids, 2*time.Minute, 10*time.Second).Should(HaveLen(2))
		Ω(guidserver.ReportingGuids()).Should(Equal(gitserver.CommittedGuids()))
	})

	It("performs outputs only if the build succeeds", func() {
		masterSHA := gitserver.RevParse("master")
		Ω(masterSHA).ShouldNot(BeEmpty())

		// synchronize on the build triggering
		Eventually(guidserver.ReportingGuids, 5*time.Minute, 10*time.Second).Should(HaveLen(1))

		// should have eventually promoted
		Eventually(func() string {
			return gitserver.RevParse("success")
		}, 10*time.Second, 1*time.Second).Should(Equal(masterSHA))

		// should *not* have promoted to failing branch
		Consistently(func() string {
			return gitserver.RevParse("failure")
		}, 10*time.Second, 1*time.Second).Should(BeEmpty())
	})
})
<commit_msg>cover on: [failure]<commit_after>package testflight_test

import (
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"
	"time"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/tedsuo/ifrit"
	"github.com/tedsuo/ifrit/ginkgomon"

	"github.com/concourse/atc/postgresrunner"
	"github.com/concourse/testflight/gitserver"
	"github.com/concourse/testflight/guidserver"
)

var _ = Describe("A job with a git resource", func() {
	var postgresRunner postgresrunner.Runner
	var dbProcess ifrit.Process

	var atcConfigFilePath string

	var atcProcess ifrit.Process

	BeforeEach(func() {
		var err error

		postgresRunner = postgresrunner.Runner{
			Port: 5433 + GinkgoParallelNode(),
		}

		dbProcess = ifrit.Envoke(postgresRunner)
		postgresRunner.CreateTestDB()

		guidserver.Start(helperRootfs, wardenClient)
		gitserver.Start(helperRootfs, wardenClient)

		gitserver.Commit()

		atcConfigFile, err := ioutil.TempFile("", "atc-config")
		Ω(err).ShouldNot(HaveOccurred())

		atcConfigFilePath = atcConfigFile.Name()

		_, err = fmt.Fprintf(atcConfigFile, `---
resources:
  - name: some-git-resource
    type: git
    source:
      uri: %[1]s

  - name: some-git-resource-success
    type: git
    source:
      uri: %[1]s
      branch: success

  - name: some-git-resource-no-update
    type: git
    source:
      uri: %[1]s
      branch: no-update

  - name: some-git-resource-failure
    type: git
    source:
      uri: %[1]s
      branch: failure

jobs:
  - name: some-job
    inputs:
      - resource: some-git-resource
    outputs:
      - resource: some-git-resource-success
        params:
          repository: some-git-resource
    config:
      image: %[2]s
      run:
        path: bash
        args: ["-c", "tail -1 some-git-resource/guids | %[3]s"]

  - name: some-failing-job
    inputs:
      - resource: some-git-resource
    outputs:
      - resource: some-git-resource-no-update
        params:
          repository: some-git-resource
      - resource: some-git-resource-failure
        on: [failure]
        params:
          repository: some-git-resource
    config:
      image: %[2]s
      run:
        path: bash
        args: ["-c", "exit 1"]
`, gitserver.URI(), helperRootfs, guidserver.CurlCommand())
		Ω(err).ShouldNot(HaveOccurred())

		err = atcConfigFile.Close()
		Ω(err).ShouldNot(HaveOccurred())

		atcProcess = ifrit.Envoke(&ginkgomon.Runner{
			Name:          "atc",
			AnsiColorCode: "34m",
			Command: exec.Command(
				builtComponents["atc"],
				"-peerAddr", externalAddr+":8081",
				"-config", atcConfigFilePath,
				"-templates", filepath.Join(atcDir, "server", "templates"),
				"-public", filepath.Join(atcDir, "server", "public"),
				"-sqlDataSource", postgresRunner.DataSourceName(),
				"-checkInterval", "5s",
			),
			StartCheck:        "listening",
			StartCheckTimeout: 5 * time.Second,
		})

		Consistently(atcProcess.Wait(), 1*time.Second).ShouldNot(Receive())
	})

	AfterEach(func() {
		atcProcess.Signal(syscall.SIGINT)
		Eventually(atcProcess.Wait(), 10*time.Second).Should(Receive())

		gitserver.Stop(wardenClient)
		guidserver.Stop(wardenClient)

		postgresRunner.DropTestDB()

		dbProcess.Signal(os.Interrupt)
		Eventually(dbProcess.Wait(), 10*time.Second).Should(Receive())

		err := os.Remove(atcConfigFilePath)
		Ω(err).ShouldNot(HaveOccurred())
	})

	It("builds a repo's initial and later commits", func() {
		Eventually(guidserver.ReportingGuids, 5*time.Minute, 10*time.Second).Should(HaveLen(1))
		Ω(guidserver.ReportingGuids()).Should(Equal(gitserver.CommittedGuids()))

		gitserver.Commit()

		Eventually(guidserver.ReportingGuids, 2*time.Minute, 10*time.Second).Should(HaveLen(2))
		Ω(guidserver.ReportingGuids()).Should(Equal(gitserver.CommittedGuids()))
	})

	It("performs outputs only if the build succeeds", func() {
		masterSHA := gitserver.RevParse("master")
		Ω(masterSHA).ShouldNot(BeEmpty())

		// synchronize on the build triggering
		Eventually(guidserver.ReportingGuids, 5*time.Minute, 10*time.Second).Should(HaveLen(1))

		// should have eventually promoted
		Eventually(func() string {
			return gitserver.RevParse("success")
		}, 10*time.Second, 1*time.Second).Should(Equal(masterSHA))

		// should have promoted to failure branch because of on: [falure]
		Eventually(func() string {
			return gitserver.RevParse("failure")
		}, 10*time.Second, 1*time.Second).Should(BeEmpty())

		// should *not* have promoted to no-update branch
		Consistently(func() string {
			return gitserver.RevParse("no-update")
		}, 10*time.Second, 1*time.Second).Should(BeEmpty())
	})
})
<|endoftext|>