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

package dep

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"

	"github.com/Masterminds/semver"
	"github.com/golang/dep/test"
)

func TestAnalyzerInfo(t *testing.T) {
	a := analyzer{}
	gotn, gotv := a.Info()
	if gotn != "dep" {
		t.Errorf("analyzer.Info() returned an incorrect name: '%s' (expected 'dep')", gotn)
	}
	wantv, err := semver.NewVersion("v0.0.1")
	if err != nil {
		t.Fatal(err)
	}
	if gotv != wantv {
		t.Fatalf("analyzer.Info() returned an incorrect version: %v (expected %v)", gotv, wantv)
	}
}

func TestDeriveManifestAndLock(t *testing.T) {
	h := test.NewHelper(t)
	defer h.Cleanup()

	h.TempDir("dep")
	golden := "analyzer/manifest.json"
	want := h.GetTestFileString(golden)
	h.TempCopy(filepath.Join("dep", ManifestName), golden)

	a := analyzer{}

	m, l, err := a.DeriveManifestAndLock(h.Path("dep"), "my/fake/project")
	if err != nil {
		t.Fatal(err)
	}

	got, err := m.(*Manifest).MarshalJSON()
	if err != nil {
		t.Fatal(err)
	}

	if want != string(got) {
		if *test.UpdateGolden {
			if err := h.WriteTestFile(golden, string(got)); err != nil {
				t.Fatal(err)
			}
		} else {
			t.Fatalf("expected %s\n got %s", want, string(got))
		}
	}

	if l != nil {
		t.Fatalf("expected lock to be nil, got: %#v", l)
	}
}

func TestDeriveManifestAndLockDoesNotExist(t *testing.T) {
	dir, err := ioutil.TempDir("", "dep")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(dir)

	a := analyzer{}

	m, l, err := a.DeriveManifestAndLock(dir, "my/fake/project")
	if m != nil || l != nil || err != nil {
		t.Fatalf("expected manifest & lock & err to be nil: m -> %#v l -> %#v err-> %#v", m, l, err)
	}
}
<commit_msg>Remove TestAnalyzerInfo() per feedback<commit_after>// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dep

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"

	"github.com/golang/dep/test"
)

func TestDeriveManifestAndLock(t *testing.T) {
	h := test.NewHelper(t)
	defer h.Cleanup()

	h.TempDir("dep")
	golden := "analyzer/manifest.json"
	want := h.GetTestFileString(golden)
	h.TempCopy(filepath.Join("dep", ManifestName), golden)

	a := analyzer{}

	m, l, err := a.DeriveManifestAndLock(h.Path("dep"), "my/fake/project")
	if err != nil {
		t.Fatal(err)
	}

	got, err := m.(*Manifest).MarshalJSON()
	if err != nil {
		t.Fatal(err)
	}

	if want != string(got) {
		if *test.UpdateGolden {
			if err := h.WriteTestFile(golden, string(got)); err != nil {
				t.Fatal(err)
			}
		} else {
			t.Fatalf("expected %s\n got %s", want, string(got))
		}
	}

	if l != nil {
		t.Fatalf("expected lock to be nil, got: %#v", l)
	}
}

func TestDeriveManifestAndLockDoesNotExist(t *testing.T) {
	dir, err := ioutil.TempDir("", "dep")
	if err != nil {
		t.Fatal(err)
	}
	defer os.RemoveAll(dir)

	a := analyzer{}

	m, l, err := a.DeriveManifestAndLock(dir, "my/fake/project")
	if m != nil || l != nil || err != nil {
		t.Fatalf("expected manifest & lock & err to be nil: m -> %#v l -> %#v err-> %#v", m, l, err)
	}
}
<|endoftext|>


<commit_before>// +build !ent
// +build !prem
// +build !pro
// +build !hsm

package vault

import (
	"context"
	"fmt"
	"sync/atomic"

	proto "github.com/golang/protobuf/proto"
	log "github.com/hashicorp/go-hclog"
	"github.com/hashicorp/vault/helper/locksutil"
	"github.com/hashicorp/vault/physical"
)

// NewSealUnwrapper creates a new seal unwrapper
func NewSealUnwrapper(underlying physical.Backend, logger log.Logger) physical.Backend {
	ret := &sealUnwrapper{
		underlying:   underlying,
		logger:       logger,
		locks:        locksutil.CreateLocks(),
		allowUnwraps: new(uint32),
	}

	if underTxn, ok := underlying.(physical.Transactional); ok {
		return &transactionalSealUnwrapper{
			sealUnwrapper: ret,
			Transactional: underTxn,
		}
	}

	return ret
}

var _ physical.Backend = (*sealUnwrapper)(nil)
var _ physical.Transactional = (*transactionalSealUnwrapper)(nil)

type sealUnwrapper struct {
	underlying   physical.Backend
	logger       log.Logger
	locks        []*locksutil.LockEntry
	allowUnwraps *uint32
}

// transactionalSealUnwrapper is a seal unwrapper that wraps a physical that is transactional
type transactionalSealUnwrapper struct {
	*sealUnwrapper
	physical.Transactional
}

func (d *sealUnwrapper) Put(ctx context.Context, entry *physical.Entry) error {
	if entry == nil {
		return nil
	}

	locksutil.LockForKey(d.locks, entry.Key).Lock()
	defer locksutil.LockForKey(d.locks, entry.Key).Unlock()

	return d.underlying.Put(ctx, entry)
}

func (d *sealUnwrapper) Get(ctx context.Context, key string) (*physical.Entry, error) {
	entry, err := d.underlying.Get(ctx, key)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

	var performUnwrap bool
	se := &physical.SealWrapEntry{}
	// If the value ends in our canary value, try to decode the bytes.
	eLen := len(entry.Value)
	if eLen > 0 && entry.Value[eLen-1] == 's' {
		if err := proto.Unmarshal(entry.Value[:eLen-1], se); err == nil {
			// We unmarshaled successfully which means we need to store it as a
			// non-proto message
			performUnwrap = true
		}
	}
	if !performUnwrap {
		return entry, nil
	}
	// It's actually encrypted and we can't read it
	if se.Wrapped {
		return nil, fmt.Errorf("cannot decode sealwrapped storage entry %q", entry.Key)
	}
	if atomic.LoadUint32(d.allowUnwraps) != 1 {
		return &physical.Entry{
			Key:   entry.Key,
			Value: se.Ciphertext,
		}, nil
	}

	locksutil.LockForKey(d.locks, key).Lock()
	defer locksutil.LockForKey(d.locks, key).Unlock()

	// At this point we need to re-read and re-check
	entry, err = d.underlying.Get(ctx, key)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

	performUnwrap = false
	se = &physical.SealWrapEntry{}
	// If the value ends in our canary value, try to decode the bytes.
	eLen = len(entry.Value)
	if eLen > 0 && entry.Value[eLen-1] == 's' {
		// We ignore an error because the canary is not a guarantee; if it
		// doesn't decode, proceed normally
		if err := proto.Unmarshal(entry.Value[:eLen-1], se); err == nil {
			// We unmarshaled successfully which means we need to store it as a
			// non-proto message
			performUnwrap = true
		}
	}
	if !performUnwrap {
		return entry, nil
	}
	if se.Wrapped {
		return nil, fmt.Errorf("cannot decode sealwrapped storage entry %q", entry.Key)
	}

	entry = &physical.Entry{
		Key:   entry.Key,
		Value: se.Ciphertext,
	}

	if atomic.LoadUint32(d.allowUnwraps) != 1 {
		return entry, nil
	}
	return entry, d.underlying.Put(ctx, entry)
}

func (d *sealUnwrapper) Delete(ctx context.Context, key string) error {
	locksutil.LockForKey(d.locks, key).Lock()
	defer locksutil.LockForKey(d.locks, key).Unlock()

	return d.underlying.Delete(ctx, key)
}

func (d *sealUnwrapper) List(ctx context.Context, prefix string) ([]string, error) {
	return d.underlying.List(ctx, prefix)
}

func (d *transactionalSealUnwrapper) Transaction(ctx context.Context, txns []*physical.TxnEntry) error {
	// Collect keys that need to be locked
	var keys []string
	for _, curr := range txns {
		keys = append(keys, curr.Entry.Key)
	}
	// Lock the keys
	for _, l := range locksutil.LocksForKeys(d.locks, keys) {
		l.Lock()
		defer l.Unlock()
	}

	if err := d.Transactional.Transaction(ctx, txns); err != nil {
		return err
	}

	return nil
}

// This should only run during preSeal which ensures that it can't be run
// concurrently and that it will be run only by the active node
func (d *sealUnwrapper) stopUnwraps() {
	atomic.StoreUint32(d.allowUnwraps, 0)
}

func (d *sealUnwrapper) runUnwraps() {
	// Allow key unwraps on key gets. This gets set only when running on the
	// active node to prevent standbys from changing data underneath the
	// primary
	atomic.StoreUint32(d.allowUnwraps, 1)
}
<commit_msg>Remove build tags from vendored vault file to allow for this to merge properly into enterprise<commit_after>package vault

import (
	"context"
	"fmt"
	"sync/atomic"

	proto "github.com/golang/protobuf/proto"
	log "github.com/hashicorp/go-hclog"
	"github.com/hashicorp/vault/helper/locksutil"
	"github.com/hashicorp/vault/physical"
)

// NewSealUnwrapper creates a new seal unwrapper
func NewSealUnwrapper(underlying physical.Backend, logger log.Logger) physical.Backend {
	ret := &sealUnwrapper{
		underlying:   underlying,
		logger:       logger,
		locks:        locksutil.CreateLocks(),
		allowUnwraps: new(uint32),
	}

	if underTxn, ok := underlying.(physical.Transactional); ok {
		return &transactionalSealUnwrapper{
			sealUnwrapper: ret,
			Transactional: underTxn,
		}
	}

	return ret
}

var _ physical.Backend = (*sealUnwrapper)(nil)
var _ physical.Transactional = (*transactionalSealUnwrapper)(nil)

type sealUnwrapper struct {
	underlying   physical.Backend
	logger       log.Logger
	locks        []*locksutil.LockEntry
	allowUnwraps *uint32
}

// transactionalSealUnwrapper is a seal unwrapper that wraps a physical that is transactional
type transactionalSealUnwrapper struct {
	*sealUnwrapper
	physical.Transactional
}

func (d *sealUnwrapper) Put(ctx context.Context, entry *physical.Entry) error {
	if entry == nil {
		return nil
	}

	locksutil.LockForKey(d.locks, entry.Key).Lock()
	defer locksutil.LockForKey(d.locks, entry.Key).Unlock()

	return d.underlying.Put(ctx, entry)
}

func (d *sealUnwrapper) Get(ctx context.Context, key string) (*physical.Entry, error) {
	entry, err := d.underlying.Get(ctx, key)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

	var performUnwrap bool
	se := &physical.SealWrapEntry{}
	// If the value ends in our canary value, try to decode the bytes.
	eLen := len(entry.Value)
	if eLen > 0 && entry.Value[eLen-1] == 's' {
		if err := proto.Unmarshal(entry.Value[:eLen-1], se); err == nil {
			// We unmarshaled successfully which means we need to store it as a
			// non-proto message
			performUnwrap = true
		}
	}
	if !performUnwrap {
		return entry, nil
	}
	// It's actually encrypted and we can't read it
	if se.Wrapped {
		return nil, fmt.Errorf("cannot decode sealwrapped storage entry %q", entry.Key)
	}
	if atomic.LoadUint32(d.allowUnwraps) != 1 {
		return &physical.Entry{
			Key:   entry.Key,
			Value: se.Ciphertext,
		}, nil
	}

	locksutil.LockForKey(d.locks, key).Lock()
	defer locksutil.LockForKey(d.locks, key).Unlock()

	// At this point we need to re-read and re-check
	entry, err = d.underlying.Get(ctx, key)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

	performUnwrap = false
	se = &physical.SealWrapEntry{}
	// If the value ends in our canary value, try to decode the bytes.
	eLen = len(entry.Value)
	if eLen > 0 && entry.Value[eLen-1] == 's' {
		// We ignore an error because the canary is not a guarantee; if it
		// doesn't decode, proceed normally
		if err := proto.Unmarshal(entry.Value[:eLen-1], se); err == nil {
			// We unmarshaled successfully which means we need to store it as a
			// non-proto message
			performUnwrap = true
		}
	}
	if !performUnwrap {
		return entry, nil
	}
	if se.Wrapped {
		return nil, fmt.Errorf("cannot decode sealwrapped storage entry %q", entry.Key)
	}

	entry = &physical.Entry{
		Key:   entry.Key,
		Value: se.Ciphertext,
	}

	if atomic.LoadUint32(d.allowUnwraps) != 1 {
		return entry, nil
	}
	return entry, d.underlying.Put(ctx, entry)
}

func (d *sealUnwrapper) Delete(ctx context.Context, key string) error {
	locksutil.LockForKey(d.locks, key).Lock()
	defer locksutil.LockForKey(d.locks, key).Unlock()

	return d.underlying.Delete(ctx, key)
}

func (d *sealUnwrapper) List(ctx context.Context, prefix string) ([]string, error) {
	return d.underlying.List(ctx, prefix)
}

func (d *transactionalSealUnwrapper) Transaction(ctx context.Context, txns []*physical.TxnEntry) error {
	// Collect keys that need to be locked
	var keys []string
	for _, curr := range txns {
		keys = append(keys, curr.Entry.Key)
	}
	// Lock the keys
	for _, l := range locksutil.LocksForKeys(d.locks, keys) {
		l.Lock()
		defer l.Unlock()
	}

	if err := d.Transactional.Transaction(ctx, txns); err != nil {
		return err
	}

	return nil
}

// This should only run during preSeal which ensures that it can't be run
// concurrently and that it will be run only by the active node
func (d *sealUnwrapper) stopUnwraps() {
	atomic.StoreUint32(d.allowUnwraps, 0)
}

func (d *sealUnwrapper) runUnwraps() {
	// Allow key unwraps on key gets. This gets set only when running on the
	// active node to prevent standbys from changing data underneath the
	// primary
	atomic.StoreUint32(d.allowUnwraps, 1)
}
<|endoftext|>


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

package main

import (
	"os"

	"github.com/tsuru/tsuru/cmd"
)

const (
	version = "1.0.1-rc2"
	header  = "Supported-Tsuru"
)

func buildManager(name string) *cmd.Manager {
	lookup := func(context *cmd.Context) error {
		return runPlugin(context)
	}
	m := cmd.BuildBaseManager(name, version, header, lookup)
	m.Register(&appRun{})
	m.Register(&appInfo{})
	m.Register(&appCreate{})
	m.Register(&appRemove{})
	m.Register(&appUpdate{})
	m.Register(&unitAdd{})
	m.Register(&unitRemove{})
	m.Register(&appList{})
	m.Register(&appLog{})
	m.Register(&appGrant{})
	m.Register(&appRevoke{})
	m.Register(&appRestart{})
	m.Register(&appStart{})
	m.Register(&appStop{})
	m.RegisterRemoved("app-pool-change", "You should use `tsuru app-update` instead.")
	m.RegisterRemoved("app-plan-change", "You should use `tsuru app-update` instead.")
	m.Register(&cnameAdd{})
	m.Register(&cnameRemove{})
	m.Register(&envGet{})
	m.Register(&envSet{})
	m.Register(&envUnset{})
	m.Register(&keyAdd{})
	m.Register(&keyRemove{})
	m.Register(&keyList{})
	m.Register(serviceList{})
	m.Register(&serviceInstanceAdd{})
	m.RegisterRemoved("service-add", "You should use `tsuru service-instance-add` instead.")
	m.Register(&serviceInstanceUpdate{})
	m.RegisterRemoved("service-update", "You should use `tsuru service-instance-update` instead.")
	m.Register(&serviceInstanceRemove{})
	m.RegisterRemoved("service-remove", "You should use `tsuru service-instance-remove` instead.")
	m.Register(serviceInfo{})
	m.Register(serviceInstanceInfo{})
	m.RegisterRemoved("service-status", "You should use `tsuru service-instance-status` instead.")
	m.Register(serviceInstanceStatus{})
	m.Register(&serviceInstanceGrant{})
	m.Register(&serviceInstanceRevoke{})
	m.Register(&serviceInstanceBind{})
	m.RegisterRemoved("service-bind", "You should use `tsuru service-instance-bind` instead.")
	m.Register(&serviceInstanceUnbind{})
	m.RegisterRemoved("service-unbind", "You should use `tsuru service-instance-unbind` instead.")
	m.Register(platformList{})
	m.Register(&pluginInstall{})
	m.Register(&pluginRemove{})
	m.Register(&pluginList{})
	m.Register(&appSwap{})
	m.Register(&appDeploy{})
	m.Register(&planList{})
	m.RegisterRemoved("app-team-owner-set", "You should use `tsuru service-info` instead.")
	m.Register(&userCreate{})
	m.Register(&resetPassword{})
	m.Register(&userRemove{})
	m.Register(&listUsers{})
	m.Register(&teamCreate{})
	m.Register(&teamRemove{})
	m.Register(&teamList{})
	m.RegisterRemoved("service-doc", "You should use `tsuru service-info` instead.")
	m.RegisterRemoved("team-user-add", "You should use `tsuru role-assign` instead.")
	m.RegisterRemoved("team-user-remove", "You should use `tsuru role-dissociate` instead.")
	m.RegisterRemoved("team-user-list", "You should use `tsuru user-list` instead.")
	m.Register(&changePassword{})
	m.Register(&showAPIToken{})
	m.Register(&regenerateAPIToken{})
	m.Register(&appDeployList{})
	m.Register(&appDeployRollback{})
	m.Register(&cmd.ShellToContainerCmd{})
	m.Register(&poolList{})
	m.Register(&permissionList{})
	m.Register(&roleAdd{})
	m.Register(&roleRemove{})
	m.Register(&roleList{})
	m.Register(&roleInfo{})
	m.Register(&rolePermissionAdd{})
	m.Register(&rolePermissionRemove{})
	m.Register(&roleAssign{})
	m.Register(&roleDissociate{})
	m.Register(&roleDefaultAdd{})
	m.Register(&roleDefaultList{})
	m.Register(&roleDefaultRemove{})
	return m
}

func main() {
	name := cmd.ExtractProgramName(os.Args[0])
	manager := buildManager(name)
	manager.Run(os.Args[1:])
}
<commit_msg>bump 1.0.1<commit_after>// Copyright 2016 tsuru-client authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"os"

	"github.com/tsuru/tsuru/cmd"
)

const (
	version = "1.0.1"
	header  = "Supported-Tsuru"
)

func buildManager(name string) *cmd.Manager {
	lookup := func(context *cmd.Context) error {
		return runPlugin(context)
	}
	m := cmd.BuildBaseManager(name, version, header, lookup)
	m.Register(&appRun{})
	m.Register(&appInfo{})
	m.Register(&appCreate{})
	m.Register(&appRemove{})
	m.Register(&appUpdate{})
	m.Register(&unitAdd{})
	m.Register(&unitRemove{})
	m.Register(&appList{})
	m.Register(&appLog{})
	m.Register(&appGrant{})
	m.Register(&appRevoke{})
	m.Register(&appRestart{})
	m.Register(&appStart{})
	m.Register(&appStop{})
	m.RegisterRemoved("app-pool-change", "You should use `tsuru app-update` instead.")
	m.RegisterRemoved("app-plan-change", "You should use `tsuru app-update` instead.")
	m.Register(&cnameAdd{})
	m.Register(&cnameRemove{})
	m.Register(&envGet{})
	m.Register(&envSet{})
	m.Register(&envUnset{})
	m.Register(&keyAdd{})
	m.Register(&keyRemove{})
	m.Register(&keyList{})
	m.Register(serviceList{})
	m.Register(&serviceInstanceAdd{})
	m.RegisterRemoved("service-add", "You should use `tsuru service-instance-add` instead.")
	m.Register(&serviceInstanceUpdate{})
	m.RegisterRemoved("service-update", "You should use `tsuru service-instance-update` instead.")
	m.Register(&serviceInstanceRemove{})
	m.RegisterRemoved("service-remove", "You should use `tsuru service-instance-remove` instead.")
	m.Register(serviceInfo{})
	m.Register(serviceInstanceInfo{})
	m.RegisterRemoved("service-status", "You should use `tsuru service-instance-status` instead.")
	m.Register(serviceInstanceStatus{})
	m.Register(&serviceInstanceGrant{})
	m.Register(&serviceInstanceRevoke{})
	m.Register(&serviceInstanceBind{})
	m.RegisterRemoved("service-bind", "You should use `tsuru service-instance-bind` instead.")
	m.Register(&serviceInstanceUnbind{})
	m.RegisterRemoved("service-unbind", "You should use `tsuru service-instance-unbind` instead.")
	m.Register(platformList{})
	m.Register(&pluginInstall{})
	m.Register(&pluginRemove{})
	m.Register(&pluginList{})
	m.Register(&appSwap{})
	m.Register(&appDeploy{})
	m.Register(&planList{})
	m.RegisterRemoved("app-team-owner-set", "You should use `tsuru service-info` instead.")
	m.Register(&userCreate{})
	m.Register(&resetPassword{})
	m.Register(&userRemove{})
	m.Register(&listUsers{})
	m.Register(&teamCreate{})
	m.Register(&teamRemove{})
	m.Register(&teamList{})
	m.RegisterRemoved("service-doc", "You should use `tsuru service-info` instead.")
	m.RegisterRemoved("team-user-add", "You should use `tsuru role-assign` instead.")
	m.RegisterRemoved("team-user-remove", "You should use `tsuru role-dissociate` instead.")
	m.RegisterRemoved("team-user-list", "You should use `tsuru user-list` instead.")
	m.Register(&changePassword{})
	m.Register(&showAPIToken{})
	m.Register(&regenerateAPIToken{})
	m.Register(&appDeployList{})
	m.Register(&appDeployRollback{})
	m.Register(&cmd.ShellToContainerCmd{})
	m.Register(&poolList{})
	m.Register(&permissionList{})
	m.Register(&roleAdd{})
	m.Register(&roleRemove{})
	m.Register(&roleList{})
	m.Register(&roleInfo{})
	m.Register(&rolePermissionAdd{})
	m.Register(&rolePermissionRemove{})
	m.Register(&roleAssign{})
	m.Register(&roleDissociate{})
	m.Register(&roleDefaultAdd{})
	m.Register(&roleDefaultList{})
	m.Register(&roleDefaultRemove{})
	return m
}

func main() {
	name := cmd.ExtractProgramName(os.Args[0])
	manager := buildManager(name)
	manager.Run(os.Args[1:])
}
<|endoftext|>


<commit_before>package controllers

import (
	"encoding/json"
	"github.com/gin-gonic/gin"

	e "github.com/techjanitor/pram-get/errors"
	"github.com/techjanitor/pram-get/models"
)

// ImageController handles image pages
func ImageController(c *gin.Context) {

	// Get parameters from validate middleware
	params := c.MustGet("params").([]uint)

	// get userdata from session middleware
	userdata := c.MustGet("userdata").(u.User)

	// Initialize model struct
	m := &models.ImageModel{
		Ib: params[0],
		Id: params[1],
	}

	// Get the model which outputs JSON
	err := m.Get()
	if err == e.ErrNotFound {
		c.Set("controllerError", true)
		c.JSON(e.ErrorMessage(e.ErrNotFound))
		c.Error(err)
		return
	} else if err != nil {
		c.Set("controllerError", true)
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err)
		return
	}

	// Marshal the structs into JSON
	output, err := json.Marshal(m.Result)
	if err != nil {
		c.Set("controllerError", true)
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err)
		return
	}

	// Hand off data to cache middleware
	c.Set("data", output)

	c.Writer.Header().Set("Content-Type", "application/json")
	c.Writer.Write(output)

	return

}
<commit_msg>fix popular query to not include deleted images<commit_after>package controllers

import (
	"encoding/json"
	"github.com/gin-gonic/gin"

	e "github.com/techjanitor/pram-get/errors"
	"github.com/techjanitor/pram-get/models"
	u "github.com/techjanitor/pram-get/utils"
)

// ImageController handles image pages
func ImageController(c *gin.Context) {

	// Get parameters from validate middleware
	params := c.MustGet("params").([]uint)

	// get userdata from session middleware
	userdata := c.MustGet("userdata").(u.User)

	// Initialize model struct
	m := &models.ImageModel{
		Ib: params[0],
		Id: params[1],
	}

	// Get the model which outputs JSON
	err := m.Get()
	if err == e.ErrNotFound {
		c.Set("controllerError", true)
		c.JSON(e.ErrorMessage(e.ErrNotFound))
		c.Error(err)
		return
	} else if err != nil {
		c.Set("controllerError", true)
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err)
		return
	}

	// Marshal the structs into JSON
	output, err := json.Marshal(m.Result)
	if err != nil {
		c.Set("controllerError", true)
		c.JSON(e.ErrorMessage(e.ErrInternalError))
		c.Error(err)
		return
	}

	// Hand off data to cache middleware
	c.Set("data", output)

	c.Writer.Header().Set("Content-Type", "application/json")
	c.Writer.Write(output)

	return

}
<|endoftext|>


<commit_before>// Package aphgrpc provides various interfaces, functions, types
// for building and working with gRPC services.
package aphgrpc

import (
	"encoding/json"
	"net/http"
	"strconv"
	"strings"

	context "golang.org/x/net/context"

	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	"github.com/pkg/errors"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"
)

const (
	// MetaKey is the key used for storing all metadata
	MetaKey = "error"
)

var (
	//ErrDatabaseQuery represents database query related errors
	ErrDatabaseQuery = newError("Database query error")
	//ErrDatabaseInsert represents database insert related errors
	ErrDatabaseInsert = newError("Database insert error")
	//ErrDatabaseUpdate represents database update related errors
	ErrDatabaseUpdate = newError("Database update error")
	//ErrDatabaseDelete represents database update delete errors
	ErrDatabaseDelete = newError("Database delete error")
	//ErrNotFound represents the absence of an HTTP resource
	ErrNotFound = newError("Resource not found")
	//ErrExists represents the presence of an HTTP resource
	ErrExists = newError("Resource already exists")
	//ErrJSONEncoding represents any json encoding error
	ErrJSONEncoding = newError("Json encoding error")
	//ErrStructMarshal represents any error with marshalling structure
	ErrStructMarshal = newError("Structure marshalling error")
	//ErrIncludeParam represents any error with invalid include query parameter
	ErrIncludeParam = newErrorWithParam("Invalid include query parameter", "include")
	//ErrSparseFieldSets represents any error with invalid sparse fieldsets query parameter
	ErrFields = newErrorWithParam("Invalid field query parameter", "field")
	//ErrFilterParam represents any error with invalid filter query paramter
	ErrFilterParam = newErrorWithParam("Invalid filter query parameter", "filter")
	//ErrNotAcceptable represents any error with wrong or inappropriate http Accept header
	ErrNotAcceptable = newError("Accept header is not acceptable")
	//ErrUnsupportedMedia represents any error with unsupported media type in http header
	ErrUnsupportedMedia = newError("Media type is not supported")
	//ErrRetrieveMetadata represents any error to retrieve grpc metadata from the running context
	ErrRetrieveMetadata = errors.New("unable to retrieve metadata")
	//ErrXForwardedHost represents any failure or absence of x-forwarded-host HTTP header in the grpc context
	ErrXForwardedHost = errors.New("x-forwarded-host header is absent")
)

// HTTPError is used for errors
type HTTPError struct {
	err    error
	msg    string
	status int
	Errors []Error `json:"errors,omitempty"`
}

// Error can be used for all kind of application errors
// e.g. you would use it to define form errors or any
// other semantical application problems
// for more information see http://jsonapi.org/format/#errors
type Error struct {
	ID     string       `json:"id,omitempty"`
	Links  *ErrorLinks  `json:"links,omitempty"`
	Status string       `json:"status,omitempty"`
	Code   string       `json:"code,omitempty"`
	Title  string       `json:"title,omitempty"`
	Detail string       `json:"detail,omitempty"`
	Source *ErrorSource `json:"source,omitempty"`
	Meta   interface{}  `json:"meta,omitempty"`
}

// ErrorLinks is used to provide an About URL that leads to
// further details about the particular occurrence of the problem.
//
// for more information see http://jsonapi.org/format/#error-objects
type ErrorLinks struct {
	About string `json:"about,omitempty"`
}

// ErrorSource is used to provide references to the source of an error.
//
// The Pointer is a JSON Pointer to the associated entity in the request
// document.
// The Paramter is a string indicating which query parameter caused the error.
//
// for more information see http://jsonapi.org/format/#error-objects
type ErrorSource struct {
	Pointer   string `json:"pointer,omitempty"`
	Parameter string `json:"parameter,omitempty"`
}

func newErrorWithParam(msg, param string) metadata.MD {
	return metadata.Pairs(MetaKey, msg, MetaKey, param)
}

func newError(msg string) metadata.MD {
	return metadata.Pairs(MetaKey, msg)
}

// CustomHTTPError is a custom error handler for grpc-gateway to generate
// JSONAPI formatted HTTP response.
func CustomHTTPError(ctx context.Context, _ *runtime.ServeMux, marshaler runtime.Marshaler, w http.ResponseWriter, _ *http.Request, err error) {
	md, ok := runtime.ServerMetadataFromContext(ctx)
	if !ok {
		fallbackError(w, getgRPCStatus(errors.Wrap(err, "unable to retrieve metadata")))
		return
	}
	JSONAPIError(w, md.TrailerMD, getgRPCStatus(err))
}

func getgRPCStatus(err error) *status.Status {
	s, ok := status.FromError(err)
	if !ok {
		return status.New(codes.Unknown, err.Error())
	}
	return s
}

// JSONAPIError generates JSONAPI formatted error message
func JSONAPIError(w http.ResponseWriter, md metadata.MD, s *status.Status) {
	status := runtime.HTTPStatusFromCode(s.Code())
	jsnErr := Error{
		Status: strconv.Itoa(status),
		Title:  strings.Join(md["error"], "-"),
		Detail: s.Message(),
		Meta: map[string]interface{}{
			"creator": "api error helper",
		},
	}
	w.Header().Set("Content-Type", "application/vnd.api+json")
	w.WriteHeader(status)
	encErr := json.NewEncoder(w).Encode(HTTPError{Errors: []Error{jsnErr}})
	if encErr != nil {
		http.Error(w, encErr.Error(), http.StatusInternalServerError)
	}
}

func fallbackError(w http.ResponseWriter, s *status.Status) {
	status := runtime.HTTPStatusFromCode(s.Code())
	jsnErr := Error{
		Status: strconv.Itoa(status),
		Title:  "gRPC error",
		Detail: s.Message(),
		Meta: map[string]interface{}{
			"creator": "api error helper",
		},
	}
	w.Header().Set("Content-Type", "application/vnd.api+json")
	w.WriteHeader(status)
	encErr := json.NewEncoder(w).Encode(HTTPError{Errors: []Error{jsnErr}})
	if encErr != nil {
		http.Error(w, encErr.Error(), http.StatusInternalServerError)
	}
}

func CheckNoRows(err error) bool {
	if strings.Contains(err.Error(), "no rows") {
		return true
	}
	return false
}

func HandleError(ctx context.Context, err error) error {
	if CheckNoRows(err) {
		grpc.SetTrailer(ctx, ErrNotFound)
		return status.Error(codes.NotFound, err.Error())
	}
	grpc.SetTrailer(ctx, newError(err.Error()))
	return status.Error(codes.Internal, err.Error())
}

func HandleGenericError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, newError(err.Error()))
	return status.Error(codes.Internal, err.Error())
}

func HandleDeleteError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrDatabaseDelete)
	return status.Error(codes.Internal, err.Error())
}

func HandleGetError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrDatabaseQuery)
	return status.Error(codes.Internal, err.Error())
}

func HandleInsertError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrDatabaseInsert)
	return status.Error(codes.Internal, err.Error())
}

func HandleUpdateError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrDatabaseUpdate)
	return status.Error(codes.Internal, err.Error())
}

func HandleGetArgError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrDatabaseQuery)
	return status.Error(codes.InvalidArgument, err.Error())
}

func HandleInsertArgError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrDatabaseInsert)
	return status.Error(codes.InvalidArgument, err.Error())
}

func HandleUpdateArgError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrDatabaseUpdate)
	return status.Error(codes.InvalidArgument, err.Error())
}

func HandleNotFoundError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrNotFound)
	return status.Error(codes.NotFound, err.Error())
}

func HandleExistError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrExists)
	return status.Error(codes.AlreadyExists, err.Error())
}
<commit_msg>Added function for handling messaging error<commit_after>// Package aphgrpc provides various interfaces, functions, types
// for building and working with gRPC services.
package aphgrpc

import (
	"encoding/json"
	"net/http"
	"strconv"
	"strings"

	context "golang.org/x/net/context"

	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	"github.com/pkg/errors"
	spb "google.golang.org/genproto/googleapis/rpc/status"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"
)

const (
	// MetaKey is the key used for storing all metadata
	MetaKey = "error"
)

var (
	//ErrDatabaseQuery represents database query related errors
	ErrDatabaseQuery = newError("Database query error")
	//ErrDatabaseInsert represents database insert related errors
	ErrDatabaseInsert = newError("Database insert error")
	//ErrDatabaseUpdate represents database update related errors
	ErrDatabaseUpdate = newError("Database update error")
	//ErrDatabaseDelete represents database update delete errors
	ErrDatabaseDelete = newError("Database delete error")
	//ErrNotFound represents the absence of an HTTP resource
	ErrNotFound = newError("Resource not found")
	//ErrExists represents the presence of an HTTP resource
	ErrExists = newError("Resource already exists")
	//ErrJSONEncoding represents any json encoding error
	ErrJSONEncoding = newError("Json encoding error")
	//ErrStructMarshal represents any error with marshalling structure
	ErrStructMarshal = newError("Structure marshalling error")
	//ErrIncludeParam represents any error with invalid include query parameter
	ErrIncludeParam = newErrorWithParam("Invalid include query parameter", "include")
	//ErrSparseFieldSets represents any error with invalid sparse fieldsets query parameter
	ErrFields = newErrorWithParam("Invalid field query parameter", "field")
	//ErrFilterParam represents any error with invalid filter query paramter
	ErrFilterParam = newErrorWithParam("Invalid filter query parameter", "filter")
	//ErrNotAcceptable represents any error with wrong or inappropriate http Accept header
	ErrNotAcceptable = newError("Accept header is not acceptable")
	//ErrUnsupportedMedia represents any error with unsupported media type in http header
	ErrUnsupportedMedia = newError("Media type is not supported")
	//ErrRetrieveMetadata represents any error to retrieve grpc metadata from the running context
	ErrRetrieveMetadata = errors.New("unable to retrieve metadata")
	//ErrXForwardedHost represents any failure or absence of x-forwarded-host HTTP header in the grpc context
	ErrXForwardedHost = errors.New("x-forwarded-host header is absent")
)

// HTTPError is used for errors
type HTTPError struct {
	err    error
	msg    string
	status int
	Errors []Error `json:"errors,omitempty"`
}

// Error can be used for all kind of application errors
// e.g. you would use it to define form errors or any
// other semantical application problems
// for more information see http://jsonapi.org/format/#errors
type Error struct {
	ID     string       `json:"id,omitempty"`
	Links  *ErrorLinks  `json:"links,omitempty"`
	Status string       `json:"status,omitempty"`
	Code   string       `json:"code,omitempty"`
	Title  string       `json:"title,omitempty"`
	Detail string       `json:"detail,omitempty"`
	Source *ErrorSource `json:"source,omitempty"`
	Meta   interface{}  `json:"meta,omitempty"`
}

// ErrorLinks is used to provide an About URL that leads to
// further details about the particular occurrence of the problem.
//
// for more information see http://jsonapi.org/format/#error-objects
type ErrorLinks struct {
	About string `json:"about,omitempty"`
}

// ErrorSource is used to provide references to the source of an error.
//
// The Pointer is a JSON Pointer to the associated entity in the request
// document.
// The Paramter is a string indicating which query parameter caused the error.
//
// for more information see http://jsonapi.org/format/#error-objects
type ErrorSource struct {
	Pointer   string `json:"pointer,omitempty"`
	Parameter string `json:"parameter,omitempty"`
}

func newErrorWithParam(msg, param string) metadata.MD {
	return metadata.Pairs(MetaKey, msg, MetaKey, param)
}

func newError(msg string) metadata.MD {
	return metadata.Pairs(MetaKey, msg)
}

// CustomHTTPError is a custom error handler for grpc-gateway to generate
// JSONAPI formatted HTTP response.
func CustomHTTPError(ctx context.Context, _ *runtime.ServeMux, marshaler runtime.Marshaler, w http.ResponseWriter, _ *http.Request, err error) {
	md, ok := runtime.ServerMetadataFromContext(ctx)
	if !ok {
		fallbackError(w, getgRPCStatus(errors.Wrap(err, "unable to retrieve metadata")))
		return
	}
	JSONAPIError(w, md.TrailerMD, getgRPCStatus(err))
}

func getgRPCStatus(err error) *status.Status {
	s, ok := status.FromError(err)
	if !ok {
		return status.New(codes.Unknown, err.Error())
	}
	return s
}

// JSONAPIError generates JSONAPI formatted error message
func JSONAPIError(w http.ResponseWriter, md metadata.MD, s *status.Status) {
	status := runtime.HTTPStatusFromCode(s.Code())
	jsnErr := Error{
		Status: strconv.Itoa(status),
		Title:  strings.Join(md["error"], "-"),
		Detail: s.Message(),
		Meta: map[string]interface{}{
			"creator": "api error helper",
		},
	}
	w.Header().Set("Content-Type", "application/vnd.api+json")
	w.WriteHeader(status)
	encErr := json.NewEncoder(w).Encode(HTTPError{Errors: []Error{jsnErr}})
	if encErr != nil {
		http.Error(w, encErr.Error(), http.StatusInternalServerError)
	}
}

func fallbackError(w http.ResponseWriter, s *status.Status) {
	status := runtime.HTTPStatusFromCode(s.Code())
	jsnErr := Error{
		Status: strconv.Itoa(status),
		Title:  "gRPC error",
		Detail: s.Message(),
		Meta: map[string]interface{}{
			"creator": "api error helper",
		},
	}
	w.Header().Set("Content-Type", "application/vnd.api+json")
	w.WriteHeader(status)
	encErr := json.NewEncoder(w).Encode(HTTPError{Errors: []Error{jsnErr}})
	if encErr != nil {
		http.Error(w, encErr.Error(), http.StatusInternalServerError)
	}
}

func CheckNoRows(err error) bool {
	if strings.Contains(err.Error(), "no rows") {
		return true
	}
	return false
}

func HandleMessagingError(ctx context.Context, st spb.Status) error {
	err := status.ErrorProto(st)
	grpc.SetTrailer(ctx, newError(err.Error()))
	return err
}

func HandleError(ctx context.Context, err error) error {
	if CheckNoRows(err) {
		grpc.SetTrailer(ctx, ErrNotFound)
		return status.Error(codes.NotFound, err.Error())
	}
	grpc.SetTrailer(ctx, newError(err.Error()))
	return status.Error(codes.Internal, err.Error())
}

func HandleGenericError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, newError(err.Error()))
	return status.Error(codes.Internal, err.Error())
}

func HandleDeleteError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrDatabaseDelete)
	return status.Error(codes.Internal, err.Error())
}

func HandleGetError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrDatabaseQuery)
	return status.Error(codes.Internal, err.Error())
}

func HandleInsertError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrDatabaseInsert)
	return status.Error(codes.Internal, err.Error())
}

func HandleUpdateError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrDatabaseUpdate)
	return status.Error(codes.Internal, err.Error())
}

func HandleGetArgError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrDatabaseQuery)
	return status.Error(codes.InvalidArgument, err.Error())
}

func HandleInsertArgError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrDatabaseInsert)
	return status.Error(codes.InvalidArgument, err.Error())
}

func HandleUpdateArgError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrDatabaseUpdate)
	return status.Error(codes.InvalidArgument, err.Error())
}

func HandleNotFoundError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrNotFound)
	return status.Error(codes.NotFound, err.Error())
}

func HandleExistError(ctx context.Context, err error) error {
	grpc.SetTrailer(ctx, ErrExists)
	return status.Error(codes.AlreadyExists, err.Error())
}
<|endoftext|>


<commit_before>package yquotes

import (
	"encoding/csv"
	"fmt"
	"net/http"
	"strconv"
	"time"
)

const (
	// URL of Yahoo quotes for stock quotes.
	YURL = "http://finance.yahoo.com/d/quotes.csv?s=%s&f=%s"

	// Base data formating.
	// s - symbol
	// n - name
	// b - bid
	// a - ask
	// o - open
	// p - previous price
	// l1 - last price without time
	// d1 - last trade date
	BaseFormat = "snbaopl1d1"

	// Historical data URL with params:
	// s - symbol
	// a - from month (zero based)
	// b - from day
	// c - from year
	// d - to month (zero based)
	// e - to day
	// f - to year
	// g - period frequence (d - daily, w - weekly, m - monthly, y -yearly)
	YURL_H = "http://ichart.yahoo.com/table.csv?s=%s&a=%d&b=%d&c=%d&d=%d&e=%d&f=%d&g=%s&ignore=.csv"
)

// Formatting constants.
const (
	Symbol   = "s"
	Name     = "n"
	Bid      = "b"
	Ask      = "a"
	Open     = "o"
	Previous = "p"
	Last     = "l1"
	LastDate = "d1"
)

// Constance of frequesncy for historical data requests.
const (
	Daily   = "d"
	Weekly  = "w"
	Monthly = "m"
	Yearly  = "y"
)

// Price struct represents price in single point in time.
type Price struct {
	Bid           float64   `json:"bid,omitempty"`
	Ask           float64   `json:"ask,omitempty"`
	Open          float64   `json:"open,omitempty"`
	PreviousClose float64   `json:"previousClose,omitempty"`
	Last          float64   `json:"last,omitempty"`
	Date          time.Time `json:"date,omitempty"`
}

// Price type that is used for historical price data.
type PriceH struct {
	Date     time.Time `json:"date,omitempty"`
	Open     float64   `json:"open,omitempty"`
	High     float64   `json:"high,omitempty"`
	Low      float64   `json:"low,omitempty"`
	Close    float64   `json:"close,omitempty"`
	Volume   float64   `json:"volume,omitempty"`
	AdjClose float64   `json:"adjClose,omitempty"`
}

// Stock is used as container for stock price data.
type Stock struct {
	// Symbol of stock that should meet requirements of Yahoo. Otherwise,
	// there will be no possibility to find stock.
	Symbol string `json:"symbol,omitempty"`

	// Name of the company will be filled from request of stock data.
	Name string `json:"name,omitempty"`

	// Information about last price of stock.
	Price *Price `json:"price,omitempty"`

	// Contains historical price information. If client asks information
	// for recent price, this field will be omited.
	History []PriceH `json:"history,omitempty"`
}

// Create new stock with recent price data and historical prices. All the prices
// are represented in daily basis.
//
// symbol - Symbol of company (ticker)
// history - If true 3 year price history will be loaded.
// Returns a pointer to value of Stock type.
func NewStock(symbol string, history bool) (*Stock, error) {
	var stock *Stock

	data, err := loadSingleStockPrice(symbol)
	if err != nil {
		return nil, err
	}
	stock = parseStock(data)

	// If history is TRUE, we need to load historical price for 3 year period.
	if history == true {
		histPrices, err := HistoryForYears(symbol, 3, Daily)
		if err != nil {
			return stock, err
		}
		stock.History = histPrices
	}

	return stock, nil
}

// Get single stock price data.
func GetPrice(symbol string) (*Price, error) {
	data, err := loadSingleStockPrice(symbol)
	if err != nil {
		return nil, err
	}

	price := parsePrice(data)
	return price, nil
}

// Get single stock price for certain date.
func GetPriceForDate(symbol string, date time.Time) (PriceH, error) {
	var price PriceH
	// We need to get price information for single date, so date passed to
	// this function will be used both for "from" and "to" arguments.
	data, err := loadHistoricalPrice(symbol, date, date, Daily)
	if err != nil {
		return price, err
	}

	prices, err := parseHistorical(data)
	if err != nil {
		return PriceH{}, err
	}
	price = prices[0]

	// Return single price.
	return price, nil
}

// Get historical prices for the stock.
func GetDailyHistory(symbol string, from, to time.Time) ([]PriceH, error) {
	var prices []PriceH
	// Create URL with daily frequency of data.
	data, err := loadHistoricalPrice(symbol, from, to, Daily)
	if err != nil {
		return prices, err
	}

	prices, err = parseHistorical(data)
	if err != nil {
		return prices, err
	}

	return prices, nil
}

// Get stock price history for number of years backwards.
func HistoryForYears(symbol string, years int, period string) ([]PriceH, error) {
	var prices []PriceH
	duration := time.Duration(int(time.Hour) * 24 * 365 * years)
	to := time.Now()
	from := to.Add(-duration)

	data, err := loadHistoricalPrice(symbol, from, to, period)
	if err != nil {
		return prices, err
	}

	prices, err = parseHistorical(data)
	if err != nil {
		return prices, err
	}

	return prices, nil
}

// Single company data request to Yahoo Finance.
func loadSingleStockPrice(symbol string) ([]string, error) {
	url := singleStockUrl(symbol)
	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	reader := csv.NewReader(resp.Body)
	data, err := reader.Read()
	if err != nil {
		return nil, err
	}

	return data, err
}

// Load historical data price.
func loadHistoricalPrice(symbol string, from, to time.Time, period string) ([][]string, error) {
	url := stockHistoryURL(symbol, from, to, period)
	var data [][]string

	resp, err := http.Get(url)
	if err != nil {
		return data, err
	}
	defer resp.Body.Close()

	reader := csv.NewReader(resp.Body)
	data, err = reader.ReadAll()
	if err != nil {
		return data, err
	}

	return data, nil
}

// Generate request URL for single stock.
func singleStockUrl(symbol string) string {
	url := fmt.Sprintf(YURL, symbol, BaseFormat)
	return url
}

// Generate request URL for historicat stock data.
func stockHistoryURL(symbol string, from, to time.Time, frequency string) string {
	// From date
	fMonth := (from.Month() - 1) // Need to subtract 1 because months in query is 0 based.
	fDay := from.Day()
	fYear := from.Year()
	// To date
	tMonth := (to.Month() - 1)
	tDay := to.Day()
	tYear := to.Year()

	url := fmt.Sprintf(
		YURL_H,
		symbol,
		fMonth,
		fDay,
		fYear,
		tMonth,
		tDay,
		tYear,
		frequency)

	return url
}

// Parse base information of stock price. Base inforamtion is reperesented by
// request format BaseFormat.
func parseStock(data []string) *Stock {
	s := &Stock{
		Symbol: data[0],
		Name:   data[1],
		Price:  parsePrice(data),
	}

	return s
}

// Parse collection of historical prices.
func parseHistorical(data [][]string) ([]PriceH, error) {
	// This is the list of prices with allocated space. Length of space should
	// subtracted by 1 because the first row of data is title.
	var list = make([]PriceH, len(data)-1)
	// We need to leave the first row, because it contains title of columns.
	for k, v := range data {
		if k == 0 {
			continue
		}
		// Parse row of data into PriceH type and append it to collection of prices.
		p, err := parseHistoricalRow(v)
		if err != nil {
			return list, err
		}

		// (k - 1) because we remove header from the list so index should be
		// reduced by one.
		list[k-1] = p
	}
	return list, nil
}

// Parse data row that comes from historical data. Data row contains
// 7 columns:
// 0 - Date
// 1 - Open
// 2 - High
// 3 - Low
// 4 - Close
// 5 - Volume
// 6 - Adj Close
// This function will return PriceH type that wraps all these columns.
func parseHistoricalRow(data []string) (PriceH, error) {
	p := PriceH{}

	// Parse date.
	d, err := time.Parse("2006-01-02", data[0])
	if err != nil {
		return p, err
	}

	p.Date = d
	p.Open, _ = strconv.ParseFloat(data[1], 64)
	p.High, _ = strconv.ParseFloat(data[2], 64)
	p.Low, _ = strconv.ParseFloat(data[3], 64)
	p.Close, _ = strconv.ParseFloat(data[4], 64)
	p.Volume, _ = strconv.ParseFloat(data[5], 64)
	p.AdjClose, _ = strconv.ParseFloat(data[6], 64)

	return p, nil
}

// Parse date from string into time.Time type.
func parseDate(date string) (time.Time, error) {
	d, err := time.Parse("1/2/2006", date)
	if err != nil {
		return time.Time{}, err
	}

	return d, nil
}

// Parse price information from base data.
func parsePrice(data []string) *Price {
	p := &Price{}
	p.Bid, _ = strconv.ParseFloat(data[2], 64)
	p.Ask, _ = strconv.ParseFloat(data[3], 64)
	p.Open, _ = strconv.ParseFloat(data[4], 64)
	p.PreviousClose, _ = strconv.ParseFloat(data[5], 64)
	p.Last, _ = strconv.ParseFloat(data[6], 64)
	p.Date, _ = parseDate(data[7])

	return p
}
<commit_msg>Fix integer overflow on 32 bit systems<commit_after>package yquotes

import (
	"encoding/csv"
	"fmt"
	"net/http"
	"strconv"
	"time"
)

const (
	// URL of Yahoo quotes for stock quotes.
	YURL = "http://finance.yahoo.com/d/quotes.csv?s=%s&f=%s"

	// Base data formating.
	// s - symbol
	// n - name
	// b - bid
	// a - ask
	// o - open
	// p - previous price
	// l1 - last price without time
	// d1 - last trade date
	BaseFormat = "snbaopl1d1"

	// Historical data URL with params:
	// s - symbol
	// a - from month (zero based)
	// b - from day
	// c - from year
	// d - to month (zero based)
	// e - to day
	// f - to year
	// g - period frequence (d - daily, w - weekly, m - monthly, y -yearly)
	YURL_H = "http://ichart.yahoo.com/table.csv?s=%s&a=%d&b=%d&c=%d&d=%d&e=%d&f=%d&g=%s&ignore=.csv"
)

// Formatting constants.
const (
	Symbol   = "s"
	Name     = "n"
	Bid      = "b"
	Ask      = "a"
	Open     = "o"
	Previous = "p"
	Last     = "l1"
	LastDate = "d1"
)

// Constance of frequesncy for historical data requests.
const (
	Daily   = "d"
	Weekly  = "w"
	Monthly = "m"
	Yearly  = "y"
)

// Price struct represents price in single point in time.
type Price struct {
	Bid           float64   `json:"bid,omitempty"`
	Ask           float64   `json:"ask,omitempty"`
	Open          float64   `json:"open,omitempty"`
	PreviousClose float64   `json:"previousClose,omitempty"`
	Last          float64   `json:"last,omitempty"`
	Date          time.Time `json:"date,omitempty"`
}

// Price type that is used for historical price data.
type PriceH struct {
	Date     time.Time `json:"date,omitempty"`
	Open     float64   `json:"open,omitempty"`
	High     float64   `json:"high,omitempty"`
	Low      float64   `json:"low,omitempty"`
	Close    float64   `json:"close,omitempty"`
	Volume   float64   `json:"volume,omitempty"`
	AdjClose float64   `json:"adjClose,omitempty"`
}

// Stock is used as container for stock price data.
type Stock struct {
	// Symbol of stock that should meet requirements of Yahoo. Otherwise,
	// there will be no possibility to find stock.
	Symbol string `json:"symbol,omitempty"`

	// Name of the company will be filled from request of stock data.
	Name string `json:"name,omitempty"`

	// Information about last price of stock.
	Price *Price `json:"price,omitempty"`

	// Contains historical price information. If client asks information
	// for recent price, this field will be omited.
	History []PriceH `json:"history,omitempty"`
}

// Create new stock with recent price data and historical prices. All the prices
// are represented in daily basis.
//
// symbol - Symbol of company (ticker)
// history - If true 3 year price history will be loaded.
// Returns a pointer to value of Stock type.
func NewStock(symbol string, history bool) (*Stock, error) {
	var stock *Stock

	data, err := loadSingleStockPrice(symbol)
	if err != nil {
		return nil, err
	}
	stock = parseStock(data)

	// If history is TRUE, we need to load historical price for 3 year period.
	if history == true {
		histPrices, err := HistoryForYears(symbol, 3, Daily)
		if err != nil {
			return stock, err
		}
		stock.History = histPrices
	}

	return stock, nil
}

// Get single stock price data.
func GetPrice(symbol string) (*Price, error) {
	data, err := loadSingleStockPrice(symbol)
	if err != nil {
		return nil, err
	}

	price := parsePrice(data)
	return price, nil
}

// Get single stock price for certain date.
func GetPriceForDate(symbol string, date time.Time) (PriceH, error) {
	var price PriceH
	// We need to get price information for single date, so date passed to
	// this function will be used both for "from" and "to" arguments.
	data, err := loadHistoricalPrice(symbol, date, date, Daily)
	if err != nil {
		return price, err
	}

	prices, err := parseHistorical(data)
	if err != nil {
		return PriceH{}, err
	}
	price = prices[0]

	// Return single price.
	return price, nil
}

// Get historical prices for the stock.
func GetDailyHistory(symbol string, from, to time.Time) ([]PriceH, error) {
	var prices []PriceH
	// Create URL with daily frequency of data.
	data, err := loadHistoricalPrice(symbol, from, to, Daily)
	if err != nil {
		return prices, err
	}

	prices, err = parseHistorical(data)
	if err != nil {
		return prices, err
	}

	return prices, nil
}

// Get stock price history for number of years backwards.
func HistoryForYears(symbol string, years int, period string) ([]PriceH, error) {
	var prices []PriceH
	duration := time.Duration(int64(time.Hour) * 24 * 365 * int64(years))
	to := time.Now()
	from := to.Add(-duration)

	data, err := loadHistoricalPrice(symbol, from, to, period)
	if err != nil {
		return prices, err
	}

	prices, err = parseHistorical(data)
	if err != nil {
		return prices, err
	}

	return prices, nil
}

// Single company data request to Yahoo Finance.
func loadSingleStockPrice(symbol string) ([]string, error) {
	url := singleStockUrl(symbol)
	resp, err := http.Get(url)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	reader := csv.NewReader(resp.Body)
	data, err := reader.Read()
	if err != nil {
		return nil, err
	}

	return data, err
}

// Load historical data price.
func loadHistoricalPrice(symbol string, from, to time.Time, period string) ([][]string, error) {
	url := stockHistoryURL(symbol, from, to, period)
	var data [][]string

	resp, err := http.Get(url)
	if err != nil {
		return data, err
	}
	defer resp.Body.Close()

	reader := csv.NewReader(resp.Body)
	data, err = reader.ReadAll()
	if err != nil {
		return data, err
	}

	return data, nil
}

// Generate request URL for single stock.
func singleStockUrl(symbol string) string {
	url := fmt.Sprintf(YURL, symbol, BaseFormat)
	return url
}

// Generate request URL for historicat stock data.
func stockHistoryURL(symbol string, from, to time.Time, frequency string) string {
	// From date
	fMonth := (from.Month() - 1) // Need to subtract 1 because months in query is 0 based.
	fDay := from.Day()
	fYear := from.Year()
	// To date
	tMonth := (to.Month() - 1)
	tDay := to.Day()
	tYear := to.Year()

	url := fmt.Sprintf(
		YURL_H,
		symbol,
		fMonth,
		fDay,
		fYear,
		tMonth,
		tDay,
		tYear,
		frequency)

	return url
}

// Parse base information of stock price. Base inforamtion is reperesented by
// request format BaseFormat.
func parseStock(data []string) *Stock {
	s := &Stock{
		Symbol: data[0],
		Name:   data[1],
		Price:  parsePrice(data),
	}

	return s
}

// Parse collection of historical prices.
func parseHistorical(data [][]string) ([]PriceH, error) {
	// This is the list of prices with allocated space. Length of space should
	// subtracted by 1 because the first row of data is title.
	var list = make([]PriceH, len(data)-1)
	// We need to leave the first row, because it contains title of columns.
	for k, v := range data {
		if k == 0 {
			continue
		}
		// Parse row of data into PriceH type and append it to collection of prices.
		p, err := parseHistoricalRow(v)
		if err != nil {
			return list, err
		}

		// (k - 1) because we remove header from the list so index should be
		// reduced by one.
		list[k-1] = p
	}
	return list, nil
}

// Parse data row that comes from historical data. Data row contains
// 7 columns:
// 0 - Date
// 1 - Open
// 2 - High
// 3 - Low
// 4 - Close
// 5 - Volume
// 6 - Adj Close
// This function will return PriceH type that wraps all these columns.
func parseHistoricalRow(data []string) (PriceH, error) {
	p := PriceH{}

	// Parse date.
	d, err := time.Parse("2006-01-02", data[0])
	if err != nil {
		return p, err
	}

	p.Date = d
	p.Open, _ = strconv.ParseFloat(data[1], 64)
	p.High, _ = strconv.ParseFloat(data[2], 64)
	p.Low, _ = strconv.ParseFloat(data[3], 64)
	p.Close, _ = strconv.ParseFloat(data[4], 64)
	p.Volume, _ = strconv.ParseFloat(data[5], 64)
	p.AdjClose, _ = strconv.ParseFloat(data[6], 64)

	return p, nil
}

// Parse date from string into time.Time type.
func parseDate(date string) (time.Time, error) {
	d, err := time.Parse("1/2/2006", date)
	if err != nil {
		return time.Time{}, err
	}

	return d, nil
}

// Parse price information from base data.
func parsePrice(data []string) *Price {
	p := &Price{}
	p.Bid, _ = strconv.ParseFloat(data[2], 64)
	p.Ask, _ = strconv.ParseFloat(data[3], 64)
	p.Open, _ = strconv.ParseFloat(data[4], 64)
	p.PreviousClose, _ = strconv.ParseFloat(data[5], 64)
	p.Last, _ = strconv.ParseFloat(data[6], 64)
	p.Date, _ = parseDate(data[7])

	return p
}
<|endoftext|>


<commit_before>/*
Copyright 2018 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package podresources

import (
	"context"
	"reflect"
	"sort"
	"testing"

	"k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1"
	"k8s.io/kubernetes/pkg/kubelet/cm/cpuset"
	"k8s.io/kubernetes/pkg/kubelet/cm/devicemanager"
)

func TestListPodResourcesV1(t *testing.T) {
	podName := "pod-name"
	podNamespace := "pod-namespace"
	podUID := types.UID("pod-uid")
	containerName := "container-name"
	numaID := int64(1)

	devs := []*podresourcesapi.ContainerDevices{
		{
			ResourceName: "resource",
			DeviceIds:    []string{"dev0", "dev1"},
			Topology:     &podresourcesapi.TopologyInfo{Nodes: []*podresourcesapi.NUMANode{{ID: numaID}}},
		},
	}

	cpus := []int64{12, 23, 30}

	for _, tc := range []struct {
		desc             string
		pods             []*v1.Pod
		devices          []*podresourcesapi.ContainerDevices
		cpus             []int64
		expectedResponse *podresourcesapi.ListPodResourcesResponse
	}{
		{
			desc:             "no pods",
			pods:             []*v1.Pod{},
			devices:          []*podresourcesapi.ContainerDevices{},
			cpus:             []int64{},
			expectedResponse: &podresourcesapi.ListPodResourcesResponse{},
		},
		{
			desc: "pod without devices",
			pods: []*v1.Pod{
				{
					ObjectMeta: metav1.ObjectMeta{
						Name:      podName,
						Namespace: podNamespace,
						UID:       podUID,
					},
					Spec: v1.PodSpec{
						Containers: []v1.Container{
							{
								Name: containerName,
							},
						},
					},
				},
			},
			devices: []*podresourcesapi.ContainerDevices{},
			cpus:    []int64{},
			expectedResponse: &podresourcesapi.ListPodResourcesResponse{
				PodResources: []*podresourcesapi.PodResources{
					{
						Name:      podName,
						Namespace: podNamespace,
						Containers: []*podresourcesapi.ContainerResources{
							{
								Name:    containerName,
								Devices: []*podresourcesapi.ContainerDevices{},
							},
						},
					},
				},
			},
		},
		{
			desc: "pod with devices",
			pods: []*v1.Pod{
				{
					ObjectMeta: metav1.ObjectMeta{
						Name:      podName,
						Namespace: podNamespace,
						UID:       podUID,
					},
					Spec: v1.PodSpec{
						Containers: []v1.Container{
							{
								Name: containerName,
							},
						},
					},
				},
			},
			devices: devs,
			cpus:    cpus,
			expectedResponse: &podresourcesapi.ListPodResourcesResponse{
				PodResources: []*podresourcesapi.PodResources{
					{
						Name:      podName,
						Namespace: podNamespace,
						Containers: []*podresourcesapi.ContainerResources{
							{
								Name:    containerName,
								Devices: devs,
								CpuIds:  cpus,
							},
						},
					},
				},
			},
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			m := new(mockProvider)
			m.On("GetPods").Return(tc.pods)
			m.On("GetDevices", string(podUID), containerName).Return(tc.devices)
			m.On("GetCPUs", string(podUID), containerName).Return(tc.cpus)
			m.On("UpdateAllocatedDevices").Return()
			m.On("GetAllocatableCPUs").Return(cpuset.CPUSet{})
			m.On("GetAllocatableDevices").Return(devicemanager.NewResourceDeviceInstances())
			server := NewV1PodResourcesServer(m, m, m)
			resp, err := server.List(context.TODO(), &podresourcesapi.ListPodResourcesRequest{})
			if err != nil {
				t.Errorf("want err = %v, got %q", nil, err)
			}
			if !equalListResponse(tc.expectedResponse, resp) {
				t.Errorf("want resp = %s, got %s", tc.expectedResponse.String(), resp.String())
			}
		})
	}
}

func TestAllocatableResources(t *testing.T) {
	allDevs := []*podresourcesapi.ContainerDevices{
		{
			ResourceName: "resource",
			DeviceIds:    []string{"dev0"},
			Topology: &podresourcesapi.TopologyInfo{
				Nodes: []*podresourcesapi.NUMANode{
					{
						ID: 0,
					},
				},
			},
		},
		{
			ResourceName: "resource",
			DeviceIds:    []string{"dev1"},
			Topology: &podresourcesapi.TopologyInfo{
				Nodes: []*podresourcesapi.NUMANode{
					{
						ID: 1,
					},
				},
			},
		},
	}

	allCPUs := []int64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}

	for _, tc := range []struct {
		desc                                 string
		allCPUs                              []int64
		allDevices                           []*podresourcesapi.ContainerDevices
		expectedAllocatableResourcesResponse *podresourcesapi.AllocatableResourcesResponse
	}{
		{
			desc:                                 "no devices, no CPUs",
			allCPUs:                              []int64{},
			allDevices:                           []*podresourcesapi.ContainerDevices{},
			expectedAllocatableResourcesResponse: &podresourcesapi.AllocatableResourcesResponse{},
		},
		{
			desc:       "no devices, all CPUs",
			allCPUs:    allCPUs,
			allDevices: []*podresourcesapi.ContainerDevices{},
			expectedAllocatableResourcesResponse: &podresourcesapi.AllocatableResourcesResponse{
				CpuIds: allCPUs,
			},
		},
		{
			desc:       "with devices, all CPUs",
			allCPUs:    allCPUs,
			allDevices: allDevs,
			expectedAllocatableResourcesResponse: &podresourcesapi.AllocatableResourcesResponse{
				CpuIds: allCPUs,
				Devices: []*podresourcesapi.ContainerDevices{
					{
						ResourceName: "resource",
						DeviceIds:    []string{"dev0"},
						Topology: &podresourcesapi.TopologyInfo{
							Nodes: []*podresourcesapi.NUMANode{
								{
									ID: 0,
								},
							},
						},
					},
					{
						ResourceName: "resource",
						DeviceIds:    []string{"dev1"},
						Topology: &podresourcesapi.TopologyInfo{
							Nodes: []*podresourcesapi.NUMANode{
								{
									ID: 1,
								},
							},
						},
					},
				},
			},
		},
		{
			desc:       "with devices, no CPUs",
			allCPUs:    []int64{},
			allDevices: allDevs,
			expectedAllocatableResourcesResponse: &podresourcesapi.AllocatableResourcesResponse{
				Devices: []*podresourcesapi.ContainerDevices{
					{
						ResourceName: "resource",
						DeviceIds:    []string{"dev0"},
						Topology: &podresourcesapi.TopologyInfo{
							Nodes: []*podresourcesapi.NUMANode{
								{
									ID: 0,
								},
							},
						},
					},
					{
						ResourceName: "resource",
						DeviceIds:    []string{"dev1"},
						Topology: &podresourcesapi.TopologyInfo{
							Nodes: []*podresourcesapi.NUMANode{
								{
									ID: 1,
								},
							},
						},
					},
				},
			},
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			m := new(mockProvider)
			m.On("GetDevices", "", "").Return([]*podresourcesapi.ContainerDevices{})
			m.On("GetCPUs", "", "").Return([]int64{})
			m.On("UpdateAllocatedDevices").Return()
			m.On("GetAllocatableDevices").Return(tc.allDevices)
			m.On("GetAllocatableCPUs").Return(tc.allCPUs)
			server := NewV1PodResourcesServer(m, m, m)

			resp, err := server.GetAllocatableResources(context.TODO(), &podresourcesapi.AllocatableResourcesRequest{})
			if err != nil {
				t.Errorf("want err = %v, got %q", nil, err)
			}

			if !equalAllocatableResourcesResponse(tc.expectedAllocatableResourcesResponse, resp) {
				t.Errorf("want resp = %s, got %s", tc.expectedAllocatableResourcesResponse.String(), resp.String())
			}
		})
	}
}

func equalListResponse(respA, respB *podresourcesapi.ListPodResourcesResponse) bool {
	if len(respA.PodResources) != len(respB.PodResources) {
		return false
	}
	for idx := 0; idx < len(respA.PodResources); idx++ {
		podResA := respA.PodResources[idx]
		podResB := respB.PodResources[idx]
		if podResA.Name != podResB.Name {
			return false
		}
		if podResA.Namespace != podResB.Namespace {
			return false
		}
		if len(podResA.Containers) != len(podResB.Containers) {
			return false
		}
		for jdx := 0; jdx < len(podResA.Containers); jdx++ {
			cntA := podResA.Containers[jdx]
			cntB := podResB.Containers[jdx]

			if cntA.Name != cntB.Name {
				return false
			}
			if !equalInt64s(cntA.CpuIds, cntB.CpuIds) {
				return false
			}

			if !equalContainerDevices(cntA.Devices, cntB.Devices) {
				return false
			}
		}
	}
	return true
}

func equalContainerDevices(devA, devB []*podresourcesapi.ContainerDevices) bool {
	if len(devA) != len(devB) {
		return false
	}

	for idx := 0; idx < len(devA); idx++ {
		cntDevA := devA[idx]
		cntDevB := devB[idx]

		if cntDevA.ResourceName != cntDevB.ResourceName {
			return false
		}
		if !equalTopology(cntDevA.Topology, cntDevB.Topology) {
			return false
		}
		if !equalStrings(cntDevA.DeviceIds, cntDevB.DeviceIds) {
			return false
		}
	}

	return true
}

func equalInt64s(a, b []int64) bool {
	if len(a) != len(b) {
		return false
	}
	aCopy := append([]int64{}, a...)
	sort.Slice(aCopy, func(i, j int) bool { return aCopy[i] < aCopy[j] })
	bCopy := append([]int64{}, b...)
	sort.Slice(bCopy, func(i, j int) bool { return bCopy[i] < bCopy[j] })
	return reflect.DeepEqual(aCopy, bCopy)
}

func equalStrings(a, b []string) bool {
	if len(a) != len(b) {
		return false
	}
	aCopy := append([]string{}, a...)
	sort.Strings(aCopy)
	bCopy := append([]string{}, b...)
	sort.Strings(bCopy)
	return reflect.DeepEqual(aCopy, bCopy)
}

func equalTopology(a, b *podresourcesapi.TopologyInfo) bool {
	if a == nil && b != nil {
		return false
	}
	if a != nil && b == nil {
		return false
	}
	return reflect.DeepEqual(a, b)
}

func equalAllocatableResourcesResponse(respA, respB *podresourcesapi.AllocatableResourcesResponse) bool {
	if !equalInt64s(respA.CpuIds, respB.CpuIds) {
		return false
	}
	return equalContainerDevices(respA.Devices, respB.Devices)
}
<commit_msg>podresources: test: add test for nil Topology<commit_after>/*
Copyright 2018 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package podresources

import (
	"context"
	"reflect"
	"sort"
	"testing"

	"k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/types"
	podresourcesapi "k8s.io/kubelet/pkg/apis/podresources/v1"
	"k8s.io/kubernetes/pkg/kubelet/cm/cpuset"
	"k8s.io/kubernetes/pkg/kubelet/cm/devicemanager"
)

func TestListPodResourcesV1(t *testing.T) {
	podName := "pod-name"
	podNamespace := "pod-namespace"
	podUID := types.UID("pod-uid")
	containerName := "container-name"
	numaID := int64(1)

	devs := []*podresourcesapi.ContainerDevices{
		{
			ResourceName: "resource",
			DeviceIds:    []string{"dev0", "dev1"},
			Topology:     &podresourcesapi.TopologyInfo{Nodes: []*podresourcesapi.NUMANode{{ID: numaID}}},
		},
	}

	cpus := []int64{12, 23, 30}

	for _, tc := range []struct {
		desc             string
		pods             []*v1.Pod
		devices          []*podresourcesapi.ContainerDevices
		cpus             []int64
		expectedResponse *podresourcesapi.ListPodResourcesResponse
	}{
		{
			desc:             "no pods",
			pods:             []*v1.Pod{},
			devices:          []*podresourcesapi.ContainerDevices{},
			cpus:             []int64{},
			expectedResponse: &podresourcesapi.ListPodResourcesResponse{},
		},
		{
			desc: "pod without devices",
			pods: []*v1.Pod{
				{
					ObjectMeta: metav1.ObjectMeta{
						Name:      podName,
						Namespace: podNamespace,
						UID:       podUID,
					},
					Spec: v1.PodSpec{
						Containers: []v1.Container{
							{
								Name: containerName,
							},
						},
					},
				},
			},
			devices: []*podresourcesapi.ContainerDevices{},
			cpus:    []int64{},
			expectedResponse: &podresourcesapi.ListPodResourcesResponse{
				PodResources: []*podresourcesapi.PodResources{
					{
						Name:      podName,
						Namespace: podNamespace,
						Containers: []*podresourcesapi.ContainerResources{
							{
								Name:    containerName,
								Devices: []*podresourcesapi.ContainerDevices{},
							},
						},
					},
				},
			},
		},
		{
			desc: "pod with devices",
			pods: []*v1.Pod{
				{
					ObjectMeta: metav1.ObjectMeta{
						Name:      podName,
						Namespace: podNamespace,
						UID:       podUID,
					},
					Spec: v1.PodSpec{
						Containers: []v1.Container{
							{
								Name: containerName,
							},
						},
					},
				},
			},
			devices: devs,
			cpus:    cpus,
			expectedResponse: &podresourcesapi.ListPodResourcesResponse{
				PodResources: []*podresourcesapi.PodResources{
					{
						Name:      podName,
						Namespace: podNamespace,
						Containers: []*podresourcesapi.ContainerResources{
							{
								Name:    containerName,
								Devices: devs,
								CpuIds:  cpus,
							},
						},
					},
				},
			},
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			m := new(mockProvider)
			m.On("GetPods").Return(tc.pods)
			m.On("GetDevices", string(podUID), containerName).Return(tc.devices)
			m.On("GetCPUs", string(podUID), containerName).Return(tc.cpus)
			m.On("UpdateAllocatedDevices").Return()
			m.On("GetAllocatableCPUs").Return(cpuset.CPUSet{})
			m.On("GetAllocatableDevices").Return(devicemanager.NewResourceDeviceInstances())
			server := NewV1PodResourcesServer(m, m, m)
			resp, err := server.List(context.TODO(), &podresourcesapi.ListPodResourcesRequest{})
			if err != nil {
				t.Errorf("want err = %v, got %q", nil, err)
			}
			if !equalListResponse(tc.expectedResponse, resp) {
				t.Errorf("want resp = %s, got %s", tc.expectedResponse.String(), resp.String())
			}
		})
	}
}

func TestAllocatableResources(t *testing.T) {
	allDevs := []*podresourcesapi.ContainerDevices{
		{
			ResourceName: "resource",
			DeviceIds:    []string{"dev0"},
			Topology: &podresourcesapi.TopologyInfo{
				Nodes: []*podresourcesapi.NUMANode{
					{
						ID: 0,
					},
				},
			},
		},
		{
			ResourceName: "resource",
			DeviceIds:    []string{"dev1"},
			Topology: &podresourcesapi.TopologyInfo{
				Nodes: []*podresourcesapi.NUMANode{
					{
						ID: 1,
					},
				},
			},
		},
		{
			ResourceName: "resource-nt",
			DeviceIds:    []string{"devA"},
		},
	}

	allCPUs := []int64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}

	for _, tc := range []struct {
		desc                                 string
		allCPUs                              []int64
		allDevices                           []*podresourcesapi.ContainerDevices
		expectedAllocatableResourcesResponse *podresourcesapi.AllocatableResourcesResponse
	}{
		{
			desc:                                 "no devices, no CPUs",
			allCPUs:                              []int64{},
			allDevices:                           []*podresourcesapi.ContainerDevices{},
			expectedAllocatableResourcesResponse: &podresourcesapi.AllocatableResourcesResponse{},
		},
		{
			desc:       "no devices, all CPUs",
			allCPUs:    allCPUs,
			allDevices: []*podresourcesapi.ContainerDevices{},
			expectedAllocatableResourcesResponse: &podresourcesapi.AllocatableResourcesResponse{
				CpuIds: allCPUs,
			},
		},
		{
			desc:       "with devices, all CPUs",
			allCPUs:    allCPUs,
			allDevices: allDevs,
			expectedAllocatableResourcesResponse: &podresourcesapi.AllocatableResourcesResponse{
				CpuIds: allCPUs,
				Devices: []*podresourcesapi.ContainerDevices{
					{
						ResourceName: "resource",
						DeviceIds:    []string{"dev0"},
						Topology: &podresourcesapi.TopologyInfo{
							Nodes: []*podresourcesapi.NUMANode{
								{
									ID: 0,
								},
							},
						},
					},
					{
						ResourceName: "resource",
						DeviceIds:    []string{"dev1"},
						Topology: &podresourcesapi.TopologyInfo{
							Nodes: []*podresourcesapi.NUMANode{
								{
									ID: 1,
								},
							},
						},
					},
					{
						ResourceName: "resource-nt",
						DeviceIds:    []string{"devA"},
					},
				},
			},
		},
		{
			desc:       "with devices, no CPUs",
			allCPUs:    []int64{},
			allDevices: allDevs,
			expectedAllocatableResourcesResponse: &podresourcesapi.AllocatableResourcesResponse{
				Devices: []*podresourcesapi.ContainerDevices{
					{
						ResourceName: "resource",
						DeviceIds:    []string{"dev0"},
						Topology: &podresourcesapi.TopologyInfo{
							Nodes: []*podresourcesapi.NUMANode{
								{
									ID: 0,
								},
							},
						},
					},
					{
						ResourceName: "resource",
						DeviceIds:    []string{"dev1"},
						Topology: &podresourcesapi.TopologyInfo{
							Nodes: []*podresourcesapi.NUMANode{
								{
									ID: 1,
								},
							},
						},
					},
					{
						ResourceName: "resource-nt",
						DeviceIds:    []string{"devA"},
					},
				},
			},
		},
	} {
		t.Run(tc.desc, func(t *testing.T) {
			m := new(mockProvider)
			m.On("GetDevices", "", "").Return([]*podresourcesapi.ContainerDevices{})
			m.On("GetCPUs", "", "").Return([]int64{})
			m.On("UpdateAllocatedDevices").Return()
			m.On("GetAllocatableDevices").Return(tc.allDevices)
			m.On("GetAllocatableCPUs").Return(tc.allCPUs)
			server := NewV1PodResourcesServer(m, m, m)

			resp, err := server.GetAllocatableResources(context.TODO(), &podresourcesapi.AllocatableResourcesRequest{})
			if err != nil {
				t.Errorf("want err = %v, got %q", nil, err)
			}

			if !equalAllocatableResourcesResponse(tc.expectedAllocatableResourcesResponse, resp) {
				t.Errorf("want resp = %s, got %s", tc.expectedAllocatableResourcesResponse.String(), resp.String())
			}
		})
	}
}

func equalListResponse(respA, respB *podresourcesapi.ListPodResourcesResponse) bool {
	if len(respA.PodResources) != len(respB.PodResources) {
		return false
	}
	for idx := 0; idx < len(respA.PodResources); idx++ {
		podResA := respA.PodResources[idx]
		podResB := respB.PodResources[idx]
		if podResA.Name != podResB.Name {
			return false
		}
		if podResA.Namespace != podResB.Namespace {
			return false
		}
		if len(podResA.Containers) != len(podResB.Containers) {
			return false
		}
		for jdx := 0; jdx < len(podResA.Containers); jdx++ {
			cntA := podResA.Containers[jdx]
			cntB := podResB.Containers[jdx]

			if cntA.Name != cntB.Name {
				return false
			}
			if !equalInt64s(cntA.CpuIds, cntB.CpuIds) {
				return false
			}

			if !equalContainerDevices(cntA.Devices, cntB.Devices) {
				return false
			}
		}
	}
	return true
}

func equalContainerDevices(devA, devB []*podresourcesapi.ContainerDevices) bool {
	if len(devA) != len(devB) {
		return false
	}

	for idx := 0; idx < len(devA); idx++ {
		cntDevA := devA[idx]
		cntDevB := devB[idx]

		if cntDevA.ResourceName != cntDevB.ResourceName {
			return false
		}
		if !equalTopology(cntDevA.Topology, cntDevB.Topology) {
			return false
		}
		if !equalStrings(cntDevA.DeviceIds, cntDevB.DeviceIds) {
			return false
		}
	}

	return true
}

func equalInt64s(a, b []int64) bool {
	if len(a) != len(b) {
		return false
	}
	aCopy := append([]int64{}, a...)
	sort.Slice(aCopy, func(i, j int) bool { return aCopy[i] < aCopy[j] })
	bCopy := append([]int64{}, b...)
	sort.Slice(bCopy, func(i, j int) bool { return bCopy[i] < bCopy[j] })
	return reflect.DeepEqual(aCopy, bCopy)
}

func equalStrings(a, b []string) bool {
	if len(a) != len(b) {
		return false
	}
	aCopy := append([]string{}, a...)
	sort.Strings(aCopy)
	bCopy := append([]string{}, b...)
	sort.Strings(bCopy)
	return reflect.DeepEqual(aCopy, bCopy)
}

func equalTopology(a, b *podresourcesapi.TopologyInfo) bool {
	if a == nil && b != nil {
		return false
	}
	if a != nil && b == nil {
		return false
	}
	return reflect.DeepEqual(a, b)
}

func equalAllocatableResourcesResponse(respA, respB *podresourcesapi.AllocatableResourcesResponse) bool {
	if !equalInt64s(respA.CpuIds, respB.CpuIds) {
		return false
	}
	return equalContainerDevices(respA.Devices, respB.Devices)
}
<|endoftext|>


<commit_before>/*
 * This file is part of the KubeVirt project
 *
 * 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.
 *
 * Copyright 2017, 2018 Red Hat, Inc.
 *
 */

package cmdserver

import (
	"fmt"
	"os"
	"time"

	"golang.org/x/net/context"
	"google.golang.org/grpc"

	"k8s.io/apimachinery/pkg/util/json"

	v1 "kubevirt.io/client-go/api/v1"
	"kubevirt.io/client-go/log"
	cmdv1 "kubevirt.io/kubevirt/pkg/handler-launcher-com/cmd/v1"
	grpcutil "kubevirt.io/kubevirt/pkg/util/net/grpc"
	cmdclient "kubevirt.io/kubevirt/pkg/virt-handler/cmd-client"
	"kubevirt.io/kubevirt/pkg/virt-launcher/virtwrap"
	launcherErrors "kubevirt.io/kubevirt/pkg/virt-launcher/virtwrap/errors"
)

type ServerOptions struct {
	useEmulation bool
}

func NewServerOptions(useEmulation bool) *ServerOptions {
	return &ServerOptions{useEmulation: useEmulation}
}

type Launcher struct {
	domainManager virtwrap.DomainManager
	useEmulation  bool
}

func getVMIFromRequest(request *cmdv1.VMI) (*v1.VirtualMachineInstance, *cmdv1.Response) {

	response := &cmdv1.Response{
		Success: true,
	}

	var vmi v1.VirtualMachineInstance
	if err := json.Unmarshal(request.VmiJson, &vmi); err != nil {
		response.Success = false
		response.Message = "No valid vmi object present in command server request"
	}

	return &vmi, response
}

func getMigrationOptionsFromRequest(request *cmdv1.MigrationRequest) (*cmdclient.MigrationOptions, error) {

	if request.Options == nil {
		return nil, fmt.Errorf("migration options object not present in command server request")
	}

	var options *cmdclient.MigrationOptions
	if err := json.Unmarshal(request.Options, &options); err != nil {
		return nil, fmt.Errorf("no valid migration options object present in command server request: %v", err)
	}

	return options, nil
}

func getErrorMessage(err error) string {
	if virErr := launcherErrors.FormatLibvirtError(err); virErr != "" {
		return virErr
	}
	return err.Error()
}

func (l *Launcher) MigrateVirtualMachine(ctx context.Context, request *cmdv1.MigrationRequest) (*cmdv1.Response, error) {

	vmi, response := getVMIFromRequest(request.Vmi)
	if !response.Success {
		return response, nil
	}

	options, err := getMigrationOptionsFromRequest(request)
	if err != nil {
		response.Success = false
		response.Message = err.Error()
		return response, nil
	}

	if err := l.domainManager.MigrateVMI(vmi, options); err != nil {
		log.Log.Object(vmi).Reason(err).Errorf("Failed to migrate vmi")
		response.Success = false
		response.Message = getErrorMessage(err)
		return response, nil
	}

	log.Log.Object(vmi).Info("Signaled vmi migration")
	return response, nil
}

func (l *Launcher) CancelVirtualMachineMigration(ctx context.Context, request *cmdv1.VMIRequest) (*cmdv1.Response, error) {

	vmi, response := getVMIFromRequest(request.Vmi)
	if !response.Success {
		return response, nil
	}

	if err := l.domainManager.CancelVMIMigration(vmi); err != nil {
		log.Log.Object(vmi).Reason(err).Errorf("Failed to abort live migration")
		response.Success = false
		response.Message = getErrorMessage(err)
		return response, nil
	}

	log.Log.Object(vmi).Info("Live migration as been aborted")
	return response, nil

}

func (l *Launcher) SyncMigrationTarget(ctx context.Context, request *cmdv1.VMIRequest) (*cmdv1.Response, error) {

	vmi, response := getVMIFromRequest(request.Vmi)
	if !response.Success {
		return response, nil
	}

	if err := l.domainManager.PrepareMigrationTarget(vmi, l.useEmulation); err != nil {
		log.Log.Object(vmi).Reason(err).Errorf("Failed to prepare migration target pod")
		response.Success = false
		response.Message = getErrorMessage(err)
		return response, nil
	}

	log.Log.Object(vmi).Info("Prepared migration target pod")
	return response, nil

}

func (l *Launcher) SyncVirtualMachine(ctx context.Context, request *cmdv1.VMIRequest) (*cmdv1.Response, error) {

	vmi, response := getVMIFromRequest(request.Vmi)
	if !response.Success {
		return response, nil
	}

	if _, err := l.domainManager.SyncVMI(vmi, l.useEmulation, request.Options); err != nil {
		log.Log.Object(vmi).Reason(err).Errorf("Failed to sync vmi")
		response.Success = false
		response.Message = getErrorMessage(err)
		return response, nil
	}

	log.Log.Object(vmi).Info("Synced vmi")
	return response, nil
}

func (l *Launcher) KillVirtualMachine(ctx context.Context, request *cmdv1.VMIRequest) (*cmdv1.Response, error) {

	vmi, response := getVMIFromRequest(request.Vmi)
	if !response.Success {
		return response, nil
	}

	if err := l.domainManager.KillVMI(vmi); err != nil {
		log.Log.Object(vmi).Reason(err).Errorf("Failed to kill vmi")
		response.Success = false
		response.Message = getErrorMessage(err)
		return response, nil
	}

	log.Log.Object(vmi).Info("Signaled vmi kill")
	return response, nil
}

func (l *Launcher) ShutdownVirtualMachine(ctx context.Context, request *cmdv1.VMIRequest) (*cmdv1.Response, error) {

	vmi, response := getVMIFromRequest(request.Vmi)
	if !response.Success {
		return response, nil
	}

	if err := l.domainManager.SignalShutdownVMI(vmi); err != nil {
		log.Log.Object(vmi).Reason(err).Errorf("Failed to signal shutdown for vmi")
		response.Success = false
		response.Message = getErrorMessage(err)
		return response, nil
	}

	log.Log.Object(vmi).Info("Signaled vmi shutdown")
	return response, nil
}

func (l *Launcher) DeleteVirtualMachine(ctx context.Context, request *cmdv1.VMIRequest) (*cmdv1.Response, error) {

	vmi, response := getVMIFromRequest(request.Vmi)
	if !response.Success {
		return response, nil
	}

	if err := l.domainManager.DeleteVMI(vmi); err != nil {
		log.Log.Object(vmi).Reason(err).Errorf("Failed to signal deletion for vmi")
		response.Success = false
		response.Message = getErrorMessage(err)
		return response, nil
	}

	log.Log.Object(vmi).Info("Signaled vmi deletion")
	return response, nil
}

func (l *Launcher) GetDomain(ctx context.Context, request *cmdv1.EmptyRequest) (*cmdv1.DomainResponse, error) {

	response := &cmdv1.DomainResponse{
		Response: &cmdv1.Response{
			Success: true,
		},
	}

	list, err := l.domainManager.ListAllDomains()
	if err != nil {
		response.Response.Success = false
		response.Response.Message = getErrorMessage(err)
		return response, nil
	}

	if len(list) >= 0 {
		if domain, err := json.Marshal(list[0]); err != nil {
			log.Log.Reason(err).Errorf("Failed to marshal domain")
			response.Response.Success = false
			response.Response.Message = getErrorMessage(err)
			return response, nil
		} else {
			response.Domain = string(domain)
		}
	}

	return response, nil
}

func (l *Launcher) GetDomainStats(ctx context.Context, request *cmdv1.EmptyRequest) (*cmdv1.DomainStatsResponse, error) {

	response := &cmdv1.DomainStatsResponse{
		Response: &cmdv1.Response{
			Success: true,
		},
	}

	list, err := l.domainManager.GetDomainStats()
	if err != nil {
		response.Response.Success = false
		response.Response.Message = getErrorMessage(err)
		return response, nil
	}

	if len(list) >= 0 {
		if domainStats, err := json.Marshal(list[0]); err != nil {
			log.Log.Reason(err).Errorf("Failed to marshal domain stats")
			response.Response.Success = false
			response.Response.Message = getErrorMessage(err)
			return response, nil
		} else {
			response.DomainStats = string(domainStats)
		}
	}

	return response, nil
}

func RunServer(socketPath string,
	domainManager virtwrap.DomainManager,
	stopChan chan struct{},
	options *ServerOptions) (chan struct{}, error) {

	useEmulation := false
	if options != nil {
		useEmulation = options.useEmulation
	}

	grpcServer := grpc.NewServer([]grpc.ServerOption{}...)
	server := &Launcher{
		domainManager: domainManager,
		useEmulation:  useEmulation,
	}
	registerInfoServer(grpcServer)

	// register more versions as soon as needed
	// and add them to info.go
	cmdv1.RegisterCmdServer(grpcServer, server)

	sock, err := grpcutil.CreateSocket(socketPath)
	if err != nil {
		return nil, err
	}

	done := make(chan struct{})

	go func() {
		select {
		case <-stopChan:
			log.Log.Info("stopping cmd server")
			stopped := make(chan struct{})
			go func() {
				grpcServer.Stop()
				close(stopped)
			}()

			select {
			case <-stopped:
				log.Log.Info("cmd server stopped")
			case <-time.After(1 * time.Second):
				log.Log.Error("timeout on stopping the cmd server, continuing anyway.")
			}
			sock.Close()
			os.Remove(socketPath)
			close(done)
		}
	}()

	go func() {
		grpcServer.Serve(sock)
	}()

	return done, nil
}

func (l *Launcher) Ping(ctx context.Context, request *cmdv1.EmptyRequest) (*cmdv1.Response, error) {
	response := &cmdv1.Response{
		Success: true,
	}
	return response, nil
}
<commit_msg>Fix boundary condition for DomainStats<commit_after>/*
 * This file is part of the KubeVirt project
 *
 * 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.
 *
 * Copyright 2017, 2018 Red Hat, Inc.
 *
 */

package cmdserver

import (
	"fmt"
	"os"
	"time"

	"golang.org/x/net/context"
	"google.golang.org/grpc"

	"k8s.io/apimachinery/pkg/util/json"

	v1 "kubevirt.io/client-go/api/v1"
	"kubevirt.io/client-go/log"
	cmdv1 "kubevirt.io/kubevirt/pkg/handler-launcher-com/cmd/v1"
	grpcutil "kubevirt.io/kubevirt/pkg/util/net/grpc"
	cmdclient "kubevirt.io/kubevirt/pkg/virt-handler/cmd-client"
	"kubevirt.io/kubevirt/pkg/virt-launcher/virtwrap"
	launcherErrors "kubevirt.io/kubevirt/pkg/virt-launcher/virtwrap/errors"
)

type ServerOptions struct {
	useEmulation bool
}

func NewServerOptions(useEmulation bool) *ServerOptions {
	return &ServerOptions{useEmulation: useEmulation}
}

type Launcher struct {
	domainManager virtwrap.DomainManager
	useEmulation  bool
}

func getVMIFromRequest(request *cmdv1.VMI) (*v1.VirtualMachineInstance, *cmdv1.Response) {

	response := &cmdv1.Response{
		Success: true,
	}

	var vmi v1.VirtualMachineInstance
	if err := json.Unmarshal(request.VmiJson, &vmi); err != nil {
		response.Success = false
		response.Message = "No valid vmi object present in command server request"
	}

	return &vmi, response
}

func getMigrationOptionsFromRequest(request *cmdv1.MigrationRequest) (*cmdclient.MigrationOptions, error) {

	if request.Options == nil {
		return nil, fmt.Errorf("migration options object not present in command server request")
	}

	var options *cmdclient.MigrationOptions
	if err := json.Unmarshal(request.Options, &options); err != nil {
		return nil, fmt.Errorf("no valid migration options object present in command server request: %v", err)
	}

	return options, nil
}

func getErrorMessage(err error) string {
	if virErr := launcherErrors.FormatLibvirtError(err); virErr != "" {
		return virErr
	}
	return err.Error()
}

func (l *Launcher) MigrateVirtualMachine(ctx context.Context, request *cmdv1.MigrationRequest) (*cmdv1.Response, error) {

	vmi, response := getVMIFromRequest(request.Vmi)
	if !response.Success {
		return response, nil
	}

	options, err := getMigrationOptionsFromRequest(request)
	if err != nil {
		response.Success = false
		response.Message = err.Error()
		return response, nil
	}

	if err := l.domainManager.MigrateVMI(vmi, options); err != nil {
		log.Log.Object(vmi).Reason(err).Errorf("Failed to migrate vmi")
		response.Success = false
		response.Message = getErrorMessage(err)
		return response, nil
	}

	log.Log.Object(vmi).Info("Signaled vmi migration")
	return response, nil
}

func (l *Launcher) CancelVirtualMachineMigration(ctx context.Context, request *cmdv1.VMIRequest) (*cmdv1.Response, error) {

	vmi, response := getVMIFromRequest(request.Vmi)
	if !response.Success {
		return response, nil
	}

	if err := l.domainManager.CancelVMIMigration(vmi); err != nil {
		log.Log.Object(vmi).Reason(err).Errorf("Failed to abort live migration")
		response.Success = false
		response.Message = getErrorMessage(err)
		return response, nil
	}

	log.Log.Object(vmi).Info("Live migration as been aborted")
	return response, nil

}

func (l *Launcher) SyncMigrationTarget(ctx context.Context, request *cmdv1.VMIRequest) (*cmdv1.Response, error) {

	vmi, response := getVMIFromRequest(request.Vmi)
	if !response.Success {
		return response, nil
	}

	if err := l.domainManager.PrepareMigrationTarget(vmi, l.useEmulation); err != nil {
		log.Log.Object(vmi).Reason(err).Errorf("Failed to prepare migration target pod")
		response.Success = false
		response.Message = getErrorMessage(err)
		return response, nil
	}

	log.Log.Object(vmi).Info("Prepared migration target pod")
	return response, nil

}

func (l *Launcher) SyncVirtualMachine(ctx context.Context, request *cmdv1.VMIRequest) (*cmdv1.Response, error) {

	vmi, response := getVMIFromRequest(request.Vmi)
	if !response.Success {
		return response, nil
	}

	if _, err := l.domainManager.SyncVMI(vmi, l.useEmulation, request.Options); err != nil {
		log.Log.Object(vmi).Reason(err).Errorf("Failed to sync vmi")
		response.Success = false
		response.Message = getErrorMessage(err)
		return response, nil
	}

	log.Log.Object(vmi).Info("Synced vmi")
	return response, nil
}

func (l *Launcher) KillVirtualMachine(ctx context.Context, request *cmdv1.VMIRequest) (*cmdv1.Response, error) {

	vmi, response := getVMIFromRequest(request.Vmi)
	if !response.Success {
		return response, nil
	}

	if err := l.domainManager.KillVMI(vmi); err != nil {
		log.Log.Object(vmi).Reason(err).Errorf("Failed to kill vmi")
		response.Success = false
		response.Message = getErrorMessage(err)
		return response, nil
	}

	log.Log.Object(vmi).Info("Signaled vmi kill")
	return response, nil
}

func (l *Launcher) ShutdownVirtualMachine(ctx context.Context, request *cmdv1.VMIRequest) (*cmdv1.Response, error) {

	vmi, response := getVMIFromRequest(request.Vmi)
	if !response.Success {
		return response, nil
	}

	if err := l.domainManager.SignalShutdownVMI(vmi); err != nil {
		log.Log.Object(vmi).Reason(err).Errorf("Failed to signal shutdown for vmi")
		response.Success = false
		response.Message = getErrorMessage(err)
		return response, nil
	}

	log.Log.Object(vmi).Info("Signaled vmi shutdown")
	return response, nil
}

func (l *Launcher) DeleteVirtualMachine(ctx context.Context, request *cmdv1.VMIRequest) (*cmdv1.Response, error) {

	vmi, response := getVMIFromRequest(request.Vmi)
	if !response.Success {
		return response, nil
	}

	if err := l.domainManager.DeleteVMI(vmi); err != nil {
		log.Log.Object(vmi).Reason(err).Errorf("Failed to signal deletion for vmi")
		response.Success = false
		response.Message = getErrorMessage(err)
		return response, nil
	}

	log.Log.Object(vmi).Info("Signaled vmi deletion")
	return response, nil
}

func (l *Launcher) GetDomain(ctx context.Context, request *cmdv1.EmptyRequest) (*cmdv1.DomainResponse, error) {

	response := &cmdv1.DomainResponse{
		Response: &cmdv1.Response{
			Success: true,
		},
	}

	list, err := l.domainManager.ListAllDomains()
	if err != nil {
		response.Response.Success = false
		response.Response.Message = getErrorMessage(err)
		return response, nil
	}

	if len(list) >= 0 {
		if domain, err := json.Marshal(list[0]); err != nil {
			log.Log.Reason(err).Errorf("Failed to marshal domain")
			response.Response.Success = false
			response.Response.Message = getErrorMessage(err)
			return response, nil
		} else {
			response.Domain = string(domain)
		}
	}

	return response, nil
}

func (l *Launcher) GetDomainStats(ctx context.Context, request *cmdv1.EmptyRequest) (*cmdv1.DomainStatsResponse, error) {

	response := &cmdv1.DomainStatsResponse{
		Response: &cmdv1.Response{
			Success: true,
		},
	}

	list, err := l.domainManager.GetDomainStats()
	if err != nil {
		response.Response.Success = false
		response.Response.Message = getErrorMessage(err)
		return response, nil
	}

	if len(list) > 0 {
		if domainStats, err := json.Marshal(list[0]); err != nil {
			log.Log.Reason(err).Errorf("Failed to marshal domain stats")
			response.Response.Success = false
			response.Response.Message = getErrorMessage(err)
			return response, nil
		} else {
			response.DomainStats = string(domainStats)
		}
	}

	return response, nil
}

func RunServer(socketPath string,
	domainManager virtwrap.DomainManager,
	stopChan chan struct{},
	options *ServerOptions) (chan struct{}, error) {

	useEmulation := false
	if options != nil {
		useEmulation = options.useEmulation
	}

	grpcServer := grpc.NewServer([]grpc.ServerOption{}...)
	server := &Launcher{
		domainManager: domainManager,
		useEmulation:  useEmulation,
	}
	registerInfoServer(grpcServer)

	// register more versions as soon as needed
	// and add them to info.go
	cmdv1.RegisterCmdServer(grpcServer, server)

	sock, err := grpcutil.CreateSocket(socketPath)
	if err != nil {
		return nil, err
	}

	done := make(chan struct{})

	go func() {
		select {
		case <-stopChan:
			log.Log.Info("stopping cmd server")
			stopped := make(chan struct{})
			go func() {
				grpcServer.Stop()
				close(stopped)
			}()

			select {
			case <-stopped:
				log.Log.Info("cmd server stopped")
			case <-time.After(1 * time.Second):
				log.Log.Error("timeout on stopping the cmd server, continuing anyway.")
			}
			sock.Close()
			os.Remove(socketPath)
			close(done)
		}
	}()

	go func() {
		grpcServer.Serve(sock)
	}()

	return done, nil
}

func (l *Launcher) Ping(ctx context.Context, request *cmdv1.EmptyRequest) (*cmdv1.Response, error) {
	response := &cmdv1.Response{
		Success: true,
	}
	return response, nil
}
<|endoftext|>


<commit_before>package kinsokujiko

import (
	"errors"

	"github.com/ikawaha/kagome/tokenizer"
	"github.com/sys-cat/kinsokujiko/targets"
)

type (
	// Master is Master data for analyze
	Master struct {
		Sentence string
	}

	// Surface is surface, pos pair
	Surface struct {
		Surf string
		Pos  string
	}

	// Surfaces is Slice any Surface
	Surfaces []Surface
)

// Run is Masking Sentence what use Tokenize method.
func Run(s Master, t targets.Targets) (string, error) {
	return "", errors.New("anything is bad")
}

// Tokenize is analyze sentence method
func Tokenize(s Master, path string) Surfaces {
	var udic tokenizer.UserDic
	if path != "" {
		udic, err := tokenizer.NewUserDic(path)
		if err != nil {
			return Surfaces{}
		}
	}
	t := tokenizer.NewWithDic(tokenizer.SysDic())
	t.SetUserDic(udic)
	if udic != tokenizer.UserDic {
		return Surfaces{}
	}
	tokens := t.Analyze(s.Sentence, tokenizer.Normal)
	var surf Surfaces
	for _, token := range tokens {
		if token.Pos() != "" {
			surf = append(surf, Surface{token.Surface, token.Pos()})
		}
	}
	return surf
}

// AddDictionary is Create User Dictionary
func AddDictionary(dic Dictionary) (bool, error) {
	if err := insertItem(dic); err != nil {
		return false, err
	}
	return true, errors.New("")
}

func insertItem(dic Dictionary) error {
	// anything to Create User Dictionary
	return errors.New("anything is bad")
}
<commit_msg>use NewUserDic<commit_after>package kinsokujiko

import (
	"errors"
	"log"

	"github.com/ikawaha/kagome/tokenizer"
	"github.com/sys-cat/kinsokujiko/targets"
)

type (
	// Master is Master data for analyze
	Master struct {
		Sentence string
	}

	// Surface is surface, pos pair
	Surface struct {
		Surf string
		Pos  string
	}

	// Surfaces is Slice any Surface
	Surfaces []Surface
)

// Run is Masking Sentence what use Tokenize method.
func Run(s Master, t targets.Targets) (string, error) {
	return "", errors.New("anything is bad")
}

// Tokenize is analyze sentence method
func Tokenize(s Master, path string) Surfaces {
	var udic tokenizer.UserDic
	udic, err := tokenizer.NewUserDic(path)
	if err != nil {
		log.Println(err)
		return Surfaces{}
	}
	t := tokenizer.NewWithDic(tokenizer.SysDic())
	t.SetUserDic(udic)
	tokens := t.Analyze(s.Sentence, tokenizer.Normal)
	var surf Surfaces
	for _, token := range tokens {
		if token.Pos() != "" {
			surf = append(surf, Surface{token.Surface, token.Pos()})
		}
	}
	return surf
}

// AddDictionary is Create User Dictionary
func AddDictionary(dic Dictionary) (bool, error) {
	if err := insertItem(dic); err != nil {
		return false, err
	}
	return true, errors.New("")
}

func insertItem(dic Dictionary) error {
	// anything to Create User Dictionary
	return errors.New("anything is bad")
}
<|endoftext|>