<commit_before>package volumecontroller

import (
	"os"
	"testing"
	"time"

	apis "github.com/openebs/maya/pkg/apis/openebs.io/v1alpha1"
	openebsFakeClientset "github.com/openebs/maya/pkg/client/clientset/versioned/fake"
	informers "github.com/openebs/maya/pkg/client/informers/externalversions"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	kubeinformers "k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes/fake"
)

// TestGetVolumeResource checks if volume resource created is successfully got.
func TestGetVolumeResource(t *testing.T) {
	fakeKubeClient := fake.NewSimpleClientset()
	fakeOpenebsClient := openebsFakeClientset.NewSimpleClientset()

	kubeInformerFactory := kubeinformers.NewSharedInformerFactory(fakeKubeClient, time.Second*30)
	openebsInformerFactory := informers.NewSharedInformerFactory(fakeOpenebsClient, time.Second*30)

	// Instantiate the cStor Volume controllers.
	volumeController := NewCStorVolumeController(fakeKubeClient, fakeOpenebsClient, kubeInformerFactory,
		openebsInformerFactory)

	testVolumeResource := map[string]struct {
		expectedVolumeName string
		test               *apis.CStorVolume
	}{
		"img1VolumeResource": {
			expectedVolumeName: "abc",
			test: &apis.CStorVolume{
				TypeMeta: metav1.TypeMeta{},
				ObjectMeta: metav1.ObjectMeta{
					Name: "volume1",
					UID:  types.UID("abc"),
				},
				Spec: apis.CStorVolumeSpec{
					TargetIP: "0.0.0.0",
					Capacity: "5G",
					Status:   "init",
				},
				Status: apis.CStorVolumeStatus{},
			},
		},
		"img2VolumeResource": {
			expectedVolumeName: "abcd",
			test: &apis.CStorVolume{
				TypeMeta: metav1.TypeMeta{},
				ObjectMeta: metav1.ObjectMeta{
					Name: "volume2",
					UID:  types.UID("abcd"),
				},
				Spec: apis.CStorVolumeSpec{
					TargetIP: "0.0.0.0",
					Capacity: "15G",
					Status:   "init",
				},
				Status: apis.CStorVolumeStatus{},
			},
		},
	}
	for desc, ut := range testVolumeResource {
		// Create Volume resource
		_, err := volumeController.clientset.OpenebsV1alpha1().CStorVolumes("default").Create(ut.test)
		if err != nil {
			t.Fatalf("Desc:%v, Unable to create resource : %v", desc, ut.test.ObjectMeta.Name)
		}
		// Get the created volume resource using name
		cStorVolumeObtained, err := volumeController.getVolumeResource(ut.test.ObjectMeta.Name)
		if string(cStorVolumeObtained.ObjectMeta.UID) != ut.expectedVolumeName {
			t.Fatalf("Desc:%v, VolumeName mismatch, Expected:%v, Got:%v", desc, ut.expectedVolumeName,
				string(cStorVolumeObtained.ObjectMeta.UID))
		}
	}
}

// TestIsValidCStorVolumeMgmt is to check if right sidecar does operation with env match.
func TestIsValidCStorVolumeMgmt(t *testing.T) {
	testVolumeResource := map[string]struct {
		expectedOutput bool
		test           *apis.CStorVolume
	}{
		"img2VolumeResource": {
			expectedOutput: true,
			test: &apis.CStorVolume{
				TypeMeta: metav1.TypeMeta{},
				ObjectMeta: metav1.ObjectMeta{
					Name:       "volume2",
					UID:        types.UID("abcd"),
					Finalizers: []string{"cstorvolume.openebs.io/finalizer"},
				},
				Spec: apis.CStorVolumeSpec{
					TargetIP: "0.0.0.0",
					Capacity: "15G",
					Status:   "init",
				},
				Status: apis.CStorVolumeStatus{},
			},
		},
	}
	for desc, ut := range testVolumeResource {
		os.Setenv("OPENEBS_IO_CSTOR_VOLUME_ID", string(ut.test.UID))
		obtainedOutput := IsValidCStorVolumeMgmt(ut.test)
		if obtainedOutput != ut.expectedOutput {
			t.Fatalf("Desc:%v, Expected:%v, Got:%v", desc, ut.expectedOutput,
				obtainedOutput)
		}
		os.Setenv("OPENEBS_IO_CSTOR_VOLUME_ID", "")
	}
}

// TestIsValidCStorVolumeMgmtNegative is to check if right sidecar does operation with env match.
func TestIsValidCStorVolumeMgmtNegative(t *testing.T) {
	testVolumeResource := map[string]struct {
		expectedOutput bool
		test           *apis.CStorVolume
	}{
		"img2VolumeResource": {
			expectedOutput: false,
			test: &apis.CStorVolume{
				TypeMeta: metav1.TypeMeta{},
				ObjectMeta: metav1.ObjectMeta{
					Name:       "volume2",
					UID:        types.UID("abcd"),
					Finalizers: []string{"cstorvolume.openebs.io/finalizer"},
				},
				Spec: apis.CStorVolumeSpec{
					TargetIP: "0.0.0.0",
					Capacity: "15G",
					Status:   "init",
				},
				Status: apis.CStorVolumeStatus{},
			},
		},
	}
	for desc, ut := range testVolumeResource {
		os.Setenv("OPENEBS_IO_CSTOR_VOLUME_ID", string("awer"))
		obtainedOutput := IsValidCStorVolumeMgmt(ut.test)
		if obtainedOutput != ut.expectedOutput {
			t.Fatalf("Desc:%v, Expected:%v, Got:%v", desc, ut.expectedOutput,
				obtainedOutput)
		}
		os.Setenv("OPENEBS_IO_CSTOR_VOLUME_ID", "")
	}
}
<commit_msg>using openebs namespace in tests (#402)<commit_after>package volumecontroller

import (
	"os"
	"testing"
	"time"

	"github.com/openebs/maya/cmd/cstor-volume-mgmt/controller/common"
	apis "github.com/openebs/maya/pkg/apis/openebs.io/v1alpha1"
	openebsFakeClientset "github.com/openebs/maya/pkg/client/clientset/versioned/fake"
	informers "github.com/openebs/maya/pkg/client/informers/externalversions"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	kubeinformers "k8s.io/client-go/informers"
	"k8s.io/client-go/kubernetes/fake"
)

// TestGetVolumeResource checks if volume resource created is successfully got.
func TestGetVolumeResource(t *testing.T) {
	fakeKubeClient := fake.NewSimpleClientset()
	fakeOpenebsClient := openebsFakeClientset.NewSimpleClientset()

	kubeInformerFactory := kubeinformers.NewSharedInformerFactory(fakeKubeClient, time.Second*30)
	openebsInformerFactory := informers.NewSharedInformerFactory(fakeOpenebsClient, time.Second*30)

	// Instantiate the cStor Volume controllers.
	volumeController := NewCStorVolumeController(fakeKubeClient, fakeOpenebsClient, kubeInformerFactory,
		openebsInformerFactory)

	testVolumeResource := map[string]struct {
		expectedVolumeName string
		test               *apis.CStorVolume
	}{
		"img1VolumeResource": {
			expectedVolumeName: "abc",
			test: &apis.CStorVolume{
				TypeMeta: metav1.TypeMeta{},
				ObjectMeta: metav1.ObjectMeta{
					Name:      "volume1",
					UID:       types.UID("abc"),
					Namespace: string(common.DefaultNameSpace),
				},
				Spec: apis.CStorVolumeSpec{
					TargetIP: "0.0.0.0",
					Capacity: "5G",
					Status:   "init",
				},
				Status: apis.CStorVolumeStatus{},
			},
		},
		"img2VolumeResource": {
			expectedVolumeName: "abcd",
			test: &apis.CStorVolume{
				TypeMeta: metav1.TypeMeta{},
				ObjectMeta: metav1.ObjectMeta{
					Name:      "volume2",
					UID:       types.UID("abcd"),
					Namespace: string(common.DefaultNameSpace),
				},
				Spec: apis.CStorVolumeSpec{
					TargetIP: "0.0.0.0",
					Capacity: "15G",
					Status:   "init",
				},
				Status: apis.CStorVolumeStatus{},
			},
		},
	}
	for desc, ut := range testVolumeResource {
		// Create Volume resource
		_, err := volumeController.clientset.OpenebsV1alpha1().CStorVolumes(string(common.DefaultNameSpace)).Create(ut.test)
		if err != nil {
			t.Fatalf("Desc:%v, Unable to create resource : %v", desc, ut.test.ObjectMeta.Name)
		}
		// Get the created volume resource using name
		cStorVolumeObtained, err := volumeController.getVolumeResource(ut.test.ObjectMeta.Name)
		if string(cStorVolumeObtained.ObjectMeta.UID) != ut.expectedVolumeName {
			t.Fatalf("Desc:%v, VolumeName mismatch, Expected:%v, Got:%v", desc, ut.expectedVolumeName,
				string(cStorVolumeObtained.ObjectMeta.UID))
		}
	}
}

// TestIsValidCStorVolumeMgmt is to check if right sidecar does operation with env match.
func TestIsValidCStorVolumeMgmt(t *testing.T) {
	testVolumeResource := map[string]struct {
		expectedOutput bool
		test           *apis.CStorVolume
	}{
		"img2VolumeResource": {
			expectedOutput: true,
			test: &apis.CStorVolume{
				TypeMeta: metav1.TypeMeta{},
				ObjectMeta: metav1.ObjectMeta{
					Name:       "volume2",
					UID:        types.UID("abcd"),
					Finalizers: []string{"cstorvolume.openebs.io/finalizer"},
					Namespace:  string(common.DefaultNameSpace),
				},
				Spec: apis.CStorVolumeSpec{
					TargetIP: "0.0.0.0",
					Capacity: "15G",
					Status:   "init",
				},
				Status: apis.CStorVolumeStatus{},
			},
		},
	}
	for desc, ut := range testVolumeResource {
		os.Setenv("OPENEBS_IO_CSTOR_VOLUME_ID", string(ut.test.UID))
		obtainedOutput := IsValidCStorVolumeMgmt(ut.test)
		if obtainedOutput != ut.expectedOutput {
			t.Fatalf("Desc:%v, Expected:%v, Got:%v", desc, ut.expectedOutput,
				obtainedOutput)
		}
		os.Setenv("OPENEBS_IO_CSTOR_VOLUME_ID", "")
	}
}

// TestIsValidCStorVolumeMgmtNegative is to check if right sidecar does operation with env match.
func TestIsValidCStorVolumeMgmtNegative(t *testing.T) {
	testVolumeResource := map[string]struct {
		expectedOutput bool
		test           *apis.CStorVolume
	}{
		"img2VolumeResource": {
			expectedOutput: false,
			test: &apis.CStorVolume{
				TypeMeta: metav1.TypeMeta{},
				ObjectMeta: metav1.ObjectMeta{
					Name:       "volume2",
					UID:        types.UID("abcd"),
					Finalizers: []string{"cstorvolume.openebs.io/finalizer"},
					Namespace:  string(common.DefaultNameSpace),
				},
				Spec: apis.CStorVolumeSpec{
					TargetIP: "0.0.0.0",
					Capacity: "15G",
					Status:   "init",
				},
				Status: apis.CStorVolumeStatus{},
			},
		},
	}
	for desc, ut := range testVolumeResource {
		os.Setenv("OPENEBS_IO_CSTOR_VOLUME_ID", string("awer"))
		obtainedOutput := IsValidCStorVolumeMgmt(ut.test)
		if obtainedOutput != ut.expectedOutput {
			t.Fatalf("Desc:%v, Expected:%v, Got:%v", desc, ut.expectedOutput,
				obtainedOutput)
		}
		os.Setenv("OPENEBS_IO_CSTOR_VOLUME_ID", "")
	}
}
<|endoftext|>


<commit_before>package ov

import (
	"encoding/json"
	"fmt"
	"github.com/HewlettPackard/oneview-golang/rest"
	"github.com/HewlettPackard/oneview-golang/utils"
	"github.com/docker/machine/libmachine/log"
	"strconv"
)

type VirtualPort struct {
	Capabilities []string `json:"capabilities,omitempty"` // "capabilities": {}
	PortFunction string   `json:"portFunction,omitempty"` // "portFunction": "a"
	PortNumber   int      `json:"portNumber,omitempty"`   // "portNumber": 2
}
type SHTPort struct {
	Mapping               int           `json:"mapping,omitempty"`               // "mapping": 3
	MaxSpeedMbps          int           `json:"maxSpeedMbps,omitempty"`          // "maxSpeedMbps":3553
	MaxVFsSupported       int           `json:"maxVFsSupported,omitempty"`       // "maxVFsSupported": 23
	Number                int           `json:"number,omitempty"`                // "number": 1
	PhysicalFunctionCount int           `json:"physicalFunctionCount,omitempty"` // "physicalFunctionCount": 4
	SupportedFcGbps       []string      `json:"supportedFcGbps,omitempty"`       // "supportedFcGbps": ""
	Type                  string        `json:"type,omitempty"`                  // "type": "Ethernet"
	VirtualPort           []VirtualPort `json:"virtualPorts,omitempty"`          // "virtualPorts": {}
}
type Adapter struct {
	Capabilities        []string           `json:"capabilities,omitempty"`        // "capabilities": {}
	DeviceNumber        int                `json:"deviceNumber,omitempty"`        // "deviceNumber": 123
	DeviceType          string             `json:"deviceType,omitempty"`          // "deviceType":"Ethernet"
	Location            string             `json:"location,omitempty"`            // "location": "Mezz"
	MaxVFsSupported     int                `json:"maxVFsSupported,omitempty"`     // "maxVFsSupported": 256
	MinVFsIncrement     int                `json:"minVFsIncrement,omitempty"`     // "minVFsIncrement": 8
	Model               string             `json:"model,omitempty"`               // "model": ""
	Ports               []SHTPort          `json:"ports,omitempty"`               // "ports": {}
	Slot                int                `json:"slot,omitempty"`                // "slot": 3
	StorageCapabilities *StorageCapability `json:"storageCapabilities,omitempty"` // "storageCapabilities":{..,},
}

type Dependency struct {
	Type string `json:"type,omitempty"` // "type": "Map"
}

type OptionLink struct {
	Action    string `json:"action,omitempty"`
	OptionID  string `json:"optionId,omitempty"`
	SettingID string `json:"settingId,omitempty"`
}

type Option struct {
	ID          string       `json:"id,omitempty"`          //"id":"sc3d"
	Name        string       `json:"name,omitempty"`        // "name":"COM"
	OptionLinks []OptionLink `json:"optionLinks,omitempty"` // "optionLinks":{}
}
type BiosSetting struct {
	Category        string       `json:"category,omitempty"`        // "category":""
	DefaultValue    string       `json:"defaultValue,omitempty"`    // "defaultValue":"Cpm21Trq"
	DependencyList  []Dependency `json:"dependencyList,omitempty"`  //"dependencyList:" {}
	HelpText        string       `json:"helpText,omitempty"`        // "helpText": ""
	ID              string       `json:"id,omitempty"`              // "id":""
	LowerBound      int          `json:"lowerBound,omitempty"`      // "lowerBound": 3
	Name            string       `json:"name,omitempty"`            // "name": ""
	Options         []Option     `json:"options,omitempty"`         // "options":{}
	ScalarIncrement int          `json:"scalarIncrement,omitempty"` // "scalarIncrement":4
	StringMaxLength int          `json:"stringMaxLength,omitempty"` // "stringMaxLength":24
	StringMinLength int          `json:"stringMinLength,omitempty"` // "stringMinLength":2
	Type            string       `json:"type,omitempty"`            // "type":""
	UpperBound      int          `json:"upperBound,omitempty"`      // "upperBound": 78
	ValueExpression string       `json:"valueExpression,omitempty"` // "valueExpression":""
	WarningText     string       `json:"warningText,omitempty"`     // "warningText":""
}

type serverDisplaySchema struct {
	Args        []args `json:"args,omitempty"`        // "args":{},
	HelpText    string `json:"helpText,omitempty"`    // "helpText":"",
	Label       string `json:"label,omitempty"`       // "label":"",
	SettingType string `json:"settingType,omitempty"` // "settingType":"",
}

type args struct {
	ArgumentType  string        `json:argumentType,omitempty`  // "argumentType":"",
	AttributeName string        `json:attributeName,omitempty` // "attributeName":"",
	DefaultValue  string        `json:defaultValue,omitempty`  // "defaultValue":"",
	HelpText      string        `json:helpText,omitempty`      // "helpText":"",
	HideShowList  []hidShowList `json:hideShowList,omitempty`  // "hideShowList":{},
	Label         string        `json:label,omitempty`         // "label":"",
	UiData        []uiData      `json:uiData,omitempty`        // "uiData":{},
	Validation    []validation  `json:validation,omitempty`    // "validation":{},

}

type hideShowList struct {
	FieldName   string `json:fieldName,omitempty`   // "filedName":"",
	MatchAction string `json:matchAction,omitempty` // "matchAction":"",
	Value       string `json:value,omitempty`       // "value":"",
}

type uiData struct {
	ItemType string `json:itemType,omitempty` // "itemValue":"",
	Value    string `json:value,omitempty`    // "value":"",
}

type validation struct {
	ValidationType string `json:validationType,omitempty` // "validationType":"",
	Value          string `json:value,omitempty`          // "value":"",
}

type StorageCapability struct {
	ConotrollerCapabilities    []string `json:"controllerCapabilities,omitempty"`     // "controllerCapabilities":{}
	ControllerModes            []string `json:"controllerModes,omitempty"`            // "controllerModes":{}
	DedicatedSpareSupported    bool     `json:"dedicatedSpareSupported,omitempty"`    // "dedicatedSpareSupported":false
	DriveTechnologies          []string `json:"driveTechnologies,omitempty"`          // "driveTechnologies":{}
	DriveWriteCacheSupported   bool     `json:"driveWriteCacheSupported,omitempty"`   // "driveWriteCacheSupported":false
	MaximumDrives              int      `json:"maximumDrives,omitempty"`              // "maximumDrives":5
	NvmeBackplaneCapable       bool     `json:"nvmeBackplaneCapable,omitempty"`       // "nvmeBackplaneCapable":true
	RaidLevels                 []string `json:"raidLevels,omitempty"`                 // "raidLevels":{}
	StandupControllerSupported bool     `json:"standupControllerSupported,omitempty"` // "standupControllerSupported,":false
}
type ServerHardwareType struct {
	Adapters            []Adapter            `json:"adapters,omitempty"`            // "adapters": {},
	BiosSettings        []BiosSetting        `json:"biosSettings,omitempty"`        //"biosSettings": {},
	BootCapabilities    []string             `json:"bootCapabilities,omitempty"`    // "bootCapabilities":{},
	BootModes           []string             `json:"bootModes,omitempty"`           // "bootModes":{},
	Capabilities        []string             `json:"capabilities,omitempty"`        // "capabilities": {},
	Category            string               `json:"category,omitempty"`            // "category": "server-hardware",
	Created             string               `json:"created,omitempty"`             // "created": "20150831T154835.250Z",
	Description         utils.Nstring        `json:"description,omitempty"`         // "description": "ServerHardware",
	ETAG                string               `json:"eTag,omitempty"`                // "eTag": "1441036118675/8",
	Family              string               `json:"family,omitempty"`              // "family":"135",
	FormFactor          string               `json:"formFactor,omitempty"`          // "formFactor":"HalfHeight",
	Model               string               `json:"model,omitempty"`               // "model":"",
	Modified            string               `json:"modified,omitempty"`            // "modified": "20150831T154835.250Z",
	Name                string               `json:"name,omitempty"`                // "name": "ServerHardware 1",
	PxeBootPolicies     []string             `json:"pxeBootPolicies,omitempty"`     // "pxeBootPolicies":{},
	ServerDisplaySchema *serverDisplaySchema `json:"serverDisplaySchema,omitempty"` // "serverDisplaySchema":{},
	StorageCapabilities *StorageCapability   `json:"storageCapabilities,omitempty"` // "storageCapabilities":{..,},
	Type                string               `json:"type,omitempty"`                // "type": "server-hardware-type-10",
	URI                 utils.Nstring        `json:"uri,omitempty"`                 // "uri": "/rest/server-hardware-types/e2f0031b-52bd-4223-9ac1-d91cb519d548"
	UefiClass           string               `json:"uefiClass,omitempty"`           // "uefiClass":"2"
}

type ServerHardwareTypeList struct {
	Total       int                  `json:"total,omitempty"`       // "total": 1,
	Count       int                  `json:"count,omitempty"`       // "count": 1,
	Start       int                  `json:"start,omitempty"`       // "start": 0,
	PrevPageURI utils.Nstring        `json:"prevPageUri,omitempty"` // "prevPageUri": null,
	NextPageURI utils.Nstring        `json:"nextPageUri,omitempty"` // "nextPageUri": null,
	URI         utils.Nstring        `json:"uri,omitempty"`         // "uri": "/rest/server-hardware-types?filter=connectionTemplateUri%20matches%7769cae0-b680-435b-9b87-9b864c81657fsort=name:asc"
	Members     []ServerHardwareType `json:"members,omitempty"`     // "members":[]
}

func (c *OVClient) GetServerHardwareTypeByName(name string) (ServerHardwareType, error) {
	var (
		serverHardwareType ServerHardwareType
	)
	serverHardwareTypes, err := c.GetServerHardwareTypes(0, 0, fmt.Sprintf("name matches '%s'", name), "name:asc")
	if serverHardwareTypes.Total > 0 {
		return serverHardwareTypes.Members[0], err
	} else {
		return serverHardwareType, fmt.Errorf("Could not find Server Hardware Type: %s", name)
	}
}

func (c *OVClient) GetServerHardwareTypeByUri(uri utils.Nstring) (ServerHardwareType, error) {
	var (
		serverHardwareType ServerHardwareType
	)
	// refresh login
	c.RefreshLogin()
	c.SetAuthHeaderOptions(c.GetAuthHeaderMap())
	data, err := c.RestAPICall(rest.GET, uri.String(), nil)
	if err != nil {
		return serverHardwareType, err
	}
	log.Debugf("GetServerHardwareType %s", data)
	if err := json.Unmarshal([]byte(data), &serverHardwareType); err != nil {
		return serverHardwareType, err
	}
	return serverHardwareType, nil
}

func (c *OVClient) GetServerHardwareTypes(start int, count int, filter string, sort string) (ServerHardwareTypeList, error) {
	var (
		uri                 = "/rest/server-hardware-types"
		q                   map[string]interface{}
		serverHardwareTypes ServerHardwareTypeList
	)
	q = make(map[string]interface{})
	if start > 0 {
		q["start"] = strconv.Itoa(start)
	}

	if count > 0 {
		q["count"] = strconv.Itoa(count)
	}

	if len(filter) > 0 {
		q["filter"] = filter
	}

	if sort != "" {
		q["sort"] = sort
	}

	// refresh login
	c.RefreshLogin()
	c.SetAuthHeaderOptions(c.GetAuthHeaderMap())
	// Setup query
	if len(q) > 0 {
		c.SetQueryString(q)
	}

	data, err := c.RestAPICall(rest.GET, uri, nil)
	if err != nil {
		return serverHardwareTypes, err
	}

	log.Debugf("GetServerHardwareTypes %s", data)
	if err := json.Unmarshal([]byte(data), &serverHardwareTypes); err != nil {
		return serverHardwareTypes, err
	}
	return serverHardwareTypes, nil
}
<commit_msg>fixed vet issue<commit_after>package ov

import (
	"encoding/json"
	"fmt"
	"github.com/HewlettPackard/oneview-golang/rest"
	"github.com/HewlettPackard/oneview-golang/utils"
	"github.com/docker/machine/libmachine/log"
	"strconv"
)

type VirtualPort struct {
	Capabilities []string `json:"capabilities,omitempty"` // "capabilities": {}
	PortFunction string   `json:"portFunction,omitempty"` // "portFunction": "a"
	PortNumber   int      `json:"portNumber,omitempty"`   // "portNumber": 2
}
type SHTPort struct {
	Mapping               int           `json:"mapping,omitempty"`               // "mapping": 3
	MaxSpeedMbps          int           `json:"maxSpeedMbps,omitempty"`          // "maxSpeedMbps":3553
	MaxVFsSupported       int           `json:"maxVFsSupported,omitempty"`       // "maxVFsSupported": 23
	Number                int           `json:"number,omitempty"`                // "number": 1
	PhysicalFunctionCount int           `json:"physicalFunctionCount,omitempty"` // "physicalFunctionCount": 4
	SupportedFcGbps       []string      `json:"supportedFcGbps,omitempty"`       // "supportedFcGbps": ""
	Type                  string        `json:"type,omitempty"`                  // "type": "Ethernet"
	VirtualPort           []VirtualPort `json:"virtualPorts,omitempty"`          // "virtualPorts": {}
}
type Adapter struct {
	Capabilities        []string           `json:"capabilities,omitempty"`        // "capabilities": {}
	DeviceNumber        int                `json:"deviceNumber,omitempty"`        // "deviceNumber": 123
	DeviceType          string             `json:"deviceType,omitempty"`          // "deviceType":"Ethernet"
	Location            string             `json:"location,omitempty"`            // "location": "Mezz"
	MaxVFsSupported     int                `json:"maxVFsSupported,omitempty"`     // "maxVFsSupported": 256
	MinVFsIncrement     int                `json:"minVFsIncrement,omitempty"`     // "minVFsIncrement": 8
	Model               string             `json:"model,omitempty"`               // "model": ""
	Ports               []SHTPort          `json:"ports,omitempty"`               // "ports": {}
	Slot                int                `json:"slot,omitempty"`                // "slot": 3
	StorageCapabilities *StorageCapability `json:"storageCapabilities,omitempty"` // "storageCapabilities":{..,},
}

type Dependency struct {
	Type string `json:"type,omitempty"` // "type": "Map"
}

type OptionLink struct {
	Action    string `json:"action,omitempty"`
	OptionID  string `json:"optionId,omitempty"`
	SettingID string `json:"settingId,omitempty"`
}

type Option struct {
	ID          string       `json:"id,omitempty"`          //"id":"sc3d"
	Name        string       `json:"name,omitempty"`        // "name":"COM"
	OptionLinks []OptionLink `json:"optionLinks,omitempty"` // "optionLinks":{}
}
type BiosSetting struct {
	Category        string       `json:"category,omitempty"`        // "category":""
	DefaultValue    string       `json:"defaultValue,omitempty"`    // "defaultValue":"Cpm21Trq"
	DependencyList  []Dependency `json:"dependencyList,omitempty"`  //"dependencyList:" {}
	HelpText        string       `json:"helpText,omitempty"`        // "helpText": ""
	ID              string       `json:"id,omitempty"`              // "id":""
	LowerBound      int          `json:"lowerBound,omitempty"`      // "lowerBound": 3
	Name            string       `json:"name,omitempty"`            // "name": ""
	Options         []Option     `json:"options,omitempty"`         // "options":{}
	ScalarIncrement int          `json:"scalarIncrement,omitempty"` // "scalarIncrement":4
	StringMaxLength int          `json:"stringMaxLength,omitempty"` // "stringMaxLength":24
	StringMinLength int          `json:"stringMinLength,omitempty"` // "stringMinLength":2
	Type            string       `json:"type,omitempty"`            // "type":""
	UpperBound      int          `json:"upperBound,omitempty"`      // "upperBound": 78
	ValueExpression string       `json:"valueExpression,omitempty"` // "valueExpression":""
	WarningText     string       `json:"warningText,omitempty"`     // "warningText":""
}

type serverDisplaySchema struct {
	Args        []args `json:"args,omitempty"`        // "args":{},
	HelpText    string `json:"helpText,omitempty"`    // "helpText":"",
	Label       string `json:"label,omitempty"`       // "label":"",
	SettingType string `json:"settingType,omitempty"` // "settingType":"",
}

type args struct {
	ArgumentType  string         `json:argumentType,omitempty`  // "argumentType":"",
	AttributeName string         `json:attributeName,omitempty` // "attributeName":"",
	DefaultValue  string         `json:defaultValue,omitempty`  // "defaultValue":"",
	HelpText      string         `json:helpText,omitempty`      // "helpText":"",
	HideShowList  []hideShowList `json:hideShowList,omitempty`  // "hideShowList":{},
	Label         string         `json:label,omitempty`         // "label":"",
	UiData        []uiData       `json:uiData,omitempty`        // "uiData":{},
	Validation    []validation   `json:validation,omitempty`    // "validation":{},

}

type hideShowList struct {
	FieldName   string `json:fieldName,omitempty`   // "filedName":"",
	MatchAction string `json:matchAction,omitempty` // "matchAction":"",
	Value       string `json:value,omitempty`       // "value":"",
}

type uiData struct {
	ItemType string `json:itemType,omitempty` // "itemValue":"",
	Value    string `json:value,omitempty`    // "value":"",
}

type validation struct {
	ValidationType string `json:validationType,omitempty` // "validationType":"",
	Value          string `json:value,omitempty`          // "value":"",
}

type StorageCapability struct {
	ConotrollerCapabilities    []string `json:"controllerCapabilities,omitempty"`     // "controllerCapabilities":{}
	ControllerModes            []string `json:"controllerModes,omitempty"`            // "controllerModes":{}
	DedicatedSpareSupported    bool     `json:"dedicatedSpareSupported,omitempty"`    // "dedicatedSpareSupported":false
	DriveTechnologies          []string `json:"driveTechnologies,omitempty"`          // "driveTechnologies":{}
	DriveWriteCacheSupported   bool     `json:"driveWriteCacheSupported,omitempty"`   // "driveWriteCacheSupported":false
	MaximumDrives              int      `json:"maximumDrives,omitempty"`              // "maximumDrives":5
	NvmeBackplaneCapable       bool     `json:"nvmeBackplaneCapable,omitempty"`       // "nvmeBackplaneCapable":true
	RaidLevels                 []string `json:"raidLevels,omitempty"`                 // "raidLevels":{}
	StandupControllerSupported bool     `json:"standupControllerSupported,omitempty"` // "standupControllerSupported,":false
}
type ServerHardwareType struct {
	Adapters            []Adapter            `json:"adapters,omitempty"`            // "adapters": {},
	BiosSettings        []BiosSetting        `json:"biosSettings,omitempty"`        //"biosSettings": {},
	BootCapabilities    []string             `json:"bootCapabilities,omitempty"`    // "bootCapabilities":{},
	BootModes           []string             `json:"bootModes,omitempty"`           // "bootModes":{},
	Capabilities        []string             `json:"capabilities,omitempty"`        // "capabilities": {},
	Category            string               `json:"category,omitempty"`            // "category": "server-hardware",
	Created             string               `json:"created,omitempty"`             // "created": "20150831T154835.250Z",
	Description         utils.Nstring        `json:"description,omitempty"`         // "description": "ServerHardware",
	ETAG                string               `json:"eTag,omitempty"`                // "eTag": "1441036118675/8",
	Family              string               `json:"family,omitempty"`              // "family":"135",
	FormFactor          string               `json:"formFactor,omitempty"`          // "formFactor":"HalfHeight",
	Model               string               `json:"model,omitempty"`               // "model":"",
	Modified            string               `json:"modified,omitempty"`            // "modified": "20150831T154835.250Z",
	Name                string               `json:"name,omitempty"`                // "name": "ServerHardware 1",
	PxeBootPolicies     []string             `json:"pxeBootPolicies,omitempty"`     // "pxeBootPolicies":{},
	ServerDisplaySchema *serverDisplaySchema `json:"serverDisplaySchema,omitempty"` // "serverDisplaySchema":{},
	StorageCapabilities *StorageCapability   `json:"storageCapabilities,omitempty"` // "storageCapabilities":{..,},
	Type                string               `json:"type,omitempty"`                // "type": "server-hardware-type-10",
	URI                 utils.Nstring        `json:"uri,omitempty"`                 // "uri": "/rest/server-hardware-types/e2f0031b-52bd-4223-9ac1-d91cb519d548"
	UefiClass           string               `json:"uefiClass,omitempty"`           // "uefiClass":"2"
}

type ServerHardwareTypeList struct {
	Total       int                  `json:"total,omitempty"`       // "total": 1,
	Count       int                  `json:"count,omitempty"`       // "count": 1,
	Start       int                  `json:"start,omitempty"`       // "start": 0,
	PrevPageURI utils.Nstring        `json:"prevPageUri,omitempty"` // "prevPageUri": null,
	NextPageURI utils.Nstring        `json:"nextPageUri,omitempty"` // "nextPageUri": null,
	URI         utils.Nstring        `json:"uri,omitempty"`         // "uri": "/rest/server-hardware-types?filter=connectionTemplateUri%20matches%7769cae0-b680-435b-9b87-9b864c81657fsort=name:asc"
	Members     []ServerHardwareType `json:"members,omitempty"`     // "members":[]
}

func (c *OVClient) GetServerHardwareTypeByName(name string) (ServerHardwareType, error) {
	var (
		serverHardwareType ServerHardwareType
	)
	serverHardwareTypes, err := c.GetServerHardwareTypes(0, 0, fmt.Sprintf("name matches '%s'", name), "name:asc")
	if serverHardwareTypes.Total > 0 {
		return serverHardwareTypes.Members[0], err
	} else {
		return serverHardwareType, fmt.Errorf("Could not find Server Hardware Type: %s", name)
	}
}

func (c *OVClient) GetServerHardwareTypeByUri(uri utils.Nstring) (ServerHardwareType, error) {
	var (
		serverHardwareType ServerHardwareType
	)
	// refresh login
	c.RefreshLogin()
	c.SetAuthHeaderOptions(c.GetAuthHeaderMap())
	data, err := c.RestAPICall(rest.GET, uri.String(), nil)
	if err != nil {
		return serverHardwareType, err
	}
	log.Debugf("GetServerHardwareType %s", data)
	if err := json.Unmarshal([]byte(data), &serverHardwareType); err != nil {
		return serverHardwareType, err
	}
	return serverHardwareType, nil
}

func (c *OVClient) GetServerHardwareTypes(start int, count int, filter string, sort string) (ServerHardwareTypeList, error) {
	var (
		uri                 = "/rest/server-hardware-types"
		q                   map[string]interface{}
		serverHardwareTypes ServerHardwareTypeList
	)
	q = make(map[string]interface{})
	if start > 0 {
		q["start"] = strconv.Itoa(start)
	}

	if count > 0 {
		q["count"] = strconv.Itoa(count)
	}

	if len(filter) > 0 {
		q["filter"] = filter
	}

	if sort != "" {
		q["sort"] = sort
	}

	// refresh login
	c.RefreshLogin()
	c.SetAuthHeaderOptions(c.GetAuthHeaderMap())
	// Setup query
	if len(q) > 0 {
		c.SetQueryString(q)
	}

	data, err := c.RestAPICall(rest.GET, uri, nil)
	if err != nil {
		return serverHardwareTypes, err
	}

	log.Debugf("GetServerHardwareTypes %s", data)
	if err := json.Unmarshal([]byte(data), &serverHardwareTypes); err != nil {
		return serverHardwareTypes, err
	}
	return serverHardwareTypes, nil
}
<|endoftext|>


<commit_before>// Copyright 2021 Google Inc.
//
// 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.

// +build !localtest !tpm12
// +build cgo

// NOTE: simulator requires cgo, hence the build tag.

package attest

import (
	"bytes"
	"crypto"
	"crypto/ecdsa"
	"crypto/rand"
	"crypto/x509"
	"encoding/asn1"
	"math/big"
	"testing"
)

func TestSimTPM20KeyCreateAndLoad(t *testing.T) {
	sim, tpm := setupSimulatedTPM(t)
	defer sim.Close()
	testKeyCreateAndLoad(t, tpm)
}

func TestTPM20KeyCreateAndLoad(t *testing.T) {
	if !*testLocal {
		t.SkipNow()
	}
	tpm, err := OpenTPM(nil)
	if err != nil {
		t.Fatalf("OpenTPM() failed: %v", err)
	}
	defer tpm.Close()
	testKeyCreateAndLoad(t, tpm)
}

func testKeyCreateAndLoad(t *testing.T, tpm *TPM) {
	ak, err := tpm.NewAK(nil)
	if err != nil {
		t.Fatalf("NewAK() failed: %v", err)
	}
	sk, err := tpm.NewKey(ak, nil)
	if err != nil {
		t.Fatalf("NewKey() failed: %v", err)
	}
	defer sk.Close()

	enc, err := sk.Marshal()
	if err != nil {
		t.Fatalf("sk.Marshal() failed: %v", err)
	}
	if err := sk.Close(); err != nil {
		t.Fatalf("sk.Close() failed: %v", err)
	}

	loaded, err := tpm.LoadKey(enc)
	if err != nil {
		t.Fatalf("LoadKey() failed: %v", err)
	}
	defer loaded.Close()

	k1, k2 := sk.key.(*wrappedKey20), loaded.key.(*wrappedKey20)
	if !bytes.Equal(k1.public, k2.public) {
		t.Error("Original & loaded Key public blobs did not match.")
		t.Logf("Original = %v", k1.public)
		t.Logf("Loaded   = %v", k2.public)
	}

	priv1, err := sk.Private(sk.Public())
	if err != nil {
		t.Fatalf("sk.Private() failed: %v", err)
	}
	signer1, ok := priv1.(crypto.Signer)
	if !ok {
		t.Fatalf("want crypto.Signer, got %T", priv1)
	}
	pk1, err := x509.MarshalPKIXPublicKey(signer1.Public())
	if err != nil {
		t.Fatalf("cannot marshal public key: %v", err)
	}

	priv2, err := loaded.Private(loaded.Public())
	if err != nil {
		t.Fatalf("loaded.Private() failed: %v", err)
	}
	signer2, ok := priv2.(crypto.Signer)
	if !ok {
		t.Fatalf("want crypto.Signer, got %T", priv2)
	}
	pk2, err := x509.MarshalPKIXPublicKey(signer2.Public())
	if err != nil {
		t.Fatalf("cannot marshal public key: %v", err)
	}

	if !bytes.Equal(pk1, pk2) {
		t.Error("public keys do not match")
	}
}

func TestSimTPM20KeySign(t *testing.T) {
	sim, tpm := setupSimulatedTPM(t)
	defer sim.Close()
	testKeySign(t, tpm)
}

func TestTPM20KeySign(t *testing.T) {
	if !*testLocal {
		t.SkipNow()
	}
	tpm, err := OpenTPM(nil)
	if err != nil {
		t.Fatalf("OpenTPM() failed: %v", err)
	}
	defer tpm.Close()
	testKeySign(t, tpm)
}

func testKeySign(t *testing.T, tpm *TPM) {
	ak, err := tpm.NewAK(nil)
	if err != nil {
		t.Fatalf("NewAK() failed: %v", err)
	}
	sk, err := tpm.NewKey(ak, nil)
	if err != nil {
		t.Fatalf("NewKey() failed: %v", err)
	}
	defer sk.Close()

	pub := sk.Public()
	priv, err := sk.Private(pub)
	if err != nil {
		t.Fatalf("sk.Private() failed: %v", err)
	}
	signer, ok := priv.(crypto.Signer)
	if !ok {
		t.Fatalf("want crypto.Signer, got %T", priv)
	}
	digest := []byte("12345678901234567890123456789012")
	sig, err := signer.Sign(rand.Reader, digest, nil)
	if !ok {
		t.Fatalf("signer.Sign() failed: %v", err)
	}

	parsed := struct{ R, S *big.Int }{}
	_, err = asn1.Unmarshal(sig, &parsed)
	if err != nil {
		t.Fatalf("signature parsing failed: %v", err)
	}

	pubECDSA, ok := pub.(*ecdsa.PublicKey)
	if !ok {
		t.Fatalf("want *ecdsa.PublicKey, got %T", pub)
	}
	if !ecdsa.Verify(pubECDSA, digest[:], parsed.R, parsed.S) {
		t.Fatalf("ecdsa.Verify() failed")
	}
}
<commit_msg>testKeySign: small fix (#206)<commit_after>// Copyright 2021 Google Inc.
//
// 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.

// +build !localtest !tpm12
// +build cgo

// NOTE: simulator requires cgo, hence the build tag.

package attest

import (
	"bytes"
	"crypto"
	"crypto/ecdsa"
	"crypto/rand"
	"crypto/x509"
	"encoding/asn1"
	"math/big"
	"testing"
)

func TestSimTPM20KeyCreateAndLoad(t *testing.T) {
	sim, tpm := setupSimulatedTPM(t)
	defer sim.Close()
	testKeyCreateAndLoad(t, tpm)
}

func TestTPM20KeyCreateAndLoad(t *testing.T) {
	if !*testLocal {
		t.SkipNow()
	}
	tpm, err := OpenTPM(nil)
	if err != nil {
		t.Fatalf("OpenTPM() failed: %v", err)
	}
	defer tpm.Close()
	testKeyCreateAndLoad(t, tpm)
}

func testKeyCreateAndLoad(t *testing.T, tpm *TPM) {
	ak, err := tpm.NewAK(nil)
	if err != nil {
		t.Fatalf("NewAK() failed: %v", err)
	}
	sk, err := tpm.NewKey(ak, nil)
	if err != nil {
		t.Fatalf("NewKey() failed: %v", err)
	}
	defer sk.Close()

	enc, err := sk.Marshal()
	if err != nil {
		t.Fatalf("sk.Marshal() failed: %v", err)
	}
	if err := sk.Close(); err != nil {
		t.Fatalf("sk.Close() failed: %v", err)
	}

	loaded, err := tpm.LoadKey(enc)
	if err != nil {
		t.Fatalf("LoadKey() failed: %v", err)
	}
	defer loaded.Close()

	k1, k2 := sk.key.(*wrappedKey20), loaded.key.(*wrappedKey20)
	if !bytes.Equal(k1.public, k2.public) {
		t.Error("Original & loaded Key public blobs did not match.")
		t.Logf("Original = %v", k1.public)
		t.Logf("Loaded   = %v", k2.public)
	}

	priv1, err := sk.Private(sk.Public())
	if err != nil {
		t.Fatalf("sk.Private() failed: %v", err)
	}
	signer1, ok := priv1.(crypto.Signer)
	if !ok {
		t.Fatalf("want crypto.Signer, got %T", priv1)
	}
	pk1, err := x509.MarshalPKIXPublicKey(signer1.Public())
	if err != nil {
		t.Fatalf("cannot marshal public key: %v", err)
	}

	priv2, err := loaded.Private(loaded.Public())
	if err != nil {
		t.Fatalf("loaded.Private() failed: %v", err)
	}
	signer2, ok := priv2.(crypto.Signer)
	if !ok {
		t.Fatalf("want crypto.Signer, got %T", priv2)
	}
	pk2, err := x509.MarshalPKIXPublicKey(signer2.Public())
	if err != nil {
		t.Fatalf("cannot marshal public key: %v", err)
	}

	if !bytes.Equal(pk1, pk2) {
		t.Error("public keys do not match")
	}
}

func TestSimTPM20KeySign(t *testing.T) {
	sim, tpm := setupSimulatedTPM(t)
	defer sim.Close()
	testKeySign(t, tpm)
}

func TestTPM20KeySign(t *testing.T) {
	if !*testLocal {
		t.SkipNow()
	}
	tpm, err := OpenTPM(nil)
	if err != nil {
		t.Fatalf("OpenTPM() failed: %v", err)
	}
	defer tpm.Close()
	testKeySign(t, tpm)
}

func testKeySign(t *testing.T, tpm *TPM) {
	ak, err := tpm.NewAK(nil)
	if err != nil {
		t.Fatalf("NewAK() failed: %v", err)
	}
	sk, err := tpm.NewKey(ak, nil)
	if err != nil {
		t.Fatalf("NewKey() failed: %v", err)
	}
	defer sk.Close()

	pub := sk.Public()
	priv, err := sk.Private(pub)
	if err != nil {
		t.Fatalf("sk.Private() failed: %v", err)
	}
	signer, ok := priv.(crypto.Signer)
	if !ok {
		t.Fatalf("want crypto.Signer, got %T", priv)
	}
	digest := []byte("12345678901234567890123456789012")
	sig, err := signer.Sign(rand.Reader, digest, nil)
	if err != nil {
		t.Fatalf("signer.Sign() failed: %v", err)
	}

	parsed := struct{ R, S *big.Int }{}
	_, err = asn1.Unmarshal(sig, &parsed)
	if err != nil {
		t.Fatalf("signature parsing failed: %v", err)
	}

	pubECDSA, ok := pub.(*ecdsa.PublicKey)
	if !ok {
		t.Fatalf("want *ecdsa.PublicKey, got %T", pub)
	}
	if !ecdsa.Verify(pubECDSA, digest[:], parsed.R, parsed.S) {
		t.Fatalf("ecdsa.Verify() failed")
	}
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/ec2"

	"github.com/hashicorp/errwrap"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsEbsVolume() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsEbsVolumeCreate,
		Read:   resourceAwsEbsVolumeRead,
		Update: resourceAWSEbsVolumeUpdate,
		Delete: resourceAwsEbsVolumeDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"availability_zone": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"encrypted": {
				Type:     schema.TypeBool,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},
			"iops": {
				Type:     schema.TypeInt,
				Optional: true,
				Computed: true,
			},
			"kms_key_id": {
				Type:         schema.TypeString,
				Optional:     true,
				Computed:     true,
				ForceNew:     true,
				ValidateFunc: validateArn,
			},
			"size": {
				Type:     schema.TypeInt,
				Optional: true,
				Computed: true,
			},
			"snapshot_id": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},
			"type": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"tags": tagsSchema(),
		},
	}
}

func resourceAwsEbsVolumeCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	request := &ec2.CreateVolumeInput{
		AvailabilityZone: aws.String(d.Get("availability_zone").(string)),
	}
	if value, ok := d.GetOk("encrypted"); ok {
		request.Encrypted = aws.Bool(value.(bool))
	}
	if value, ok := d.GetOk("kms_key_id"); ok {
		request.KmsKeyId = aws.String(value.(string))
	}
	if value, ok := d.GetOk("size"); ok {
		request.Size = aws.Int64(int64(value.(int)))
	}
	if value, ok := d.GetOk("snapshot_id"); ok {
		request.SnapshotId = aws.String(value.(string))
	}

	// IOPs are only valid, and required for, storage type io1. The current minimu
	// is 100. Instead of a hard validation we we only apply the IOPs to the
	// request if the type is io1, and log a warning otherwise. This allows users
	// to "disable" iops. See https://github.com/hashicorp/terraform/pull/4146
	var t string
	if value, ok := d.GetOk("type"); ok {
		t = value.(string)
		request.VolumeType = aws.String(t)
	}

	iops := d.Get("iops").(int)
	if t != "io1" && iops > 0 {
		log.Printf("[WARN] IOPs is only valid for storate type io1 for EBS Volumes")
	} else if t == "io1" {
		// We add the iops value without validating it's size, to allow AWS to
		// enforce a size requirement (currently 100)
		request.Iops = aws.Int64(int64(iops))
	}

	log.Printf(
		"[DEBUG] EBS Volume create opts: %s", request)
	result, err := conn.CreateVolume(request)
	if err != nil {
		return fmt.Errorf("Error creating EC2 volume: %s", err)
	}

	log.Println("[DEBUG] Waiting for Volume to become available")

	stateConf := &resource.StateChangeConf{
		Pending:    []string{"creating"},
		Target:     []string{"available"},
		Refresh:    volumeStateRefreshFunc(conn, *result.VolumeId),
		Timeout:    5 * time.Minute,
		Delay:      10 * time.Second,
		MinTimeout: 3 * time.Second,
	}

	_, err = stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf(
			"Error waiting for Volume (%s) to become available: %s",
			*result.VolumeId, err)
	}

	d.SetId(*result.VolumeId)

	if _, ok := d.GetOk("tags"); ok {
		if err := setTags(conn, d); err != nil {
			return errwrap.Wrapf("Error setting tags for EBS Volume: {{err}}", err)
		}
	}

	return readVolume(d, result)
}

func resourceAWSEbsVolumeUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn
	if _, ok := d.GetOk("tags"); ok {
		if err := setTags(conn, d); err != nil {
			return errwrap.Wrapf("Error updating tags for EBS Volume: {{err}}", err)
		}
	}

	requestUpdate := false
	params := &ec2.ModifyVolumeInput{
		VolumeId: aws.String(d.Id()),
	}

	if d.HasChange("size") {
		requestUpdate = true
		params.Size = aws.Int64(int64(d.Get("size").(int)))
	}

	if d.HasChange("type") {
		requestUpdate = true
		params.VolumeType = aws.String(d.Get("type").(string))
	}

	if d.HasChange("iops") {
		requestUpdate = true
		params.Iops = aws.Int64(int64(d.Get("iops").(int)))
	}

	if requestUpdate {
		result, err := conn.ModifyVolume(params)
		if err != nil {
			return err
		}

		stateConf := &resource.StateChangeConf{
			Pending:    []string{"creating", "modifying"},
			Target:     []string{"available", "in-use"},
			Refresh:    volumeStateRefreshFunc(conn, *result.VolumeModification.VolumeId),
			Timeout:    5 * time.Minute,
			Delay:      10 * time.Second,
			MinTimeout: 3 * time.Second,
		}

		_, err = stateConf.WaitForState()
		if err != nil {
			return fmt.Errorf(
				"Error waiting for Volume (%s) to become available: %s",
				*result.VolumeModification.VolumeId, err)
		}
	}

	return resourceAwsEbsVolumeRead(d, meta)
}

// volumeStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch
// a the state of a Volume. Returns successfully when volume is available
func volumeStateRefreshFunc(conn *ec2.EC2, volumeID string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		resp, err := conn.DescribeVolumes(&ec2.DescribeVolumesInput{
			VolumeIds: []*string{aws.String(volumeID)},
		})

		if err != nil {
			if ec2err, ok := err.(awserr.Error); ok {
				// Set this to nil as if we didn't find anything.
				log.Printf("Error on Volume State Refresh: message: \"%s\", code:\"%s\"", ec2err.Message(), ec2err.Code())
				resp = nil
				return nil, "", err
			} else {
				log.Printf("Error on Volume State Refresh: %s", err)
				return nil, "", err
			}
		}

		v := resp.Volumes[0]
		return v, *v.State, nil
	}
}

func resourceAwsEbsVolumeRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	request := &ec2.DescribeVolumesInput{
		VolumeIds: []*string{aws.String(d.Id())},
	}

	response, err := conn.DescribeVolumes(request)
	if err != nil {
		if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidVolume.NotFound" {
			d.SetId("")
			return nil
		}
		return fmt.Errorf("Error reading EC2 volume %s: %s", d.Id(), err)
	}

	return readVolume(d, response.Volumes[0])
}

func resourceAwsEbsVolumeDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	return resource.Retry(5*time.Minute, func() *resource.RetryError {
		request := &ec2.DeleteVolumeInput{
			VolumeId: aws.String(d.Id()),
		}
		_, err := conn.DeleteVolume(request)
		if err == nil {
			return nil
		}

		ebsErr, ok := err.(awserr.Error)
		if ebsErr.Code() == "VolumeInUse" {
			return resource.RetryableError(fmt.Errorf("EBS VolumeInUse - trying again while it detaches"))
		}

		if !ok {
			return resource.NonRetryableError(err)
		}

		return resource.NonRetryableError(err)
	})

}

func readVolume(d *schema.ResourceData, volume *ec2.Volume) error {
	d.SetId(*volume.VolumeId)

	d.Set("availability_zone", *volume.AvailabilityZone)
	if volume.Encrypted != nil {
		d.Set("encrypted", *volume.Encrypted)
	}
	if volume.KmsKeyId != nil {
		d.Set("kms_key_id", *volume.KmsKeyId)
	}
	if volume.Size != nil {
		d.Set("size", *volume.Size)
	}
	if volume.SnapshotId != nil {
		d.Set("snapshot_id", *volume.SnapshotId)
	}
	if volume.VolumeType != nil {
		d.Set("type", *volume.VolumeType)
	}

	if volume.VolumeType != nil && *volume.VolumeType == "io1" {
		// Only set the iops attribute if the volume type is io1. Setting otherwise
		// can trigger a refresh/plan loop based on the computed value that is given
		// from AWS, and prevent us from specifying 0 as a valid iops.
		//   See https://github.com/hashicorp/terraform/pull/4146
		if volume.Iops != nil {
			d.Set("iops", *volume.Iops)
		}
	}

	if volume.Tags != nil {
		d.Set("tags", tagsToMap(volume.Tags))
	}

	return nil
}
<commit_msg>resource/aws_ebs_volume: Not setting the state for ebs_volume correctly (#999)<commit_after>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awserr"
	"github.com/aws/aws-sdk-go/service/ec2"

	"github.com/hashicorp/errwrap"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsEbsVolume() *schema.Resource {
	return &schema.Resource{
		Create: resourceAwsEbsVolumeCreate,
		Read:   resourceAwsEbsVolumeRead,
		Update: resourceAWSEbsVolumeUpdate,
		Delete: resourceAwsEbsVolumeDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"availability_zone": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"encrypted": {
				Type:     schema.TypeBool,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},
			"iops": {
				Type:     schema.TypeInt,
				Optional: true,
				Computed: true,
			},
			"kms_key_id": {
				Type:         schema.TypeString,
				Optional:     true,
				Computed:     true,
				ForceNew:     true,
				ValidateFunc: validateArn,
			},
			"size": {
				Type:     schema.TypeInt,
				Optional: true,
				Computed: true,
			},
			"snapshot_id": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ForceNew: true,
			},
			"type": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},
			"tags": tagsSchema(),
		},
	}
}

func resourceAwsEbsVolumeCreate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	request := &ec2.CreateVolumeInput{
		AvailabilityZone: aws.String(d.Get("availability_zone").(string)),
	}
	if value, ok := d.GetOk("encrypted"); ok {
		request.Encrypted = aws.Bool(value.(bool))
	}
	if value, ok := d.GetOk("kms_key_id"); ok {
		request.KmsKeyId = aws.String(value.(string))
	}
	if value, ok := d.GetOk("size"); ok {
		request.Size = aws.Int64(int64(value.(int)))
	}
	if value, ok := d.GetOk("snapshot_id"); ok {
		request.SnapshotId = aws.String(value.(string))
	}

	// IOPs are only valid, and required for, storage type io1. The current minimu
	// is 100. Instead of a hard validation we we only apply the IOPs to the
	// request if the type is io1, and log a warning otherwise. This allows users
	// to "disable" iops. See https://github.com/hashicorp/terraform/pull/4146
	var t string
	if value, ok := d.GetOk("type"); ok {
		t = value.(string)
		request.VolumeType = aws.String(t)
	}

	iops := d.Get("iops").(int)
	if t != "io1" && iops > 0 {
		log.Printf("[WARN] IOPs is only valid for storate type io1 for EBS Volumes")
	} else if t == "io1" {
		// We add the iops value without validating it's size, to allow AWS to
		// enforce a size requirement (currently 100)
		request.Iops = aws.Int64(int64(iops))
	}

	log.Printf(
		"[DEBUG] EBS Volume create opts: %s", request)
	result, err := conn.CreateVolume(request)
	if err != nil {
		return fmt.Errorf("Error creating EC2 volume: %s", err)
	}

	log.Println("[DEBUG] Waiting for Volume to become available")

	stateConf := &resource.StateChangeConf{
		Pending:    []string{"creating"},
		Target:     []string{"available"},
		Refresh:    volumeStateRefreshFunc(conn, *result.VolumeId),
		Timeout:    5 * time.Minute,
		Delay:      10 * time.Second,
		MinTimeout: 3 * time.Second,
	}

	_, err = stateConf.WaitForState()
	if err != nil {
		return fmt.Errorf(
			"Error waiting for Volume (%s) to become available: %s",
			*result.VolumeId, err)
	}

	d.SetId(*result.VolumeId)

	if _, ok := d.GetOk("tags"); ok {
		if err := setTags(conn, d); err != nil {
			return errwrap.Wrapf("Error setting tags for EBS Volume: {{err}}", err)
		}
	}

	return resourceAwsEbsVolumeRead(d, meta)
}

func resourceAWSEbsVolumeUpdate(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn
	if _, ok := d.GetOk("tags"); ok {
		if err := setTags(conn, d); err != nil {
			return errwrap.Wrapf("Error updating tags for EBS Volume: {{err}}", err)
		}
	}

	requestUpdate := false
	params := &ec2.ModifyVolumeInput{
		VolumeId: aws.String(d.Id()),
	}

	if d.HasChange("size") {
		requestUpdate = true
		params.Size = aws.Int64(int64(d.Get("size").(int)))
	}

	if d.HasChange("type") {
		requestUpdate = true
		params.VolumeType = aws.String(d.Get("type").(string))
	}

	if d.HasChange("iops") {
		requestUpdate = true
		params.Iops = aws.Int64(int64(d.Get("iops").(int)))
	}

	if requestUpdate {
		result, err := conn.ModifyVolume(params)
		if err != nil {
			return err
		}

		stateConf := &resource.StateChangeConf{
			Pending:    []string{"creating", "modifying"},
			Target:     []string{"available", "in-use"},
			Refresh:    volumeStateRefreshFunc(conn, *result.VolumeModification.VolumeId),
			Timeout:    5 * time.Minute,
			Delay:      10 * time.Second,
			MinTimeout: 3 * time.Second,
		}

		_, err = stateConf.WaitForState()
		if err != nil {
			return fmt.Errorf(
				"Error waiting for Volume (%s) to become available: %s",
				*result.VolumeModification.VolumeId, err)
		}
	}

	return resourceAwsEbsVolumeRead(d, meta)
}

// volumeStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch
// a the state of a Volume. Returns successfully when volume is available
func volumeStateRefreshFunc(conn *ec2.EC2, volumeID string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		resp, err := conn.DescribeVolumes(&ec2.DescribeVolumesInput{
			VolumeIds: []*string{aws.String(volumeID)},
		})

		if err != nil {
			if ec2err, ok := err.(awserr.Error); ok {
				// Set this to nil as if we didn't find anything.
				log.Printf("Error on Volume State Refresh: message: \"%s\", code:\"%s\"", ec2err.Message(), ec2err.Code())
				resp = nil
				return nil, "", err
			} else {
				log.Printf("Error on Volume State Refresh: %s", err)
				return nil, "", err
			}
		}

		v := resp.Volumes[0]
		return v, *v.State, nil
	}
}

func resourceAwsEbsVolumeRead(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	request := &ec2.DescribeVolumesInput{
		VolumeIds: []*string{aws.String(d.Id())},
	}

	response, err := conn.DescribeVolumes(request)
	if err != nil {
		if ec2err, ok := err.(awserr.Error); ok && ec2err.Code() == "InvalidVolume.NotFound" {
			d.SetId("")
			return nil
		}
		return fmt.Errorf("Error reading EC2 volume %s: %s", d.Id(), err)
	}

	return readVolume(d, response.Volumes[0])
}

func resourceAwsEbsVolumeDelete(d *schema.ResourceData, meta interface{}) error {
	conn := meta.(*AWSClient).ec2conn

	return resource.Retry(5*time.Minute, func() *resource.RetryError {
		request := &ec2.DeleteVolumeInput{
			VolumeId: aws.String(d.Id()),
		}
		_, err := conn.DeleteVolume(request)
		if err == nil {
			return nil
		}

		ebsErr, ok := err.(awserr.Error)
		if ebsErr.Code() == "VolumeInUse" {
			return resource.RetryableError(fmt.Errorf("EBS VolumeInUse - trying again while it detaches"))
		}

		if !ok {
			return resource.NonRetryableError(err)
		}

		return resource.NonRetryableError(err)
	})

}

func readVolume(d *schema.ResourceData, volume *ec2.Volume) error {
	d.SetId(*volume.VolumeId)

	d.Set("availability_zone", *volume.AvailabilityZone)
	if volume.Encrypted != nil {
		d.Set("encrypted", *volume.Encrypted)
	}
	if volume.KmsKeyId != nil {
		d.Set("kms_key_id", *volume.KmsKeyId)
	}
	if volume.Size != nil {
		d.Set("size", *volume.Size)
	}
	if volume.SnapshotId != nil {
		d.Set("snapshot_id", *volume.SnapshotId)
	}
	if volume.VolumeType != nil {
		d.Set("type", *volume.VolumeType)
	}

	if volume.VolumeType != nil && *volume.VolumeType == "io1" {
		// Only set the iops attribute if the volume type is io1. Setting otherwise
		// can trigger a refresh/plan loop based on the computed value that is given
		// from AWS, and prevent us from specifying 0 as a valid iops.
		//   See https://github.com/hashicorp/terraform/pull/4146
		if volume.Iops != nil {
			d.Set("iops", *volume.Iops)
		}
	}

	d.Set("tags", tagsToMap(volume.Tags))

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"net"
	"regexp"
	"sort"
	"strings"

	"github.com/wfarr/termtable"
)

func main() {
	// establish connection to our socket, for both reads and writes
	conn, err := net.Dial("unix", "/var/lib/nagios/rw/nagios.qh")
	if err != nil {
		panic(err.Error())
	}
	defer conn.Close()

	// suss out what command we actually wish to run
	if len(os.Args) == 0 {
		send_command(conn, "help")
	}

	switch os.Args[1] {
	case "help", "status", "check", "acknowledge", "unacknowledge", "disable_notifications", "enable_notifications", "downtime", "problems", "muted", "stats":
		send_command(conn, strings.Join(os.Args[1:], " "))
	case "ack":
		send_command(conn, "acknowledge" + " " + strings.Join(os.Args[2:], " "))
	case "unack":
		send_command(conn, "unacknowledge" + " " + strings.Join(os.Args[2:], " "))
	case "mute":
		send_command(conn, "disable_notifications" + " " + strings.Join(os.Args[2:], " "))
	case "unmute":
		send_command(conn, "enable_notifications" + " " + strings.Join(os.Args[2:], " "))
	default:
		send_command(conn, "help")
	}

	output := read_results(conn)
	lines := strings.Split(output, "\n")
	table_it, err := regexp.MatchString(";", output)

	if len(lines[1:]) > 0 && table_it {
		sort.Sort(sort.StringSlice(lines))

		t := termtable.NewTable(&termtable.TableOptions{Padding: 1, Header: []string{"Service", "Status", "Details"}, MaxColWidth: 72,})

		for _, line := range lines[1:] {
			parts := [3]string{"", "", ""}
			split := strings.Split(line, ";")

                        for i := 0; i < 3; i++ {
				var part string

				if i == 2 {
					part = strings.Join(split[2:], "")
				} else {
					part = split[i]
				}

				parts[i] = part

				if parts[i] == "" {
					parts[i] = "wat"
				}
			}

			row := []string{ parts[0], parts[1], parts[2] }
			t.AddRow(row)
		}

		fmt.Println(t.Render())
	} else {
		fmt.Println(strings.Join(lines, "\n"))
	}
}

func send_command(conn net.Conn, cmd string) {
	_, err := conn.Write([]byte(fmt.Sprintf("#nagioseasier %s\000", cmd)))
	if err != nil {
		panic(err.Error())
	}

}

func read_results(conn net.Conn) (output string) {
	buf := make([]byte, 4096)
	for ;; {
		n, err := conn.Read(buf[:])

		if err != nil {
			return scrub(output)
		}

		if n == 0 {
			fmt.Println("Connection closed by socket")
			return scrub(output)
		}

		output = output + string(buf[0:n])
	}
}

func scrub(input string) (output string) {
	// get rid of pesky null chars
	output = strings.Replace(input, "\000", "", -1)

	// get rid of fake newlines, lol
	output = strings.Replace(output, "\\n", "", -1)

	// chomp off trailing newlines
	output = strings.Trim(output, "\n")

	// trim spaces
	output = strings.TrimSpace(output)

	return
}
<commit_msg>Fix printing of non-tabular items<commit_after>package main

import (
	"fmt"
	"os"
	"net"
	"regexp"
	"sort"
	"strings"

	"github.com/wfarr/termtable"
)

func main() {
	// establish connection to our socket, for both reads and writes
	conn, err := net.Dial("unix", "/var/lib/nagios/rw/nagios.qh")
	if err != nil {
		panic(err.Error())
	}
	defer conn.Close()

	// suss out what command we actually wish to run
	if len(os.Args) == 0 {
		send_command(conn, "help")
	}

	switch os.Args[1] {
	case "help", "status", "check", "acknowledge", "unacknowledge", "disable_notifications", "enable_notifications", "downtime", "problems", "muted", "stats":
		send_command(conn, strings.Join(os.Args[1:], " "))
	case "ack":
		send_command(conn, "acknowledge" + " " + strings.Join(os.Args[2:], " "))
	case "unack":
		send_command(conn, "unacknowledge" + " " + strings.Join(os.Args[2:], " "))
	case "mute":
		send_command(conn, "disable_notifications" + " " + strings.Join(os.Args[2:], " "))
	case "unmute":
		send_command(conn, "enable_notifications" + " " + strings.Join(os.Args[2:], " "))
	default:
		send_command(conn, "help")
	}

	output := read_results(conn)
	lines := strings.Split(output, "\n")
	table_it, err := regexp.MatchString(";", output)

	if len(lines[1:]) > 0 && table_it {
		sort.Sort(sort.StringSlice(lines))

		t := termtable.NewTable(&termtable.TableOptions{Padding: 1, Header: []string{"Service", "Status", "Details"}, MaxColWidth: 72,})

		for _, line := range lines[1:] {
			parts := [3]string{"", "", ""}
			split := strings.Split(line, ";")

                        for i := 0; i < 3; i++ {
				var part string

				if i == 2 {
					part = strings.Join(split[2:], "")
				} else {
					part = split[i]
				}

				parts[i] = part

				if parts[i] == "" {
					parts[i] = "wat"
				}
			}

			row := []string{ parts[0], parts[1], parts[2] }
			t.AddRow(row)
		}

		fmt.Println(t.Render())
	} else {
		fmt.Println(strings.Join(lines[0:len(lines)-1], "\n"))
	}
}

func send_command(conn net.Conn, cmd string) {
	_, err := conn.Write([]byte(fmt.Sprintf("#nagioseasier %s\000", cmd)))
	if err != nil {
		panic(err.Error())
	}

}

func read_results(conn net.Conn) (output string) {
	buf := make([]byte, 4096)
	for ;; {
		n, err := conn.Read(buf[:])

		if err != nil {
			return scrub(output)
		}

		if n == 0 {
			fmt.Println("Connection closed by socket")
			return scrub(output)
		}

		output = output + string(buf[0:n])
	}
}

func scrub(input string) (output string) {
	// get rid of pesky null chars
	output = strings.Replace(input, "\000", "", -1)

	// get rid of fake newlines, lol
	output = strings.Replace(output, "\\n", "", -1)

	// chomp off trailing newlines
	output = strings.Trim(output, "\n")

	// trim spaces
	output = strings.TrimSpace(output)

	return
}
<|endoftext|>


<commit_before>package scheduler

import (
	"fmt"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func test() {}

func TestExecution(t *testing.T) {
	c := make(chan bool)
	fn := func() {
		c <- true
	}
	job, err := Every(1).Seconds().Run(fn)
	assert.Nil(t, err)
	assert.NotNil(t, job)
	select {
	case <-c:
	case <-time.After(2 * time.Second):
		t.Error("Didn't Execute")
	}
}

func TestDoNotWait(t *testing.T) {
	c := make(chan bool)
	fn := func() {
		c <- true
	}
	job, err := Every(2).Seconds().Run(fn)
	assert.Nil(t, err)
	assert.NotNil(t, job)
	job.SkipWait <- true
	select {
	case <-c:
	case <-time.After(1 * time.Second):
		t.Error("Didn't Execute")
	}
}

func TestCancelExecution(t *testing.T) {
	c := make(chan bool)
	fn := func() {
		c <- true
	}
	job, err := Every(1).Seconds().Run(fn)
	assert.Nil(t, err)
	assert.NotNil(t, job)
	job.Quit <- true
	select {
	case <-c:
		t.Error("Shouldn't have Execute")
	case <-time.After(2 * time.Second):
	}
}

func testDay(t *testing.T, job *Job, err error, date time.Time, hour, min, sec int) {
	assert.Nil(t, err)

	actual, err := job.schedule.nextRun()
	assert.Nil(t, err)
	runTime := time.Now().Add(actual)
	assert.Equal(t, date.Day(), runTime.Day())
	assert.Equal(t, date.Month(), runTime.Month())
	assert.Equal(t, date.Year(), runTime.Year())
	assert.Equal(t, hour, runTime.Hour())
	assert.Equal(t, min, runTime.Minute())
	assert.Equal(t, sec, runTime.Second())
}

func TestEveryDay(t *testing.T) {
	job, err := Every().Day().Run(test)
	testDay(t, job, err, time.Now().AddDate(0, 0, 1), 0, 0, 0)
}

func TestEveryAtAfter(t *testing.T) {
	tAdd := time.Now().Add(1 * time.Second)
	h := tAdd.Hour()
	m := tAdd.Minute()
	s := tAdd.Second()
	hourStr := fmt.Sprintf("%v:%v:%v", h, m, s)
	job, err := Every().Day().At(hourStr).Run(test)
	testDay(t, job, err, time.Now(), h, m, s)
}

func TestEveryAtBefore(t *testing.T) {
	tAdd := time.Now().Add(-1 * time.Second)
	h := tAdd.Hour()
	m := tAdd.Minute()
	s := tAdd.Second()
	hourStr := fmt.Sprintf("%v:%v:%v", h, m, s)
	job, err := Every().Day().At(hourStr).Run(test)
	testDay(t, job, err, time.Now().AddDate(0, 0, 1), h, m, s)
}

func TestEveryAtHour(t *testing.T) {
	hourStr := "08"
	job, err := Every().Day().At(hourStr).Run(test)
	assert.Nil(t, err)
	actual, err := job.schedule.nextRun()
	assert.Nil(t, err)
	runTime := time.Now().Add(actual)
	assert.Equal(t, 8, runTime.Hour())
	assert.Equal(t, 0, runTime.Minute())
	assert.Equal(t, 0, runTime.Second())
}

func TestEveryAtHourMin(t *testing.T) {
	hourStr := "08:30"
	job, err := Every().Day().At(hourStr).Run(test)
	assert.Nil(t, err)
	actual, err := job.schedule.nextRun()
	assert.Nil(t, err)
	runTime := time.Now().Add(actual)
	assert.Equal(t, 8, runTime.Hour())
	assert.Equal(t, 30, runTime.Minute())
	assert.Equal(t, 0, runTime.Second())
}

func testWeekday(t *testing.T, job *Job, weekday time.Weekday) {
	actual, err := job.schedule.nextRun()
	assert.Nil(t, err)
	runTime := time.Now().Add(actual)
	assert.Equal(t, weekday, runTime.Weekday())
	assert.Equal(t, 0, runTime.Hour())
	assert.Equal(t, 0, runTime.Minute())
	assert.Equal(t, 0, runTime.Second())

}

func TestEveryAtWeeklyAfter(t *testing.T) {
	tAdd := time.Now().Add(1 * time.Second)
	h := tAdd.Hour()
	m := tAdd.Minute()
	s := tAdd.Second()
	hourStr := fmt.Sprintf("%v:%v:%v", h, m, s)
	job, err := Every().Monday().At(hourStr).Run(test)
	assert.Nil(t, err)
	actual, err := job.schedule.nextRun()
	assert.Nil(t, err)
	runTime := time.Now().Add(actual)
	assert.Equal(t, time.Monday, runTime.Weekday())
	assert.Equal(t, h, runTime.Hour())
	assert.Equal(t, m, runTime.Minute())
	assert.Equal(t, s, runTime.Second())
}

func TestEveryAtWeeklyBefore(t *testing.T) {
	tAdd := time.Now().Add(-1 * time.Second)
	h := tAdd.Hour()
	m := tAdd.Minute()
	s := tAdd.Second()
	hourStr := fmt.Sprintf("%v:%v:%v", h, m, s)
	job, err := Every().Monday().At(hourStr).Run(test)
	assert.Nil(t, err)
	actual, err := job.schedule.nextRun()
	assert.Nil(t, err)
	runTime := time.Now().Add(actual)
	assert.Equal(t, time.Monday, runTime.Weekday())
	assert.Equal(t, h, runTime.Hour())
	assert.Equal(t, m, runTime.Minute())
	assert.Equal(t, s, runTime.Second())
}

func TestBadAtStr1(t *testing.T) {
	job, err := Every().Monday().At("0A:30:00").Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadAtStr2(t *testing.T) {
	job, err := Every().Monday().At("00:3A:00").Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadAtStr3(t *testing.T) {
	job, err := Every().Monday().At("00:30:0A").Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadAtStr4(t *testing.T) {
	job, err := Every().Monday().At("25:30:00").Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadChain1(t *testing.T) {
	job, err := Every(1).Day().At("1").Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadChain2(t *testing.T) {
	job, err := Every(1).Day().Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadChain3(t *testing.T) {
	job, err := Every(1).Seconds().At("08:00:00").Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadChain4(t *testing.T) {
	job, err := Every(1).Seconds().Monday().Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadEvery(t *testing.T) {
	job, err := Every(1, 2).Seconds().Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestEveryMonday(t *testing.T) {
	job, err := Every().Monday().Run(test)
	assert.Nil(t, err)
	testWeekday(t, job, time.Monday)
}

func TestEveryTuesday(t *testing.T) {
	job, err := Every().Tuesday().Run(test)
	assert.Nil(t, err)
	testWeekday(t, job, time.Tuesday)
}

func TestEveryWednesday(t *testing.T) {
	job, err := Every().Wednesday().Run(test)
	assert.Nil(t, err)
	testWeekday(t, job, time.Wednesday)
}

func TestEveryThursday(t *testing.T) {
	job, err := Every().Thursday().Run(test)
	assert.Nil(t, err)
	testWeekday(t, job, time.Thursday)
}

func TestEveryFriday(t *testing.T) {
	job, err := Every().Friday().Run(test)
	assert.Nil(t, err)
	testWeekday(t, job, time.Friday)
}

func TestEverySaturday(t *testing.T) {
	job, err := Every().Saturday().Run(test)
	assert.Nil(t, err)
	testWeekday(t, job, time.Saturday)
}

func TestEverySunday(t *testing.T) {
	job, err := Every().Sunday().Run(test)
	assert.Nil(t, err)
	testWeekday(t, job, time.Sunday)
}

func testEveryX(t *testing.T, job *Job, expected time.Duration) {
	actual, err := job.schedule.nextRun()
	assert.Nil(t, err)
	assert.Equal(t, 0, actual)
	actual, err = job.schedule.nextRun()
	assert.Nil(t, err)
	assert.Equal(t, expected, actual)
}

func TestEverySeconds(t *testing.T) {
	var units int
	units = 3
	expected := 3 * time.Second
	job := Every(units).Seconds()
	testEveryX(t, job, expected)
}
func TestEveryMinutes(t *testing.T) {
	var units int
	units = 3
	expected := 3 * time.Minute
	job := Every(units).Minutes()
	testEveryX(t, job, expected)
}
func TestEveryHours(t *testing.T) {
	var units int
	units = 3
	expected := 3 * time.Hour
	job := Every(units).Hours()
	testEveryX(t, job, expected)
}
func TestBadRecurrent(t *testing.T) {
	var units int
	units = 0
	job, err := Every(units).Seconds().Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}
<commit_msg>Change test nextRun expected to time.Duration<commit_after>package scheduler

import (
	"fmt"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
)

func test() {}

func TestExecution(t *testing.T) {
	c := make(chan bool)
	fn := func() {
		c <- true
	}
	job, err := Every(1).Seconds().Run(fn)
	assert.Nil(t, err)
	assert.NotNil(t, job)
	select {
	case <-c:
	case <-time.After(2 * time.Second):
		t.Error("Didn't Execute")
	}
}

func TestDoNotWait(t *testing.T) {
	c := make(chan bool)
	fn := func() {
		c <- true
	}
	job, err := Every(2).Seconds().Run(fn)
	assert.Nil(t, err)
	assert.NotNil(t, job)
	job.SkipWait <- true
	select {
	case <-c:
	case <-time.After(1 * time.Second):
		t.Error("Didn't Execute")
	}
}

func TestCancelExecution(t *testing.T) {
	c := make(chan bool)
	fn := func() {
		c <- true
	}
	job, err := Every(1).Seconds().Run(fn)
	assert.Nil(t, err)
	assert.NotNil(t, job)
	job.Quit <- true
	select {
	case <-c:
		t.Error("Shouldn't have Execute")
	case <-time.After(2 * time.Second):
	}
}

func testDay(t *testing.T, job *Job, err error, date time.Time, hour, min, sec int) {
	assert.Nil(t, err)

	actual, err := job.schedule.nextRun()
	assert.Nil(t, err)
	runTime := time.Now().Add(actual)
	assert.Equal(t, date.Day(), runTime.Day())
	assert.Equal(t, date.Month(), runTime.Month())
	assert.Equal(t, date.Year(), runTime.Year())
	assert.Equal(t, hour, runTime.Hour())
	assert.Equal(t, min, runTime.Minute())
	assert.Equal(t, sec, runTime.Second())
}

func TestEveryDay(t *testing.T) {
	job, err := Every().Day().Run(test)
	testDay(t, job, err, time.Now().AddDate(0, 0, 1), 0, 0, 0)
}

func TestEveryAtAfter(t *testing.T) {
	tAdd := time.Now().Add(1 * time.Second)
	h := tAdd.Hour()
	m := tAdd.Minute()
	s := tAdd.Second()
	hourStr := fmt.Sprintf("%v:%v:%v", h, m, s)
	job, err := Every().Day().At(hourStr).Run(test)
	testDay(t, job, err, time.Now(), h, m, s)
}

func TestEveryAtBefore(t *testing.T) {
	tAdd := time.Now().Add(-1 * time.Second)
	h := tAdd.Hour()
	m := tAdd.Minute()
	s := tAdd.Second()
	hourStr := fmt.Sprintf("%v:%v:%v", h, m, s)
	job, err := Every().Day().At(hourStr).Run(test)
	testDay(t, job, err, time.Now().AddDate(0, 0, 1), h, m, s)
}

func TestEveryAtHour(t *testing.T) {
	hourStr := "08"
	job, err := Every().Day().At(hourStr).Run(test)
	assert.Nil(t, err)
	actual, err := job.schedule.nextRun()
	assert.Nil(t, err)
	runTime := time.Now().Add(actual)
	assert.Equal(t, 8, runTime.Hour())
	assert.Equal(t, 0, runTime.Minute())
	assert.Equal(t, 0, runTime.Second())
}

func TestEveryAtHourMin(t *testing.T) {
	hourStr := "08:30"
	job, err := Every().Day().At(hourStr).Run(test)
	assert.Nil(t, err)
	actual, err := job.schedule.nextRun()
	assert.Nil(t, err)
	runTime := time.Now().Add(actual)
	assert.Equal(t, 8, runTime.Hour())
	assert.Equal(t, 30, runTime.Minute())
	assert.Equal(t, 0, runTime.Second())
}

func testWeekday(t *testing.T, job *Job, weekday time.Weekday) {
	actual, err := job.schedule.nextRun()
	assert.Nil(t, err)
	runTime := time.Now().Add(actual)
	assert.Equal(t, weekday, runTime.Weekday())
	assert.Equal(t, 0, runTime.Hour())
	assert.Equal(t, 0, runTime.Minute())
	assert.Equal(t, 0, runTime.Second())

}

func TestEveryAtWeeklyAfter(t *testing.T) {
	tAdd := time.Now().Add(1 * time.Second)
	h := tAdd.Hour()
	m := tAdd.Minute()
	s := tAdd.Second()
	hourStr := fmt.Sprintf("%v:%v:%v", h, m, s)
	job, err := Every().Monday().At(hourStr).Run(test)
	assert.Nil(t, err)
	actual, err := job.schedule.nextRun()
	assert.Nil(t, err)
	runTime := time.Now().Add(actual)
	assert.Equal(t, time.Monday, runTime.Weekday())
	assert.Equal(t, h, runTime.Hour())
	assert.Equal(t, m, runTime.Minute())
	assert.Equal(t, s, runTime.Second())
}

func TestEveryAtWeeklyBefore(t *testing.T) {
	tAdd := time.Now().Add(-1 * time.Second)
	h := tAdd.Hour()
	m := tAdd.Minute()
	s := tAdd.Second()
	hourStr := fmt.Sprintf("%v:%v:%v", h, m, s)
	job, err := Every().Monday().At(hourStr).Run(test)
	assert.Nil(t, err)
	actual, err := job.schedule.nextRun()
	assert.Nil(t, err)
	runTime := time.Now().Add(actual)
	assert.Equal(t, time.Monday, runTime.Weekday())
	assert.Equal(t, h, runTime.Hour())
	assert.Equal(t, m, runTime.Minute())
	assert.Equal(t, s, runTime.Second())
}

func TestBadAtStr1(t *testing.T) {
	job, err := Every().Monday().At("0A:30:00").Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadAtStr2(t *testing.T) {
	job, err := Every().Monday().At("00:3A:00").Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadAtStr3(t *testing.T) {
	job, err := Every().Monday().At("00:30:0A").Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadAtStr4(t *testing.T) {
	job, err := Every().Monday().At("25:30:00").Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadChain1(t *testing.T) {
	job, err := Every(1).Day().At("1").Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadChain2(t *testing.T) {
	job, err := Every(1).Day().Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadChain3(t *testing.T) {
	job, err := Every(1).Seconds().At("08:00:00").Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadChain4(t *testing.T) {
	job, err := Every(1).Seconds().Monday().Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestBadEvery(t *testing.T) {
	job, err := Every(1, 2).Seconds().Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}

func TestEveryMonday(t *testing.T) {
	job, err := Every().Monday().Run(test)
	assert.Nil(t, err)
	testWeekday(t, job, time.Monday)
}

func TestEveryTuesday(t *testing.T) {
	job, err := Every().Tuesday().Run(test)
	assert.Nil(t, err)
	testWeekday(t, job, time.Tuesday)
}

func TestEveryWednesday(t *testing.T) {
	job, err := Every().Wednesday().Run(test)
	assert.Nil(t, err)
	testWeekday(t, job, time.Wednesday)
}

func TestEveryThursday(t *testing.T) {
	job, err := Every().Thursday().Run(test)
	assert.Nil(t, err)
	testWeekday(t, job, time.Thursday)
}

func TestEveryFriday(t *testing.T) {
	job, err := Every().Friday().Run(test)
	assert.Nil(t, err)
	testWeekday(t, job, time.Friday)
}

func TestEverySaturday(t *testing.T) {
	job, err := Every().Saturday().Run(test)
	assert.Nil(t, err)
	testWeekday(t, job, time.Saturday)
}

func TestEverySunday(t *testing.T) {
	job, err := Every().Sunday().Run(test)
	assert.Nil(t, err)
	testWeekday(t, job, time.Sunday)
}

func testEveryX(t *testing.T, job *Job, expected time.Duration) {
	actual, err := job.schedule.nextRun()
	assert.Nil(t, err)
	assert.Equal(t, time.Duration(0), actual)
	actual, err = job.schedule.nextRun()
	assert.Nil(t, err)
	assert.Equal(t, expected, actual)
}

func TestEverySeconds(t *testing.T) {
	var units int
	units = 3
	expected := 3 * time.Second
	job := Every(units).Seconds()
	testEveryX(t, job, expected)
}
func TestEveryMinutes(t *testing.T) {
	var units int
	units = 3
	expected := 3 * time.Minute
	job := Every(units).Minutes()
	testEveryX(t, job, expected)
}
func TestEveryHours(t *testing.T) {
	var units int
	units = 3
	expected := 3 * time.Hour
	job := Every(units).Hours()
	testEveryX(t, job, expected)
}
func TestBadRecurrent(t *testing.T) {
	var units int
	units = 0
	job, err := Every(units).Seconds().Run(test)
	assert.Nil(t, job)
	assert.NotNil(t, err)
}
<|endoftext|>


<commit_before>package wiki

import (
	"fmt"
	"math/rand"
	"regexp"
	"strings"
	"time"

	"cgt.name/pkg/go-mwclient"
	"github.com/erbridge/gotwit"
)

type (
	Client struct {
		bot    *gotwit.Bot
		wiki   *mwclient.Client
		ticker *time.Ticker
	}
)

func NewClient(bot *gotwit.Bot) (client Client, err error) {
	// TODO: Add contact details to the user agent.
	wiki, err := mwclient.New("https://en.wikipedia.org/w/api.php", "Wikipaedian")

	if err != nil {
		return
	}

	client = Client{
		bot:  bot,
		wiki: wiki,
	}

	return
}

func (c *Client) Start(d time.Duration) {
	c.ticker = time.NewTicker(d)
	defer c.ticker.Stop()

	c.Post()

	for range c.ticker.C {
		c.Post()
	}
}

func (c *Client) Post() {
	last := c.LastPost()

	if last == "" {
		c.bot.Post("[[\"Hello, World!\" program|Hello World!]]", false)

		return
	}

	page, _ := c.Page(last)

	content := c.CreatePost(page)

	fmt.Println(content)

	// c.bot.Post(content, false)
}

func (c *Client) LastPost() string {
	if text, err := c.bot.LastTweetText(); err != nil {
		panic(err)
	} else {
		return text
	}

	return ""
}

func (c *Client) Page(last string) (content, timestamp string) {
	re := regexp.MustCompile("\\[{2}([^:]+?)\\]{2}")

	matches := re.FindAllStringSubmatch(last, -1)

	// FIXME: Handle the 0 match state.
	title := matches[rand.Intn(len(matches))][1]

	re = regexp.MustCompile("(.+?)\\|")

	match := re.FindStringSubmatch(title)

	if len(match) > 0 {
		title = match[1]
	}

	content, timestamp, err := c.wiki.GetPageByName(title)

	if err != nil {
		panic(err)
	}

	return
}

func (c *Client) CreatePost(page string) (content string) {
	re := regexp.MustCompile("[.!?][[:space:]]+" +
		"(" +
		"(" +
		"([^{^}^\\[^\\]^<^>]+?[[:space:]]+?)+?" +
		")" +
		"(\\[{2}[^:]+?\\]{2})" +
		"(" +
		"([[:space:]]+?[^{^}^\\[^\\]^<^>]+?)+?" +
		")" +
		"([.!?])" +
		")" +
		"[[:space:]]+",
	)

	matches := re.FindAllStringSubmatch(page, -1)

	// FIXME: Handle the 0 match state.
	match := matches[rand.Intn(len(matches))]

	content = match[1]

	if len(content) <= 140 {
		return
	}

	content = match[4]

	if len(content) > 138 {
		re = regexp.MustCompile("\\[{2}[^:]+?\\]{2}")

		matches := re.FindAllString(content, -1)

		// FIXME: Handle the 0 match state.
		content = matches[rand.Intn(len(matches))]
	}

	before, after := strings.Split(match[2], " "), strings.Split(match[5], " ")

	newContent := content

	for len(newContent) < 138 {
		content = newContent

		word := ""

		if len(before) > 0 && rand.Float32() > 0.5 {
			word, before = before[len(before)-1], before[:len(before)-1]

			if word == "" {
				continue
			}

			newContent = word + " " + content
		} else if len(after) > 0 {
			word, after = after[0], after[1:]

			if word == "" {
				continue
			}

			newContent = content + " " + word
		} else {
			break
		}
	}

	if len(before) > 0 {
		content = "…" + content
	}

	if len(after) > 0 {
		content += "…"
	} else {
		content += match[7]
	}

	return
}
<commit_msg>Privatize some of the wiki methods<commit_after>package wiki

import (
	"fmt"
	"math/rand"
	"regexp"
	"strings"
	"time"

	"cgt.name/pkg/go-mwclient"
	"github.com/erbridge/gotwit"
)

type (
	Client struct {
		bot    *gotwit.Bot
		wiki   *mwclient.Client
		ticker *time.Ticker
	}
)

func NewClient(bot *gotwit.Bot) (client Client, err error) {
	// TODO: Add contact details to the user agent.
	wiki, err := mwclient.New("https://en.wikipedia.org/w/api.php", "Wikipaedian")

	if err != nil {
		return
	}

	client = Client{
		bot:  bot,
		wiki: wiki,
	}

	return
}

func (c *Client) Start(d time.Duration) {
	c.ticker = time.NewTicker(d)
	defer c.ticker.Stop()

	c.post()

	for range c.ticker.C {
		c.post()
	}
}

func (c *Client) post() {
	last := c.lastPost()

	if last == "" {
		c.bot.Post("[[\"Hello, World!\" program|Hello World!]]", false)

		return
	}

	page, _ := c.page(last)

	content := c.createPost(page)

	fmt.Println(content)

	// c.bot.Post(content, false)
}

func (c *Client) lastPost() string {
	if text, err := c.bot.LastTweetText(); err != nil {
		panic(err)
	} else {
		return text
	}

	return ""
}

func (c *Client) page(last string) (content, timestamp string) {
	re := regexp.MustCompile("\\[{2}([^:]+?)\\]{2}")

	matches := re.FindAllStringSubmatch(last, -1)

	// FIXME: Handle the 0 match state.
	title := matches[rand.Intn(len(matches))][1]

	re = regexp.MustCompile("(.+?)\\|")

	match := re.FindStringSubmatch(title)

	if len(match) > 0 {
		title = match[1]
	}

	content, timestamp, err := c.wiki.GetPageByName(title)

	if err != nil {
		panic(err)
	}

	return
}

func (c *Client) createPost(page string) (content string) {
	re := regexp.MustCompile("[.!?][[:space:]]+" +
		"(" +
		"(" +
		"([^{^}^\\[^\\]^<^>]+?[[:space:]]+?)+?" +
		")" +
		"(\\[{2}[^:]+?\\]{2})" +
		"(" +
		"([[:space:]]+?[^{^}^\\[^\\]^<^>]+?)+?" +
		")" +
		"([.!?])" +
		")" +
		"[[:space:]]+",
	)

	matches := re.FindAllStringSubmatch(page, -1)

	// FIXME: Handle the 0 match state.
	match := matches[rand.Intn(len(matches))]

	content = match[1]

	if len(content) <= 140 {
		return
	}

	content = match[4]

	if len(content) > 138 {
		re = regexp.MustCompile("\\[{2}[^:]+?\\]{2}")

		matches := re.FindAllString(content, -1)

		// FIXME: Handle the 0 match state.
		content = matches[rand.Intn(len(matches))]
	}

	before, after := strings.Split(match[2], " "), strings.Split(match[5], " ")

	newContent := content

	for len(newContent) < 138 {
		content = newContent

		word := ""

		if len(before) > 0 && rand.Float32() > 0.5 {
			word, before = before[len(before)-1], before[:len(before)-1]

			if word == "" {
				continue
			}

			newContent = word + " " + content
		} else if len(after) > 0 {
			word, after = after[0], after[1:]

			if word == "" {
				continue
			}

			newContent = content + " " + word
		} else {
			break
		}
	}

	if len(before) > 0 {
		content = "…" + content
	}

	if len(after) > 0 {
		content += "…"
	} else {
		content += match[7]
	}

	return
}
<|endoftext|>


<commit_before>package object

import (
	"bytes"
	"encoding/gob"
	"encoding/json"
	"encoding/xml"
	"github.com/TShadwell/jsarray"
	htmltemplate "html/template"
	"log"
	"math/rand"
	"net/http"
	"path"
	texttemplate "text/template"
	"time"
)

type ContentMarshaler map[MediaType]MarshalFunc

type MarshalFunc func(v interface{}, rq *http.Request, m MediaType,
	params map[string]string) (data []byte, contentType string, err error)

//HTMLTemplate returns a MarshalFunc that executes the data on template `t` using the html/template
//package
func HTMLTemplate(t *htmltemplate.Template) MarshalFunc {
	return func(v interface{}, _ *http.Request, _ MediaType,
		_ map[string]string) (data []byte, contentType string, err error) {
		contentType = "text/html;charset=utf8"
		var bf bytes.Buffer
		err = t.Execute(&bf, v)
		if err != nil {
			return
		}
		data = bf.Bytes()
		return
	}
}

//Parameters is the value that ExtendParameters passes to its wrapped MarshalFunc.
type Parameters struct {
	Request *http.Request
	MediaType
	Params map[string]string
	Value  interface{}
}

func ExtendParameters(mf MarshalFunc) MarshalFunc {
	return func(v interface{}, rq *http.Request, m MediaType,
		params map[string]string) (data []byte, contentType string, err error) {

		return mf(
			Parameters{
				Request:   rq,
				MediaType: m,
				Params:    params,
				Value:     v,
			},
			rq,
			m,
			params,
		)

	}
}

//TextTemplate returns a MarshalFunc that executes the data on template `t` using the text/template
//package.
func TextTemplate(t *texttemplate.Template) MarshalFunc {
	return func(v interface{}, _ *http.Request, _ MediaType,
		_ map[string]string) (data []byte, contentType string, err error) {
		contentType = "text/plain;charset=utf8"
		var bf bytes.Buffer
		err = t.Execute(&bf, v)
		if err != nil {
			return
		}
		data = bf.Bytes()
		return
	}
}

var Json MarshalFunc = func(v interface{}, _ *http.Request, _ MediaType,
	_ map[string]string) (data []byte, contentType string, err error) {
	contentType = "application/json;charset=utf8"
	data, err = json.Marshal(v)

	return
}

var Xml MarshalFunc = func(v interface{}, _ *http.Request, _ MediaType,
	_ map[string]string) (data []byte, contentType string, err error) {

	contentType = "application/xml;charset=utf8"
	data, err = xml.Marshal(v)
	return
}

var nullbytes = []byte("null")

//See github.com/TShadwell/jsarray for details.
var JsonArray MarshalFunc = func(v interface{}, _ *http.Request, _ MediaType,
	_ map[string]string) (data []byte, contentType string, err error) {

	contentType = "application/json;charset=utf8"
	data, err = jsarray.Marshal(v)
	return
}

//Plaintext. The underlying value of v must be string.
var Plain MarshalFunc = func(v interface{}, _ *http.Request, _ MediaType,
	_ map[string]string) ([]byte, string, error) {
	return []byte(v.(string)), "text/plain", nil
}
const planesStr string = "🛧🛪🛨🛦🛫🛩"

var planes = []rune(planesStr)
var nPlanes int

//Planetext.
//
//🛧🛪🛨🛦🛫🛦 🛫🛨 🛨✈🛦🛧🛦 ✈🛬🛫🛫🛬🛫 🛩🛦✈🛩🛬🛬🛨 🛫 🛬🛨✈ 🛩 🛨
var Plane MarshalFunc = func(v interface{}, _ *http.Request, _ MediaType,
	_ map[string]string) (bt []byte, st string, err error) {

	rand.Seed(time.Now().Unix())

	st = "text/plane"

	rn := make([]rune, 0, 100)
	for i, ed := 0, cap(bt);i<ed;i++ {
		rn[i] = planes[rand.Intn(nPlanes)]
	}

	bt = []byte(string(rn))

	return
}

var Gob MarshalFunc = func(v interface{}, _ *http.Request, _ MediaType,
	_ map[string]string) (data []byte, contentType string, err error) {

	contentType = "application/gob"
	var buf bytes.Buffer
	err = gob.NewEncoder(&buf).Encode(v)
	if err != nil {
		return
	}

	data = buf.Bytes()
	return
}

//Marshaler returns the MarshalFunc present in c that matches one of the
//ContentTypes with pattern matching (text/*) in order of preference,
//as well as the chosen ContentType.
//If mf is nil ct may be some random data.
func (c ContentMarshaler) Marshaler(cts ...ContentType) (mf MarshalFunc, ct ContentType) {
	var k MediaType
	for _, ct = range cts {
		patt := restricted(string(ct.MediaType))
		for k, mf = range c {
			if ok, _ := path.Match(patt, string(k)); ok {
				return
			}
		}
	}
	mf = nil
	return
}

func Marshaler(cs []ContentMarshaler, cts ...ContentType) (mf MarshalFunc, ct ContentType) {
	var k MediaType
	for _, ct = range cts {
		patt := restricted(string(ct.MediaType))
		for _, c := range cs {
			for k, mf = range c {
				if k != "" {
					if ok, _ := path.Match(patt, string(k)); ok {
						return
					}
				}
			}
		}
	}
	mf = nil
	return
}

//RequestMarshalFunc returns the MarshalFunc mf that matches the *http.Request rq,
//as well as the selected ContentType.
//The extension of the request path is assumed to be the most preferable MIME type.
func (c ContentMarshaler) RequestMarshaler(r *http.Request) (mf MarshalFunc, ct ContentType) {
	types, _ := ParseContentType(r.Header.Get("Accept"))
	if m := pathMime(r.URL.Path); m != "" {
		types = []ContentType{{MediaType: MediaType(m)}}
	}

	return c.Marshaler(types...)
}

//RequestMarshaler returns the first MarshalFunc mf that matches the MIME types specified in
//the *http.Request from the []ContentMarshaler cs in order of preference, as well as the selected ContentType.
//The extension of the request path is assumed to be the most preferable MIME type.
func RequestMarshaler(r *http.Request, cs ...ContentMarshaler) (mf MarshalFunc, c ContentType) {
	types, _ := ParseContentType(r.Header.Get("Accept"))
	if debug {
		log.Printf("%+v", r.Header.Get("Accept"))
	}
	if m := pathMime(r.URL.Path); m != "" {
		a, b := pmt(m)
		types = append([]ContentType{{a, b}}, types...)
		if debug {
			log.Printf("%+v", types)
		}
	}

	mf, c = Marshaler(cs, types...)
	return

}

func init() {
	nPlanes = len(planes)
}
<commit_msg>fix text/plane<commit_after>package object

import (
	"bytes"
	"encoding/gob"
	"encoding/json"
	"encoding/xml"
	"github.com/TShadwell/jsarray"
	htmltemplate "html/template"
	"log"
	"math/rand"
	"net/http"
	"path"
	texttemplate "text/template"
	"time"
)

type ContentMarshaler map[MediaType]MarshalFunc

type MarshalFunc func(v interface{}, rq *http.Request, m MediaType,
	params map[string]string) (data []byte, contentType string, err error)

//HTMLTemplate returns a MarshalFunc that executes the data on template `t` using the html/template
//package
func HTMLTemplate(t *htmltemplate.Template) MarshalFunc {
	return func(v interface{}, _ *http.Request, _ MediaType,
		_ map[string]string) (data []byte, contentType string, err error) {
		contentType = "text/html;charset=utf8"
		var bf bytes.Buffer
		err = t.Execute(&bf, v)
		if err != nil {
			return
		}
		data = bf.Bytes()
		return
	}
}

//Parameters is the value that ExtendParameters passes to its wrapped MarshalFunc.
type Parameters struct {
	Request *http.Request
	MediaType
	Params map[string]string
	Value  interface{}
}

func ExtendParameters(mf MarshalFunc) MarshalFunc {
	return func(v interface{}, rq *http.Request, m MediaType,
		params map[string]string) (data []byte, contentType string, err error) {

		return mf(
			Parameters{
				Request:   rq,
				MediaType: m,
				Params:    params,
				Value:     v,
			},
			rq,
			m,
			params,
		)

	}
}

//TextTemplate returns a MarshalFunc that executes the data on template `t` using the text/template
//package.
func TextTemplate(t *texttemplate.Template) MarshalFunc {
	return func(v interface{}, _ *http.Request, _ MediaType,
		_ map[string]string) (data []byte, contentType string, err error) {
		contentType = "text/plain;charset=utf8"
		var bf bytes.Buffer
		err = t.Execute(&bf, v)
		if err != nil {
			return
		}
		data = bf.Bytes()
		return
	}
}

var Json MarshalFunc = func(v interface{}, _ *http.Request, _ MediaType,
	_ map[string]string) (data []byte, contentType string, err error) {
	contentType = "application/json;charset=utf8"
	data, err = json.Marshal(v)

	return
}

var Xml MarshalFunc = func(v interface{}, _ *http.Request, _ MediaType,
	_ map[string]string) (data []byte, contentType string, err error) {

	contentType = "application/xml;charset=utf8"
	data, err = xml.Marshal(v)
	return
}

var nullbytes = []byte("null")

//See github.com/TShadwell/jsarray for details.
var JsonArray MarshalFunc = func(v interface{}, _ *http.Request, _ MediaType,
	_ map[string]string) (data []byte, contentType string, err error) {

	contentType = "application/json;charset=utf8"
	data, err = jsarray.Marshal(v)
	return
}

//Plaintext. The underlying value of v must be string.
var Plain MarshalFunc = func(v interface{}, _ *http.Request, _ MediaType,
	_ map[string]string) ([]byte, string, error) {
	return []byte(v.(string)), "text/plain", nil
}
const planesStr string = "🛧🛪🛨🛦🛫🛩"

var planes = []rune(planesStr)
var nPlanes int

//Planetext.
//
//🛧🛪🛨🛦🛫🛦 🛫🛨 🛨✈🛦🛧🛦 ✈🛬🛫🛫🛬🛫 🛩🛦✈🛩🛬🛬🛨 🛫 🛬🛨✈ 🛩 🛨
var Plane MarshalFunc = func(v interface{}, _ *http.Request, _ MediaType,
	_ map[string]string) (bt []byte, st string, err error) {

	rand.Seed(time.Now().Unix())

	st = "text/plane"

	rn := make([]rune, 100)
	for i, ed := 0, cap(rn);i<ed;i++ {
		rn[i] = planes[rand.Intn(nPlanes)]
	}

	bt = []byte(string(rn))

	return
}

var Gob MarshalFunc = func(v interface{}, _ *http.Request, _ MediaType,
	_ map[string]string) (data []byte, contentType string, err error) {

	contentType = "application/gob"
	var buf bytes.Buffer
	err = gob.NewEncoder(&buf).Encode(v)
	if err != nil {
		return
	}

	data = buf.Bytes()
	return
}

//Marshaler returns the MarshalFunc present in c that matches one of the
//ContentTypes with pattern matching (text/*) in order of preference,
//as well as the chosen ContentType.
//If mf is nil ct may be some random data.
func (c ContentMarshaler) Marshaler(cts ...ContentType) (mf MarshalFunc, ct ContentType) {
	var k MediaType
	for _, ct = range cts {
		patt := restricted(string(ct.MediaType))
		for k, mf = range c {
			if ok, _ := path.Match(patt, string(k)); ok {
				return
			}
		}
	}
	mf = nil
	return
}

func Marshaler(cs []ContentMarshaler, cts ...ContentType) (mf MarshalFunc, ct ContentType) {
	var k MediaType
	for _, ct = range cts {
		patt := restricted(string(ct.MediaType))
		for _, c := range cs {
			for k, mf = range c {
				if k != "" {
					if ok, _ := path.Match(patt, string(k)); ok {
						return
					}
				}
			}
		}
	}
	mf = nil
	return
}

//RequestMarshalFunc returns the MarshalFunc mf that matches the *http.Request rq,
//as well as the selected ContentType.
//The extension of the request path is assumed to be the most preferable MIME type.
func (c ContentMarshaler) RequestMarshaler(r *http.Request) (mf MarshalFunc, ct ContentType) {
	types, _ := ParseContentType(r.Header.Get("Accept"))
	if m := pathMime(r.URL.Path); m != "" {
		types = []ContentType{{MediaType: MediaType(m)}}
	}

	return c.Marshaler(types...)
}

//RequestMarshaler returns the first MarshalFunc mf that matches the MIME types specified in
//the *http.Request from the []ContentMarshaler cs in order of preference, as well as the selected ContentType.
//The extension of the request path is assumed to be the most preferable MIME type.
func RequestMarshaler(r *http.Request, cs ...ContentMarshaler) (mf MarshalFunc, c ContentType) {
	types, _ := ParseContentType(r.Header.Get("Accept"))
	if debug {
		log.Printf("%+v", r.Header.Get("Accept"))
	}
	if m := pathMime(r.URL.Path); m != "" {
		a, b := pmt(m)
		types = append([]ContentType{{a, b}}, types...)
		if debug {
			log.Printf("%+v", types)
		}
	}

	mf, c = Marshaler(cs, types...)
	return

}

func init() {
	nPlanes = len(planes)
}
<|endoftext|>


<commit_before>package accessor

// Accessor provides getter/setter to the object.
type Accessor interface {
	// Get finds a object at specific path.
	// NoSuchPathError is returned when no object was found in the path.
	Get(path string, paths ...string) (Accessor, error)

	// Set set a object into specific path.
	// NoSuchPathError is returned when the path is invalid.
	Set(value interface{}, path string, paths ...string) error

	// Unwrap unwraps the object and returns actual value.
	Unwrap() interface{}
}

func NewAccessor(acc interface{}) (Accessor, error) {
	if a, ok := acc.(Accessor); ok {
		return a, nil
	}

	switch t := acc.(type) {
	case map[string]interface{}:
		ma := map[string]Accessor{}
		for k, v := range t {
			o, err := NewAccessor(v)
			if err != nil {
				return nil, err
			}
			ma[k] = o
		}
		return MapAccessor(ma), nil
	case map[interface{}]interface{}:
		ma := map[string]Accessor{}
		for k, v := range t {
			key, ok := k.(string)
			if !ok {
				return nil, NewInvalidKeyError(k)
			}
			o, err := NewAccessor(v)
			if err != nil {
				return nil, err
			}
			ma[key] = o
		}
		return MapAccessor(ma), nil
	case []interface{}:
		sa := make([]Accessor, len(t))
		for i, v := range t {
			o, err := NewAccessor(v)
			if err != nil {
				return nil, err
			}
			sa[i] = o
		}
		return SliceAccessor(sa), nil
	default:
		return ValueAccessor{t}, nil
	}
}
<commit_msg>Update definition of Accessor<commit_after>package accessor

// Accessor provides getter/setter to the object.
type Accessor interface {
	// Get finds a object at specific path.
	// NoSuchPathError is returned when no object was found in the path.
	Get(path Path) (Accessor, error)

	// Set set a object into specific path.
	// NoSuchPathError is returned when the path is invalid.
	Set(value interface{}, path Path) error

	// Unwrap unwraps the object and returns actual value.
	Unwrap() interface{}
}

func NewAccessor(acc interface{}) (Accessor, error) {
	if a, ok := acc.(Accessor); ok {
		return a, nil
	}

	switch t := acc.(type) {
	case map[string]interface{}:
		ma := map[string]Accessor{}
		for k, v := range t {
			o, err := NewAccessor(v)
			if err != nil {
				return nil, err
			}
			ma[k] = o
		}
		return MapAccessor(ma), nil
	case map[interface{}]interface{}:
		ma := map[string]Accessor{}
		for k, v := range t {
			key, ok := k.(string)
			if !ok {
				return nil, NewInvalidKeyError(k)
			}
			o, err := NewAccessor(v)
			if err != nil {
				return nil, err
			}
			ma[key] = o
		}
		return MapAccessor(ma), nil
	case []interface{}:
		sa := make([]Accessor, len(t))
		for i, v := range t {
			o, err := NewAccessor(v)
			if err != nil {
				return nil, err
			}
			sa[i] = o
		}
		return SliceAccessor(sa), nil
	default:
		return ValueAccessor{t}, nil
	}
}
<|endoftext|>