<commit_before>// Copyright 2015 Unknwon
//
// 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 models

import (
	"bytes"
	"errors"
	"fmt"
	"path"
	"strings"
	"time"

	"github.com/Unknwon/com"

	"github.com/Unknwon/gowalker/modules/base"
	"github.com/Unknwon/gowalker/modules/setting"
)

var (
	ErrEmptyPackagePath     = errors.New("Package import path is empty")
	ErrPackageNotFound      = errors.New("Package does not found")
	ErrPackageVersionTooOld = errors.New("Package version is too old")
)

// PkgInfo represents the package information.
type PkgInfo struct {
	ID         int64  `xorm:"pk autoincr"`
	Name       string `xorm:"-"`
	ImportPath string `xorm:"UNIQUE"`
	Etag       string

	ProjectPath string
	ViewDirPath string
	Synopsis    string

	IsCmd       bool
	IsCgo       bool
	IsGoRepo    bool
	IsGoSubrepo bool
	IsGaeRepo   bool

	PkgVer int

	Priority int `xorm:" NOT NULL"`
	Views    int64
	// Indicate how many JS should be downloaded(JsNum=total num - 1)
	JsNum int

	ImportNum int64
	ImportIDs string `xorm:"import_ids LONGTEXT"`
	// Import num usually is small so save it to reduce a database query.
	ImportPaths string `xorm:"LONGTEXT"`

	RefNum int64
	RefIDs string `xorm:"ref_ids LONGTEXT"`

	Subdirs string `xorm:"TEXT"`

	LastView int64 `xorm:"-"`
	Created  int64
}

func (p *PkgInfo) JSPath() string {
	return path.Join(setting.DocsJsPath, p.ImportPath) + ".js"
}

// CanRefresh returns true if package is available to refresh.
func (p *PkgInfo) CanRefresh() bool {
	return time.Now().UTC().Add(-1*setting.RefreshInterval).Unix() > p.Created
}

// GetRefs returns a list of packages that import this one.
func (p *PkgInfo) GetRefs() []*PkgInfo {
	pinfos := make([]*PkgInfo, 0, p.RefNum)
	refIDs := strings.Split(p.RefIDs, "|")
	for i := range refIDs {
		if len(refIDs[i]) == 0 {
			continue
		}

		id := com.StrTo(refIDs[i][1:]).MustInt64()
		if pinfo, _ := GetPkgInfoById(id); pinfo != nil {
			pinfo.Name = path.Base(pinfo.ImportPath)
			pinfos = append(pinfos, pinfo)
		}
	}
	return pinfos
}

// PACKAGE_VER is modified when previously stored packages are invalid.
const PACKAGE_VER = 1

// PkgRef represents temporary reference information of a package.
type PkgRef struct {
	ID         int64  `xorm:"pk autoincr"`
	ImportPath string `xorm:"UNIQUE"`
	RefNum     int64
	RefIDs     string `xorm:"ref_ids LONGTEXT"`
}

func updatePkgRef(pid int64, refPath string) error {
	if base.IsGoRepoPath(refPath) ||
		refPath == "C" ||
		refPath[1] == '.' ||
		!base.IsValidRemotePath(refPath) {
		return nil
	}

	ref := new(PkgRef)
	has, err := x.Where("import_path=?", refPath).Get(ref)
	if err != nil {
		return fmt.Errorf("get PkgRef: %v", err)
	}

	queryStr := "$" + com.ToStr(pid) + "|"
	if !has {
		if _, err = x.Insert(&PkgRef{
			ImportPath: refPath,
			RefNum:     1,
			RefIDs:     queryStr,
		}); err != nil {
			return fmt.Errorf("insert PkgRef: %v", err)
		}
		return nil
	}

	i := strings.Index(ref.RefIDs, queryStr)
	if i > -1 {
		return nil
	}

	ref.RefIDs += queryStr
	ref.RefNum++
	_, err = x.Id(ref.ID).AllCols().Update(ref)
	return err
}

// checkRefs checks if given packages are still referencing this one.
func checkRefs(pinfo *PkgInfo) {
	var buf bytes.Buffer
	pinfo.RefNum = 0
	refIDs := strings.Split(pinfo.RefIDs, "|")
	for i := range refIDs {
		if len(refIDs[i]) == 0 {
			continue
		}

		fmt.Println(com.StrTo(refIDs[i][1:]).MustInt64())
		pkg, _ := GetPkgInfoById(com.StrTo(refIDs[i][1:]).MustInt64())
		if pkg == nil {
			continue
		}

		if strings.Index(pkg.ImportIDs, "$"+com.ToStr(pinfo.ID)+"|") == -1 {
			continue
		}

		buf.WriteString("$")
		buf.WriteString(com.ToStr(pkg.ID))
		buf.WriteString("|")
		pinfo.RefNum++
	}
	pinfo.RefIDs = buf.String()
}

// updateRef updates or crates corresponding reference import information.
func updateRef(pid int64, refPath string) (int64, error) {
	pinfo, err := GetPkgInfo(refPath)
	if err != nil && pinfo == nil {
		if err == ErrPackageNotFound ||
			err == ErrPackageVersionTooOld {
			// Package hasn't existed yet, save to temporary place.
			return 0, updatePkgRef(pid, refPath)
		}
		return 0, fmt.Errorf("GetPkgInfo(%s): %v", refPath, err)
	}

	// Check if reference information has beed recorded.
	queryStr := "$" + com.ToStr(pid) + "|"
	i := strings.Index(pinfo.RefIDs, queryStr)
	if i > -1 {
		return pinfo.ID, nil
	}

	// Add new as needed.
	pinfo.RefIDs += queryStr
	pinfo.RefNum++
	_, err = x.Id(pinfo.ID).AllCols().Update(pinfo)
	return pinfo.ID, err
}

// SavePkgInfo saves package information.
func SavePkgInfo(pinfo *PkgInfo, updateRefs bool) (err error) {
	pinfo.PkgVer = PACKAGE_VER

	switch {
	case pinfo.IsGaeRepo:
		pinfo.Priority = 70
	case pinfo.IsGoSubrepo:
		pinfo.Priority = 80
	case pinfo.IsGoRepo:
		pinfo.Priority = 99
	}

	// When package is not created, there is no ID so check will certainly fail.
	var ignoreCheckRefs bool

	// Create or update package info itself.
	// Note(Unknwon): do this because we need ID field later.
	if pinfo.ID == 0 {
		ignoreCheckRefs = true
		pinfo.Views = 1

		// First time created, check PkgRef.
		ref := new(PkgRef)
		has, err := x.Where("import_path=?", pinfo.ImportPath).Get(ref)
		if err != nil {
			return fmt.Errorf("get PkgRef: %v", err)
		} else if has {
			pinfo.RefNum = ref.RefNum
			pinfo.RefIDs = ref.RefIDs
			if _, err = x.Id(ref.ID).Delete(ref); err != nil {
				return fmt.Errorf("delete PkgRef: %v", err)
			}
		}

		_, err = x.Insert(pinfo)
	} else {
		_, err = x.Id(pinfo.ID).AllCols().Update(pinfo)
	}
	if err != nil {
		return fmt.Errorf("update package info: %v", err)
	}

	// Update package import references.
	// Note(Unknwon): I just don't see the value of who imports STD
	//	when you don't even import and uses what objects.
	if updateRefs && !pinfo.IsGoRepo {
		var buf bytes.Buffer
		paths := strings.Split(pinfo.ImportPaths, "|")
		for i := range paths {
			if base.IsGoRepoPath(paths[i]) {
				continue
			}

			refID, err := updateRef(pinfo.ID, paths[i])
			if err != nil {
				return fmt.Errorf("updateRef: %v", err)
			} else if refID == 0 {
				continue
			}
			buf.WriteString("$")
			buf.WriteString(com.ToStr(refID))
			buf.WriteString("|")
		}
		pinfo.ImportIDs = buf.String()

		if !ignoreCheckRefs {
			// Check packages who import this is still importing.
			checkRefs(pinfo)
		}
		_, err = x.Id(pinfo.ID).AllCols().Update(pinfo)
		return err
	}
	return nil
}

// GetPkgInfo returns package information by given import path.
func GetPkgInfo(importPath string) (*PkgInfo, error) {
	if len(importPath) == 0 {
		return nil, ErrEmptyPackagePath
	}

	pinfo := new(PkgInfo)
	has, err := x.Where("import_path=?", importPath).Get(pinfo)
	if err != nil {
		return nil, err
	} else if !has {
		return nil, ErrPackageNotFound
	} else if pinfo.PkgVer < PACKAGE_VER {
		pinfo.Etag = ""
		return pinfo, ErrPackageVersionTooOld
	}

	if !com.IsFile(pinfo.JSPath()) {
		pinfo.Etag = ""
		return pinfo, ErrPackageVersionTooOld
	}

	return pinfo, nil
}

// GetSubPkgs returns sub-projects by given sub-directories.
func GetSubPkgs(importPath string, dirs []string) []*PkgInfo {
	pinfos := make([]*PkgInfo, 0, len(dirs))
	for _, dir := range dirs {
		if len(dir) == 0 {
			continue
		}

		fullPath := importPath + "/" + dir
		if pinfo, err := GetPkgInfo(fullPath); err == nil {
			pinfo.Name = dir
			pinfos = append(pinfos, pinfo)
		} else {
			pinfos = append(pinfos, &PkgInfo{
				Name:       dir,
				ImportPath: fullPath,
			})
		}
	}
	return pinfos
}

// GetPkgInfosByPaths returns a list of packages by given import paths.
func GetPkgInfosByPaths(paths []string) []*PkgInfo {
	pinfos := make([]*PkgInfo, 0, len(paths))
	for _, p := range paths {
		if len(p) == 0 {
			continue
		}

		if pinfo, err := GetPkgInfo(p); err == nil {
			pinfo.Name = path.Base(p)
			pinfos = append(pinfos, pinfo)
		} else {
			pinfos = append(pinfos, &PkgInfo{
				Name:       path.Base(p),
				ImportPath: p,
			})
		}
	}
	return pinfos
}

// GetPkgInfoById returns package information by given ID.
func GetPkgInfoById(id int64) (*PkgInfo, error) {
	pinfo := new(PkgInfo)
	has, err := x.Id(id).Get(pinfo)
	if err != nil {
		return nil, err
	} else if !has {
		return nil, ErrPackageNotFound
	} else if pinfo.PkgVer < PACKAGE_VER {
		return pinfo, ErrPackageVersionTooOld
	}

	if !com.IsFile(pinfo.JSPath()) {
		return pinfo, ErrPackageVersionTooOld
	}

	return pinfo, nil
}

// SearchPkgInfo searches package information by given keyword.
func SearchPkgInfo(limit int, keyword string) ([]*PkgInfo, error) {
	if len(keyword) == 0 {
		return nil, nil
	}
	pkgs := make([]*PkgInfo, 0, limit)
	return pkgs, x.Limit(limit).Desc("priority").Desc("views").Where("import_path like ?", "%"+keyword+"%").Find(&pkgs)
}
<commit_msg>fix #65<commit_after>// Copyright 2015 Unknwon
//
// 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 models

import (
	"bytes"
	"errors"
	"fmt"
	"path"
	"strings"
	"time"

	"github.com/Unknwon/com"

	"github.com/Unknwon/gowalker/modules/base"
	"github.com/Unknwon/gowalker/modules/setting"
)

var (
	ErrEmptyPackagePath     = errors.New("Package import path is empty")
	ErrPackageNotFound      = errors.New("Package does not found")
	ErrPackageVersionTooOld = errors.New("Package version is too old")
)

// PkgInfo represents the package information.
type PkgInfo struct {
	ID         int64  `xorm:"pk autoincr"`
	Name       string `xorm:"-"`
	ImportPath string `xorm:"UNIQUE"`
	Etag       string

	ProjectPath string
	ViewDirPath string
	Synopsis    string

	IsCmd       bool
	IsCgo       bool
	IsGoRepo    bool
	IsGoSubrepo bool
	IsGaeRepo   bool

	PkgVer int

	Priority int `xorm:" NOT NULL"`
	Views    int64
	// Indicate how many JS should be downloaded(JsNum=total num - 1)
	JsNum int

	ImportNum int64
	ImportIDs string `xorm:"import_ids LONGTEXT"`
	// Import num usually is small so save it to reduce a database query.
	ImportPaths string `xorm:"LONGTEXT"`

	RefNum int64
	RefIDs string `xorm:"ref_ids LONGTEXT"`

	Subdirs string `xorm:"TEXT"`

	LastView int64 `xorm:"-"`
	Created  int64
}

func (p *PkgInfo) JSPath() string {
	return path.Join(setting.DocsJsPath, p.ImportPath) + ".js"
}

// CanRefresh returns true if package is available to refresh.
func (p *PkgInfo) CanRefresh() bool {
	return time.Now().UTC().Add(-1*setting.RefreshInterval).Unix() > p.Created
}

// GetRefs returns a list of packages that import this one.
func (p *PkgInfo) GetRefs() []*PkgInfo {
	pinfos := make([]*PkgInfo, 0, p.RefNum)
	refIDs := strings.Split(p.RefIDs, "|")
	for i := range refIDs {
		if len(refIDs[i]) == 0 {
			continue
		}

		id := com.StrTo(refIDs[i][1:]).MustInt64()
		if pinfo, _ := GetPkgInfoById(id); pinfo != nil {
			pinfo.Name = path.Base(pinfo.ImportPath)
			pinfos = append(pinfos, pinfo)
		}
	}
	return pinfos
}

// PACKAGE_VER is modified when previously stored packages are invalid.
const PACKAGE_VER = 1

// PkgRef represents temporary reference information of a package.
type PkgRef struct {
	ID         int64  `xorm:"pk autoincr"`
	ImportPath string `xorm:"UNIQUE"`
	RefNum     int64
	RefIDs     string `xorm:"ref_ids LONGTEXT"`
}

func updatePkgRef(pid int64, refPath string) error {
	if base.IsGoRepoPath(refPath) ||
		refPath == "C" ||
		refPath[1] == '.' ||
		!base.IsValidRemotePath(refPath) {
		return nil
	}

	ref := new(PkgRef)
	has, err := x.Where("import_path=?", refPath).Get(ref)
	if err != nil {
		return fmt.Errorf("get PkgRef: %v", err)
	}

	queryStr := "$" + com.ToStr(pid) + "|"
	if !has {
		if _, err = x.Insert(&PkgRef{
			ImportPath: refPath,
			RefNum:     1,
			RefIDs:     queryStr,
		}); err != nil {
			return fmt.Errorf("insert PkgRef: %v", err)
		}
		return nil
	}

	i := strings.Index(ref.RefIDs, queryStr)
	if i > -1 {
		return nil
	}

	ref.RefIDs += queryStr
	ref.RefNum++
	_, err = x.Id(ref.ID).AllCols().Update(ref)
	return err
}

// checkRefs checks if given packages are still referencing this one.
func checkRefs(pinfo *PkgInfo) {
	var buf bytes.Buffer
	pinfo.RefNum = 0
	refIDs := strings.Split(pinfo.RefIDs, "|")
	for i := range refIDs {
		if len(refIDs[i]) == 0 {
			continue
		}

		fmt.Println(com.StrTo(refIDs[i][1:]).MustInt64())
		pkg, _ := GetPkgInfoById(com.StrTo(refIDs[i][1:]).MustInt64())
		if pkg == nil {
			continue
		}

		if strings.Index(pkg.ImportIDs, "$"+com.ToStr(pinfo.ID)+"|") == -1 {
			continue
		}

		buf.WriteString("$")
		buf.WriteString(com.ToStr(pkg.ID))
		buf.WriteString("|")
		pinfo.RefNum++
	}
	pinfo.RefIDs = buf.String()
}

// updateRef updates or crates corresponding reference import information.
func updateRef(pid int64, refPath string) (int64, error) {
	pinfo, err := GetPkgInfo(refPath)
	if err != nil && pinfo == nil {
		if err == ErrPackageNotFound ||
			err == ErrPackageVersionTooOld {
			// Package hasn't existed yet, save to temporary place.
			return 0, updatePkgRef(pid, refPath)
		}
		return 0, fmt.Errorf("GetPkgInfo(%s): %v", refPath, err)
	}

	// Check if reference information has beed recorded.
	queryStr := "$" + com.ToStr(pid) + "|"
	i := strings.Index(pinfo.RefIDs, queryStr)
	if i > -1 {
		return pinfo.ID, nil
	}

	// Add new as needed.
	pinfo.RefIDs += queryStr
	pinfo.RefNum++
	_, err = x.Id(pinfo.ID).AllCols().Update(pinfo)
	return pinfo.ID, err
}

// SavePkgInfo saves package information.
func SavePkgInfo(pinfo *PkgInfo, updateRefs bool) (err error) {
	if len(pinfo.Synopsis) > 255 {
		pinfo.Synopsis = pinfo.Synopsis[:255]
	}

	pinfo.PkgVer = PACKAGE_VER

	switch {
	case pinfo.IsGaeRepo:
		pinfo.Priority = 70
	case pinfo.IsGoSubrepo:
		pinfo.Priority = 80
	case pinfo.IsGoRepo:
		pinfo.Priority = 99
	}

	// When package is not created, there is no ID so check will certainly fail.
	var ignoreCheckRefs bool

	// Create or update package info itself.
	// Note(Unknwon): do this because we need ID field later.
	if pinfo.ID == 0 {
		ignoreCheckRefs = true
		pinfo.Views = 1

		// First time created, check PkgRef.
		ref := new(PkgRef)
		has, err := x.Where("import_path=?", pinfo.ImportPath).Get(ref)
		if err != nil {
			return fmt.Errorf("get PkgRef: %v", err)
		} else if has {
			pinfo.RefNum = ref.RefNum
			pinfo.RefIDs = ref.RefIDs
			if _, err = x.Id(ref.ID).Delete(ref); err != nil {
				return fmt.Errorf("delete PkgRef: %v", err)
			}
		}

		_, err = x.Insert(pinfo)
	} else {
		_, err = x.Id(pinfo.ID).AllCols().Update(pinfo)
	}
	if err != nil {
		return fmt.Errorf("update package info: %v", err)
	}

	// Update package import references.
	// Note(Unknwon): I just don't see the value of who imports STD
	//	when you don't even import and uses what objects.
	if updateRefs && !pinfo.IsGoRepo {
		var buf bytes.Buffer
		paths := strings.Split(pinfo.ImportPaths, "|")
		for i := range paths {
			if base.IsGoRepoPath(paths[i]) {
				continue
			}

			refID, err := updateRef(pinfo.ID, paths[i])
			if err != nil {
				return fmt.Errorf("updateRef: %v", err)
			} else if refID == 0 {
				continue
			}
			buf.WriteString("$")
			buf.WriteString(com.ToStr(refID))
			buf.WriteString("|")
		}
		pinfo.ImportIDs = buf.String()

		if !ignoreCheckRefs {
			// Check packages who import this is still importing.
			checkRefs(pinfo)
		}
		_, err = x.Id(pinfo.ID).AllCols().Update(pinfo)
		return err
	}
	return nil
}

// GetPkgInfo returns package information by given import path.
func GetPkgInfo(importPath string) (*PkgInfo, error) {
	if len(importPath) == 0 {
		return nil, ErrEmptyPackagePath
	}

	pinfo := new(PkgInfo)
	has, err := x.Where("import_path=?", importPath).Get(pinfo)
	if err != nil {
		return nil, err
	} else if !has {
		return nil, ErrPackageNotFound
	} else if pinfo.PkgVer < PACKAGE_VER {
		pinfo.Etag = ""
		return pinfo, ErrPackageVersionTooOld
	}

	if !com.IsFile(pinfo.JSPath()) {
		pinfo.Etag = ""
		return pinfo, ErrPackageVersionTooOld
	}

	return pinfo, nil
}

// GetSubPkgs returns sub-projects by given sub-directories.
func GetSubPkgs(importPath string, dirs []string) []*PkgInfo {
	pinfos := make([]*PkgInfo, 0, len(dirs))
	for _, dir := range dirs {
		if len(dir) == 0 {
			continue
		}

		fullPath := importPath + "/" + dir
		if pinfo, err := GetPkgInfo(fullPath); err == nil {
			pinfo.Name = dir
			pinfos = append(pinfos, pinfo)
		} else {
			pinfos = append(pinfos, &PkgInfo{
				Name:       dir,
				ImportPath: fullPath,
			})
		}
	}
	return pinfos
}

// GetPkgInfosByPaths returns a list of packages by given import paths.
func GetPkgInfosByPaths(paths []string) []*PkgInfo {
	pinfos := make([]*PkgInfo, 0, len(paths))
	for _, p := range paths {
		if len(p) == 0 {
			continue
		}

		if pinfo, err := GetPkgInfo(p); err == nil {
			pinfo.Name = path.Base(p)
			pinfos = append(pinfos, pinfo)
		} else {
			pinfos = append(pinfos, &PkgInfo{
				Name:       path.Base(p),
				ImportPath: p,
			})
		}
	}
	return pinfos
}

// GetPkgInfoById returns package information by given ID.
func GetPkgInfoById(id int64) (*PkgInfo, error) {
	pinfo := new(PkgInfo)
	has, err := x.Id(id).Get(pinfo)
	if err != nil {
		return nil, err
	} else if !has {
		return nil, ErrPackageNotFound
	} else if pinfo.PkgVer < PACKAGE_VER {
		return pinfo, ErrPackageVersionTooOld
	}

	if !com.IsFile(pinfo.JSPath()) {
		return pinfo, ErrPackageVersionTooOld
	}

	return pinfo, nil
}

// SearchPkgInfo searches package information by given keyword.
func SearchPkgInfo(limit int, keyword string) ([]*PkgInfo, error) {
	if len(keyword) == 0 {
		return nil, nil
	}
	pkgs := make([]*PkgInfo, 0, limit)
	return pkgs, x.Limit(limit).Desc("priority").Desc("views").Where("import_path like ?", "%"+keyword+"%").Find(&pkgs)
}
<|endoftext|>


<commit_before>package sacloud

// SSHKey 公開鍵
type SSHKey struct {
	*Resource       // ID
	propName        // 名称
	propDescription // 説明
	propCreatedAt   // 作成日時

	PublicKey   string `json:",omitempty"` // 公開鍵
	Fingerprint string `json:",omitempty"` // フィンガープリント
}

// SSHKeyGenerated 公開鍵生成戻り値(秘密鍵のダウンロード用)
type SSHKeyGenerated struct {
	SSHKey
	PrivateKey string `json:",omitempty"` // 秘密鍵
}

// GetPublicKey 公開鍵取得
func (k *SSHKey) GetPublicKey() string {
	return k.PublicKey
}

// SetPublicKey 公開鍵設定
func (k *SSHKey) SetPublicKey(pKey string) {
	k.PublicKey = pKey
}

// GetFingerprint フィンガープリント取得
func (k *SSHKey) GetFingerpinrt() string {
	return k.Fingerprint
}

// GetPrivateKey 秘密鍵取得
func (k *SSHKeyGenerated) GetPrivateKey() string {
	return k.PrivateKey
}
<commit_msg>Fix typo<commit_after>package sacloud

// SSHKey 公開鍵
type SSHKey struct {
	*Resource       // ID
	propName        // 名称
	propDescription // 説明
	propCreatedAt   // 作成日時

	PublicKey   string `json:",omitempty"` // 公開鍵
	Fingerprint string `json:",omitempty"` // フィンガープリント
}

// SSHKeyGenerated 公開鍵生成戻り値(秘密鍵のダウンロード用)
type SSHKeyGenerated struct {
	SSHKey
	PrivateKey string `json:",omitempty"` // 秘密鍵
}

// GetPublicKey 公開鍵取得
func (k *SSHKey) GetPublicKey() string {
	return k.PublicKey
}

// SetPublicKey 公開鍵設定
func (k *SSHKey) SetPublicKey(pKey string) {
	k.PublicKey = pKey
}

// GetFingerprint フィンガープリント取得
func (k *SSHKey) GetFingerprint() string {
	return k.Fingerprint
}

// GetPrivateKey 秘密鍵取得
func (k *SSHKeyGenerated) GetPrivateKey() string {
	return k.PrivateKey
}
<|endoftext|>


<commit_before>package models

import (
	"time"
	"fmt"
	"strings"
)

// Sensor has common fields for any sensors
type Sensor struct {
	Name    string    `json:"name"`
	Type    string    `json:"type"`
	GenTime time.Time `json:"gen_time"`
}

// GyroSensor produces x-y-z axes angle velocity values
type GyroSensor struct {
	Sensor
	AngleVelocityX float32 `json:"x_axis_angle_velocity"`
	AngleVelocityY float32 `json:"y_axis_angle_velocity"`
	AngleVelocityZ float32 `json:"z_axis_angle_velocity"`
}

func (s GyroSensor) String() string {
	var result []string

	st := fmt.Sprintf("Measured on %s", s.GenTime)
	result = append(result, st)

	st = fmt.Sprintf("Angle Velocity of X-axis : %f", s.AngleVelocityX)
	result = append(result, st)

	st = fmt.Sprintf("Angle Velocity of Y-axis : %f", s.AngleVelocityY)
	result = append(result, st)

	st = fmt.Sprintf("Anglue Velocity of Z-axis : %f\n", s.AngleVelocityZ)
	result = append(result, st)

	return strings.Join(result, "\n")
}

// AccelSensor produces x-y-z axes gravity acceleration values
type AccelSensor struct {
	Sensor
	GravityAccX float32 `json:"x_axis_gravity_acceleration"`
	GravityAccY float32 `json:"y_axis_gravity_acceleration"`
	GravityAccZ float32 `json:"z_axis_grativy_acceleration"`
}

func (s AccelSensor) String() string {
	var result []string

	st := fmt.Sprintf("Measured on %s", s.GenTime)
	result = append(result, st)

	st = fmt.Sprintf("Gravitational Velocity of X-axis : %f", s.GravityAccX)
	result = append(result, st)

	st = fmt.Sprintf("Gravitational Velocity of Y-axis : %f", s.GravityAccY)
	result = append(result, st)

	st = fmt.Sprintf("Gravitational Velocity of Z-axis : %f\n", s.GravityAccZ)
	result = append(result, st)

	return strings.Join(result, "\n")
}

// TempSensor produces temperature and humidity values
type TempSensor struct {
	Sensor
	Temperature float32 `json:"temperature"`
	Humidity    float32 `json:"humidity"`
}

func (s TempSensor) String() string {
	var result []string

	st := fmt.Sprintf("Measured on %s", s.GenTime)
	result = append(result, st)

	st = fmt.Sprintf("Temperature : %f", s.Temperature)
	result = append(result, st)

	st = fmt.Sprintf("Humidity : %f\n", s.Humidity)
	result = append(result, st)

	return strings.Join(result, "\n")
}

<commit_msg>Fix typo error in String method of GyroSensor model<commit_after>package models

import (
	"fmt"
	"strings"
	"time"
)

// Sensor has common fields for any sensors
type Sensor struct {
	Name    string    `json:"name"`
	Type    string    `json:"type"`
	GenTime time.Time `json:"gen_time"`
}

// GyroSensor produces x-y-z axes angle velocity values
type GyroSensor struct {
	Sensor
	AngleVelocityX float32 `json:"x_axis_angle_velocity"`
	AngleVelocityY float32 `json:"y_axis_angle_velocity"`
	AngleVelocityZ float32 `json:"z_axis_angle_velocity"`
}

func (s GyroSensor) String() string {
	var result []string

	st := fmt.Sprintf("Measured on %s", s.GenTime)
	result = append(result, st)

	st = fmt.Sprintf("Angle Velocity of X-axis : %f", s.AngleVelocityX)
	result = append(result, st)

	st = fmt.Sprintf("Angle Velocity of Y-axis : %f", s.AngleVelocityY)
	result = append(result, st)

	st = fmt.Sprintf("Angle Velocity of Z-axis : %f\n", s.AngleVelocityZ)
	result = append(result, st)

	return strings.Join(result, "\n")
}

// AccelSensor produces x-y-z axes gravity acceleration values
type AccelSensor struct {
	Sensor
	GravityAccX float32 `json:"x_axis_gravity_acceleration"`
	GravityAccY float32 `json:"y_axis_gravity_acceleration"`
	GravityAccZ float32 `json:"z_axis_grativy_acceleration"`
}

func (s AccelSensor) String() string {
	var result []string

	st := fmt.Sprintf("Measured on %s", s.GenTime)
	result = append(result, st)

	st = fmt.Sprintf("Gravitational Velocity of X-axis : %f", s.GravityAccX)
	result = append(result, st)

	st = fmt.Sprintf("Gravitational Velocity of Y-axis : %f", s.GravityAccY)
	result = append(result, st)

	st = fmt.Sprintf("Gravitational Velocity of Z-axis : %f\n", s.GravityAccZ)
	result = append(result, st)

	return strings.Join(result, "\n")
}

// TempSensor produces temperature and humidity values
type TempSensor struct {
	Sensor
	Temperature float32 `json:"temperature"`
	Humidity    float32 `json:"humidity"`
}

func (s TempSensor) String() string {
	var result []string

	st := fmt.Sprintf("Measured on %s", s.GenTime)
	result = append(result, st)

	st = fmt.Sprintf("Temperature : %f", s.Temperature)
	result = append(result, st)

	st = fmt.Sprintf("Humidity : %f\n", s.Humidity)
	result = append(result, st)

	return strings.Join(result, "\n")
}
<|endoftext|>


<commit_before>/*
Copyright 2016 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 instrumentation

import (
	"context"
	"encoding/json"
	"time"

	v1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/kubernetes/test/e2e/framework"
	"k8s.io/kubernetes/test/e2e/instrumentation/common"
	admissionapi "k8s.io/pod-security-admission/api"

	"github.com/onsi/ginkgo"
	"k8s.io/apimachinery/pkg/types"
)

const (
	eventRetryPeriod  = 1 * time.Second
	eventRetryTimeout = 1 * time.Minute
)

var _ = common.SIGDescribe("Events", func() {
	f := framework.NewDefaultFramework("events")
	f.NamespacePodSecurityEnforceLevel = admissionapi.LevelPrivileged

	/*
			   Release: v1.20
			   Testname: Event resource lifecycle
			   Description: Create an event, the event MUST exist.
		           The event is patched with a new message, the check MUST have the update message.
		           The event is deleted and MUST NOT show up when listing all events.
	*/
	framework.ConformanceIt("should ensure that an event can be fetched, patched, deleted, and listed", func() {
		eventTestName := "event-test"

		ginkgo.By("creating a test event")
		// create a test event in test namespace
		_, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).Create(context.TODO(), &v1.Event{
			ObjectMeta: metav1.ObjectMeta{
				Name: eventTestName,
				Labels: map[string]string{
					"testevent-constant": "true",
				},
			},
			Message: "This is a test event",
			Reason:  "Test",
			Type:    "Normal",
			Count:   1,
			InvolvedObject: v1.ObjectReference{
				Namespace: f.Namespace.Name,
			},
		}, metav1.CreateOptions{})
		framework.ExpectNoError(err, "failed to create test event")

		ginkgo.By("listing all events in all namespaces")
		// get a list of Events in all namespaces to ensure endpoint coverage
		eventsList, err := f.ClientSet.CoreV1().Events("").List(context.TODO(), metav1.ListOptions{
			LabelSelector: "testevent-constant=true",
		})
		framework.ExpectNoError(err, "failed list all events")

		foundCreatedEvent := false
		var eventCreatedName string
		for _, val := range eventsList.Items {
			if val.ObjectMeta.Name == eventTestName && val.ObjectMeta.Namespace == f.Namespace.Name {
				foundCreatedEvent = true
				eventCreatedName = val.ObjectMeta.Name
				break
			}
		}
		if !foundCreatedEvent {
			framework.Failf("unable to find test event %s in namespace %s, full list of events is %+v", eventTestName, f.Namespace.Name, eventsList.Items)
		}

		ginkgo.By("patching the test event")
		// patch the event's message
		eventPatchMessage := "This is a test event - patched"
		eventPatch, err := json.Marshal(map[string]interface{}{
			"message": eventPatchMessage,
		})
		framework.ExpectNoError(err, "failed to marshal the patch JSON payload")

		_, err = f.ClientSet.CoreV1().Events(f.Namespace.Name).Patch(context.TODO(), eventTestName, types.StrategicMergePatchType, []byte(eventPatch), metav1.PatchOptions{})
		framework.ExpectNoError(err, "failed to patch the test event")

		ginkgo.By("fetching the test event")
		// get event by name
		event, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).Get(context.TODO(), eventCreatedName, metav1.GetOptions{})
		framework.ExpectNoError(err, "failed to fetch the test event")
		framework.ExpectEqual(event.Message, eventPatchMessage, "test event message does not match patch message")

		ginkgo.By("deleting the test event")
		// delete original event
		err = f.ClientSet.CoreV1().Events(f.Namespace.Name).Delete(context.TODO(), eventCreatedName, metav1.DeleteOptions{})
		framework.ExpectNoError(err, "failed to delete the test event")

		ginkgo.By("listing all events in all namespaces")
		// get a list of Events list namespace
		eventsList, err = f.ClientSet.CoreV1().Events("").List(context.TODO(), metav1.ListOptions{
			LabelSelector: "testevent-constant=true",
		})
		framework.ExpectNoError(err, "fail to list all events")
		foundCreatedEvent = false
		for _, val := range eventsList.Items {
			if val.ObjectMeta.Name == eventTestName && val.ObjectMeta.Namespace == f.Namespace.Name {
				foundCreatedEvent = true
				break
			}
		}
		if foundCreatedEvent {
			framework.Failf("Should not have found test event %s in namespace %s, full list of events %+v", eventTestName, f.Namespace.Name, eventsList.Items)
		}
	})

	/*
	   Release: v1.20
	   Testname: Event, delete a collection
	   Description: A set of events is created with a label selector which MUST be found when listed.
	   The set of events is deleted and MUST NOT show up when listed by its label selector.
	*/
	framework.ConformanceIt("should delete a collection of events", func() {
		eventTestNames := []string{"test-event-1", "test-event-2", "test-event-3"}

		ginkgo.By("Create set of events")
		// create a test event in test namespace
		for _, eventTestName := range eventTestNames {
			eventMessage := "This is " + eventTestName
			_, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).Create(context.TODO(), &v1.Event{

				ObjectMeta: metav1.ObjectMeta{
					Name:   eventTestName,
					Labels: map[string]string{"testevent-set": "true"},
				},
				Message: eventMessage,
				Reason:  "Test",
				Type:    "Normal",
				Count:   1,
				InvolvedObject: v1.ObjectReference{
					Namespace: f.Namespace.Name,
				},
			}, metav1.CreateOptions{})
			framework.ExpectNoError(err, "failed to create event")
			framework.Logf("created %v", eventTestName)
		}

		ginkgo.By("get a list of Events with a label in the current namespace")
		// get a list of events
		eventList, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).List(context.TODO(), metav1.ListOptions{
			LabelSelector: "testevent-set=true",
		})
		framework.ExpectNoError(err, "failed to get a list of events")

		framework.ExpectEqual(len(eventList.Items), len(eventTestNames), "looking for expected number of pod templates events")

		ginkgo.By("delete collection of events")
		// delete collection

		framework.Logf("requesting DeleteCollection of events")
		err = f.ClientSet.CoreV1().Events(f.Namespace.Name).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{
			LabelSelector: "testevent-set=true"})
		framework.ExpectNoError(err, "failed to delete the test event")

		ginkgo.By("check that the list of events matches the requested quantity")

		err = wait.PollImmediate(eventRetryPeriod, eventRetryTimeout, checkEventListQuantity(f, "testevent-set=true", 0))
		framework.ExpectNoError(err, "failed to count required events")
	})

})

func checkEventListQuantity(f *framework.Framework, label string, quantity int) func() (bool, error) {
	return func() (bool, error) {
		var err error

		framework.Logf("requesting list of events to confirm quantity")

		eventList, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).List(context.TODO(), metav1.ListOptions{
			LabelSelector: label})

		if err != nil {
			return false, err
		}

		if len(eventList.Items) != quantity {
			return false, err
		}
		return true, nil
	}
}
<commit_msg>Migrate and update current e2e event test<commit_after>/*
Copyright 2016 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 instrumentation

import (
	"context"
	"encoding/json"
	"time"

	v1 "k8s.io/api/core/v1"
	apiequality "k8s.io/apimachinery/pkg/api/equality"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/diff"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/kubernetes/test/e2e/framework"
	"k8s.io/kubernetes/test/e2e/instrumentation/common"
	admissionapi "k8s.io/pod-security-admission/api"

	"github.com/onsi/ginkgo"
	"k8s.io/apimachinery/pkg/types"
)

const (
	eventRetryPeriod  = 1 * time.Second
	eventRetryTimeout = 1 * time.Minute
)

var _ = common.SIGDescribe("Events", func() {
	f := framework.NewDefaultFramework("events")
	f.NamespacePodSecurityEnforceLevel = admissionapi.LevelPrivileged

	/*
			   Release: v1.20
			   Testname: Event resource lifecycle
			   Description: Create an event, the event MUST exist.
		           The event is patched with a new message, the check MUST have the update message.
		           The event is deleted and MUST NOT show up when listing all events.
	*/
	framework.ConformanceIt("should ensure that an event can be fetched, patched, deleted, and listed", func() {
		eventTestName := "event-test"

		ginkgo.By("creating a test event")
		// create a test event in test namespace
		_, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).Create(context.TODO(), &v1.Event{
			ObjectMeta: metav1.ObjectMeta{
				Name: eventTestName,
				Labels: map[string]string{
					"testevent-constant": "true",
				},
			},
			Message: "This is a test event",
			Reason:  "Test",
			Type:    "Normal",
			Count:   1,
			InvolvedObject: v1.ObjectReference{
				Namespace: f.Namespace.Name,
			},
		}, metav1.CreateOptions{})
		framework.ExpectNoError(err, "failed to create test event")

		ginkgo.By("listing all events in all namespaces")
		// get a list of Events in all namespaces to ensure endpoint coverage
		eventsList, err := f.ClientSet.CoreV1().Events("").List(context.TODO(), metav1.ListOptions{
			LabelSelector: "testevent-constant=true",
		})
		framework.ExpectNoError(err, "failed list all events")

		foundCreatedEvent := false
		var eventCreatedName string
		for _, val := range eventsList.Items {
			if val.ObjectMeta.Name == eventTestName && val.ObjectMeta.Namespace == f.Namespace.Name {
				foundCreatedEvent = true
				eventCreatedName = val.ObjectMeta.Name
				break
			}
		}
		if !foundCreatedEvent {
			framework.Failf("unable to find test event %s in namespace %s, full list of events is %+v", eventTestName, f.Namespace.Name, eventsList.Items)
		}

		ginkgo.By("patching the test event")
		// patch the event's message
		eventPatchMessage := "This is a test event - patched"
		eventPatch, err := json.Marshal(map[string]interface{}{
			"message": eventPatchMessage,
		})
		framework.ExpectNoError(err, "failed to marshal the patch JSON payload")

		_, err = f.ClientSet.CoreV1().Events(f.Namespace.Name).Patch(context.TODO(), eventTestName, types.StrategicMergePatchType, []byte(eventPatch), metav1.PatchOptions{})
		framework.ExpectNoError(err, "failed to patch the test event")

		ginkgo.By("fetching the test event")
		// get event by name
		event, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).Get(context.TODO(), eventCreatedName, metav1.GetOptions{})
		framework.ExpectNoError(err, "failed to fetch the test event")
		framework.ExpectEqual(event.Message, eventPatchMessage, "test event message does not match patch message")

		ginkgo.By("deleting the test event")
		// delete original event
		err = f.ClientSet.CoreV1().Events(f.Namespace.Name).Delete(context.TODO(), eventCreatedName, metav1.DeleteOptions{})
		framework.ExpectNoError(err, "failed to delete the test event")

		ginkgo.By("listing all events in all namespaces")
		// get a list of Events list namespace
		eventsList, err = f.ClientSet.CoreV1().Events("").List(context.TODO(), metav1.ListOptions{
			LabelSelector: "testevent-constant=true",
		})
		framework.ExpectNoError(err, "fail to list all events")
		foundCreatedEvent = false
		for _, val := range eventsList.Items {
			if val.ObjectMeta.Name == eventTestName && val.ObjectMeta.Namespace == f.Namespace.Name {
				foundCreatedEvent = true
				break
			}
		}
		if foundCreatedEvent {
			framework.Failf("Should not have found test event %s in namespace %s, full list of events %+v", eventTestName, f.Namespace.Name, eventsList.Items)
		}
	})

	ginkgo.It("should manage the lifecycle of an event", func() {
		eventTestName := "event-test"

		ginkgo.By("creating a test event")
		// create a test event in test namespace
		_, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).Create(context.TODO(), &v1.Event{
			ObjectMeta: metav1.ObjectMeta{
				Name: eventTestName,
				Labels: map[string]string{
					"testevent-constant": "true",
				},
			},
			Message: "This is a test event",
			Reason:  "Test",
			Type:    "Normal",
			Count:   1,
			InvolvedObject: v1.ObjectReference{
				Namespace: f.Namespace.Name,
			},
		}, metav1.CreateOptions{})
		framework.ExpectNoError(err, "failed to create test event")

		ginkgo.By("listing all events in all namespaces")
		// get a list of Events in all namespaces to ensure endpoint coverage
		eventsList, err := f.ClientSet.CoreV1().Events("").List(context.TODO(), metav1.ListOptions{
			LabelSelector: "testevent-constant=true",
		})
		framework.ExpectNoError(err, "failed list all events")

		foundCreatedEvent := false
		var eventCreatedName string
		for _, val := range eventsList.Items {
			if val.ObjectMeta.Name == eventTestName && val.ObjectMeta.Namespace == f.Namespace.Name {
				foundCreatedEvent = true
				eventCreatedName = val.ObjectMeta.Name
				break
			}
		}
		if !foundCreatedEvent {
			framework.Failf("unable to find test event %s in namespace %s, full list of events is %+v", eventTestName, f.Namespace.Name, eventsList.Items)
		}

		ginkgo.By("patching the test event")
		// patch the event's message
		eventPatchMessage := "This is a test event - patched"
		eventPatch, err := json.Marshal(map[string]interface{}{
			"message": eventPatchMessage,
		})
		framework.ExpectNoError(err, "failed to marshal the patch JSON payload")

		_, err = f.ClientSet.CoreV1().Events(f.Namespace.Name).Patch(context.TODO(), eventTestName, types.StrategicMergePatchType, []byte(eventPatch), metav1.PatchOptions{})
		framework.ExpectNoError(err, "failed to patch the test event")

		ginkgo.By("fetching the test event")
		// get event by name
		event, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).Get(context.TODO(), eventCreatedName, metav1.GetOptions{})
		framework.ExpectNoError(err, "failed to fetch the test event")
		framework.ExpectEqual(event.Message, eventPatchMessage, "test event message does not match patch message")

		ginkgo.By("updating the test event")

		testEvent, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).Get(context.TODO(), event.Name, metav1.GetOptions{})
		framework.ExpectNoError(err, "failed to get test event")

		testEvent.Series = &v1.EventSeries{
			Count:            100,
			LastObservedTime: metav1.MicroTime{Time: time.Unix(1505828956, 0)},
		}

		// clear ResourceVersion and ManagedFields which are set by control-plane
		testEvent.ObjectMeta.ResourceVersion = ""
		testEvent.ObjectMeta.ManagedFields = nil

		_, err = f.ClientSet.CoreV1().Events(f.Namespace.Name).Update(context.TODO(), testEvent, metav1.UpdateOptions{})
		framework.ExpectNoError(err, "failed to update the test event")

		ginkgo.By("getting the test event")
		event, err = f.ClientSet.CoreV1().Events(f.Namespace.Name).Get(context.TODO(), testEvent.Name, metav1.GetOptions{})
		framework.ExpectNoError(err, "failed to get test event")
		// clear ResourceVersion and ManagedFields which are set by control-plane
		event.ObjectMeta.ResourceVersion = ""
		event.ObjectMeta.ManagedFields = nil
		if !apiequality.Semantic.DeepEqual(testEvent, event) {
			framework.Failf("test event wasn't properly updated: %v", diff.ObjectReflectDiff(testEvent, event))
		}

		ginkgo.By("deleting the test event")
		// delete original event
		err = f.ClientSet.CoreV1().Events(f.Namespace.Name).Delete(context.TODO(), eventCreatedName, metav1.DeleteOptions{})
		framework.ExpectNoError(err, "failed to delete the test event")

		ginkgo.By("listing all events in all namespaces")
		// get a list of Events list namespace
		eventsList, err = f.ClientSet.CoreV1().Events("").List(context.TODO(), metav1.ListOptions{
			LabelSelector: "testevent-constant=true",
		})
		framework.ExpectNoError(err, "fail to list all events")
		foundCreatedEvent = false
		for _, val := range eventsList.Items {
			if val.ObjectMeta.Name == eventTestName && val.ObjectMeta.Namespace == f.Namespace.Name {
				foundCreatedEvent = true
				break
			}
		}
		if foundCreatedEvent {
			framework.Failf("Should not have found test event %s in namespace %s, full list of events %+v", eventTestName, f.Namespace.Name, eventsList.Items)
		}
	})

	/*
	   Release: v1.20
	   Testname: Event, delete a collection
	   Description: A set of events is created with a label selector which MUST be found when listed.
	   The set of events is deleted and MUST NOT show up when listed by its label selector.
	*/
	framework.ConformanceIt("should delete a collection of events", func() {
		eventTestNames := []string{"test-event-1", "test-event-2", "test-event-3"}

		ginkgo.By("Create set of events")
		// create a test event in test namespace
		for _, eventTestName := range eventTestNames {
			eventMessage := "This is " + eventTestName
			_, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).Create(context.TODO(), &v1.Event{

				ObjectMeta: metav1.ObjectMeta{
					Name:   eventTestName,
					Labels: map[string]string{"testevent-set": "true"},
				},
				Message: eventMessage,
				Reason:  "Test",
				Type:    "Normal",
				Count:   1,
				InvolvedObject: v1.ObjectReference{
					Namespace: f.Namespace.Name,
				},
			}, metav1.CreateOptions{})
			framework.ExpectNoError(err, "failed to create event")
			framework.Logf("created %v", eventTestName)
		}

		ginkgo.By("get a list of Events with a label in the current namespace")
		// get a list of events
		eventList, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).List(context.TODO(), metav1.ListOptions{
			LabelSelector: "testevent-set=true",
		})
		framework.ExpectNoError(err, "failed to get a list of events")

		framework.ExpectEqual(len(eventList.Items), len(eventTestNames), "looking for expected number of pod templates events")

		ginkgo.By("delete collection of events")
		// delete collection

		framework.Logf("requesting DeleteCollection of events")
		err = f.ClientSet.CoreV1().Events(f.Namespace.Name).DeleteCollection(context.TODO(), metav1.DeleteOptions{}, metav1.ListOptions{
			LabelSelector: "testevent-set=true"})
		framework.ExpectNoError(err, "failed to delete the test event")

		ginkgo.By("check that the list of events matches the requested quantity")

		err = wait.PollImmediate(eventRetryPeriod, eventRetryTimeout, checkEventListQuantity(f, "testevent-set=true", 0))
		framework.ExpectNoError(err, "failed to count required events")
	})

})

func checkEventListQuantity(f *framework.Framework, label string, quantity int) func() (bool, error) {
	return func() (bool, error) {
		var err error

		framework.Logf("requesting list of events to confirm quantity")

		eventList, err := f.ClientSet.CoreV1().Events(f.Namespace.Name).List(context.TODO(), metav1.ListOptions{
			LabelSelector: label})

		if err != nil {
			return false, err
		}

		if len(eventList.Items) != quantity {
			return false, err
		}
		return true, nil
	}
}
<|endoftext|>


<commit_before>// +build linux

/*
Copyright 2016 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 e2e_node

import (
	"fmt"
	"os/exec"
	"path"
	"strconv"
	"strings"
	"time"

	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/uuid"
	"k8s.io/kubernetes/pkg/api/v1"
	"k8s.io/kubernetes/test/e2e/framework"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

func getOOMScoreForPid(pid int) (int, error) {
	procfsPath := path.Join("/proc", strconv.Itoa(pid), "oom_score_adj")
	out, err := exec.Command("sudo", "cat", procfsPath).CombinedOutput()
	if err != nil {
		return 0, err
	}
	return strconv.Atoi(strings.TrimSpace(string(out)))
}

func validateOOMScoreAdjSetting(pid int, expectedOOMScoreAdj int) error {
	oomScore, err := getOOMScoreForPid(pid)
	if err != nil {
		return fmt.Errorf("failed to get oom_score_adj for %d: %v", pid, err)
	}
	if expectedOOMScoreAdj != oomScore {
		return fmt.Errorf("expected pid %d's oom_score_adj to be %d; found %d", pid, expectedOOMScoreAdj, oomScore)
	}
	return nil
}

func validateOOMScoreAdjSettingIsInRange(pid int, expectedMinOOMScoreAdj, expectedMaxOOMScoreAdj int) error {
	oomScore, err := getOOMScoreForPid(pid)
	if err != nil {
		return fmt.Errorf("failed to get oom_score_adj for %d", pid)
	}
	if oomScore < expectedMinOOMScoreAdj {
		return fmt.Errorf("expected pid %d's oom_score_adj to be >= %d; found %d", pid, expectedMinOOMScoreAdj, oomScore)
	}
	if oomScore < expectedMaxOOMScoreAdj {
		return fmt.Errorf("expected pid %d's oom_score_adj to be < %d; found %d", pid, expectedMaxOOMScoreAdj, oomScore)
	}
	return nil
}

var _ = framework.KubeDescribe("Kubelet Container Manager [Serial]", func() {
	f := framework.NewDefaultFramework("kubelet-container-manager")

	Describe("Validate OOM score adjustments", func() {
		Context("once the node is setup", func() {
			It("docker daemon's oom-score-adj should be -999", func() {
				dockerPids, err := getPidsForProcess(dockerProcessName, dockerPidFile)
				Expect(err).To(BeNil(), "failed to get list of docker daemon pids")
				for _, pid := range dockerPids {
					Eventually(func() error {
						return validateOOMScoreAdjSetting(pid, -999)
					}, 5*time.Minute, 30*time.Second).Should(BeNil())
				}
			})
			It("Kubelet's oom-score-adj should be -999", func() {
				kubeletPids, err := getPidsForProcess(kubeletProcessName, "")
				Expect(err).To(BeNil(), "failed to get list of kubelet pids")
				Expect(len(kubeletPids)).To(Equal(1), "expected only one kubelet process; found %d", len(kubeletPids))
				Eventually(func() error {
					return validateOOMScoreAdjSetting(kubeletPids[0], -999)
				}, 5*time.Minute, 30*time.Second).Should(BeNil())
			})
			It("pod infra containers oom-score-adj should be -998 and best effort container's should be 1000", func() {
				var err error
				podClient := f.PodClient()
				podName := "besteffort" + string(uuid.NewUUID())
				podClient.Create(&v1.Pod{
					ObjectMeta: metav1.ObjectMeta{
						Name: podName,
					},
					Spec: v1.PodSpec{
						Containers: []v1.Container{
							{
								Image: "gcr.io/google_containers/serve_hostname:v1.4",
								Name:  podName,
							},
						},
					},
				})
				var pausePids []int
				By("checking infra container's oom-score-adj")
				Eventually(func() error {
					pausePids, err = getPidsForProcess("pause", "")
					if err != nil {
						return fmt.Errorf("failed to get list of pause pids: %v", err)
					}
					for _, pid := range pausePids {
						if err := validateOOMScoreAdjSetting(pid, -998); err != nil {
							return err
						}
					}
					return nil
				}, 2*time.Minute, time.Second*4).Should(BeNil())
				var shPids []int
				By("checking besteffort container's oom-score-adj")
				Eventually(func() error {
					shPids, err = getPidsForProcess("serve_hostname", "")
					if err != nil {
						return fmt.Errorf("failed to get list of serve hostname process pids: %v", err)
					}
					if len(shPids) != 1 {
						return fmt.Errorf("expected only one serve_hostname process; found %d", len(shPids))
					}
					return validateOOMScoreAdjSetting(shPids[0], 1000)
				}, 2*time.Minute, time.Second*4).Should(BeNil())

			})
			It("guaranteed container's oom-score-adj should be -998", func() {
				podClient := f.PodClient()
				podName := "guaranteed" + string(uuid.NewUUID())
				podClient.Create(&v1.Pod{
					ObjectMeta: metav1.ObjectMeta{
						Name: podName,
					},
					Spec: v1.PodSpec{
						Containers: []v1.Container{
							{
								Image: "gcr.io/google_containers/nginx-slim:0.7",
								Name:  podName,
								Resources: v1.ResourceRequirements{
									Limits: v1.ResourceList{
										"cpu":    resource.MustParse("100m"),
										"memory": resource.MustParse("50Mi"),
									},
								},
							},
						},
					},
				})
				var (
					ngPids []int
					err    error
				)
				Eventually(func() error {
					ngPids, err = getPidsForProcess("nginx", "")
					if err != nil {
						return fmt.Errorf("failed to get list of nginx process pids: %v", err)
					}
					for _, pid := range ngPids {
						if err := validateOOMScoreAdjSetting(pid, -998); err != nil {
							return err
						}
					}

					return nil
				}, 2*time.Minute, time.Second*4).Should(BeNil())

			})
			It("burstable container's oom-score-adj should be between [2, 1000)", func() {
				podClient := f.PodClient()
				podName := "burstable" + string(uuid.NewUUID())
				podClient.Create(&v1.Pod{
					ObjectMeta: metav1.ObjectMeta{
						Name: podName,
					},
					Spec: v1.PodSpec{
						Containers: []v1.Container{
							{
								Image: "gcr.io/google_containers/test-webserver:e2e",
								Name:  podName,
								Resources: v1.ResourceRequirements{
									Requests: v1.ResourceList{
										"cpu":    resource.MustParse("100m"),
										"memory": resource.MustParse("50Mi"),
									},
								},
							},
						},
					},
				})
				var (
					wsPids []int
					err    error
				)
				Eventually(func() error {
					wsPids, err = getPidsForProcess("test-webserver", "")
					if err != nil {
						return fmt.Errorf("failed to get list of test-webserver process pids: %v", err)
					}
					for _, pid := range wsPids {
						if err := validateOOMScoreAdjSettingIsInRange(pid, 2, 1000); err != nil {
							return err
						}
					}
					return nil
				}, 2*time.Minute, time.Second*4).Should(BeNil())

				// TODO: Test the oom-score-adj logic for burstable more accurately.
			})
		})
	})
})
<commit_msg>Print running containers in infra container oom score test.<commit_after>// +build linux

/*
Copyright 2016 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 e2e_node

import (
	"fmt"
	"os/exec"
	"path"
	"strconv"
	"strings"
	"time"

	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/uuid"
	"k8s.io/kubernetes/pkg/api/v1"
	"k8s.io/kubernetes/test/e2e/framework"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

func getOOMScoreForPid(pid int) (int, error) {
	procfsPath := path.Join("/proc", strconv.Itoa(pid), "oom_score_adj")
	out, err := exec.Command("sudo", "cat", procfsPath).CombinedOutput()
	if err != nil {
		return 0, err
	}
	return strconv.Atoi(strings.TrimSpace(string(out)))
}

func validateOOMScoreAdjSetting(pid int, expectedOOMScoreAdj int) error {
	oomScore, err := getOOMScoreForPid(pid)
	if err != nil {
		return fmt.Errorf("failed to get oom_score_adj for %d: %v", pid, err)
	}
	if expectedOOMScoreAdj != oomScore {
		return fmt.Errorf("expected pid %d's oom_score_adj to be %d; found %d", pid, expectedOOMScoreAdj, oomScore)
	}
	return nil
}

func validateOOMScoreAdjSettingIsInRange(pid int, expectedMinOOMScoreAdj, expectedMaxOOMScoreAdj int) error {
	oomScore, err := getOOMScoreForPid(pid)
	if err != nil {
		return fmt.Errorf("failed to get oom_score_adj for %d", pid)
	}
	if oomScore < expectedMinOOMScoreAdj {
		return fmt.Errorf("expected pid %d's oom_score_adj to be >= %d; found %d", pid, expectedMinOOMScoreAdj, oomScore)
	}
	if oomScore < expectedMaxOOMScoreAdj {
		return fmt.Errorf("expected pid %d's oom_score_adj to be < %d; found %d", pid, expectedMaxOOMScoreAdj, oomScore)
	}
	return nil
}

var _ = framework.KubeDescribe("Kubelet Container Manager [Serial]", func() {
	f := framework.NewDefaultFramework("kubelet-container-manager")

	Describe("Validate OOM score adjustments", func() {
		Context("once the node is setup", func() {
			It("docker daemon's oom-score-adj should be -999", func() {
				dockerPids, err := getPidsForProcess(dockerProcessName, dockerPidFile)
				Expect(err).To(BeNil(), "failed to get list of docker daemon pids")
				for _, pid := range dockerPids {
					Eventually(func() error {
						return validateOOMScoreAdjSetting(pid, -999)
					}, 5*time.Minute, 30*time.Second).Should(BeNil())
				}
			})
			It("Kubelet's oom-score-adj should be -999", func() {
				kubeletPids, err := getPidsForProcess(kubeletProcessName, "")
				Expect(err).To(BeNil(), "failed to get list of kubelet pids")
				Expect(len(kubeletPids)).To(Equal(1), "expected only one kubelet process; found %d", len(kubeletPids))
				Eventually(func() error {
					return validateOOMScoreAdjSetting(kubeletPids[0], -999)
				}, 5*time.Minute, 30*time.Second).Should(BeNil())
			})
			Context("", func() {
				It("pod infra containers oom-score-adj should be -998 and best effort container's should be 1000", func() {
					var err error
					podClient := f.PodClient()
					podName := "besteffort" + string(uuid.NewUUID())
					podClient.Create(&v1.Pod{
						ObjectMeta: metav1.ObjectMeta{
							Name: podName,
						},
						Spec: v1.PodSpec{
							Containers: []v1.Container{
								{
									Image: "gcr.io/google_containers/serve_hostname:v1.4",
									Name:  podName,
								},
							},
						},
					})
					var pausePids []int
					By("checking infra container's oom-score-adj")
					Eventually(func() error {
						pausePids, err = getPidsForProcess("pause", "")
						if err != nil {
							return fmt.Errorf("failed to get list of pause pids: %v", err)
						}
						for _, pid := range pausePids {
							if err := validateOOMScoreAdjSetting(pid, -998); err != nil {
								return err
							}
						}
						return nil
					}, 2*time.Minute, time.Second*4).Should(BeNil())
					var shPids []int
					By("checking besteffort container's oom-score-adj")
					Eventually(func() error {
						shPids, err = getPidsForProcess("serve_hostname", "")
						if err != nil {
							return fmt.Errorf("failed to get list of serve hostname process pids: %v", err)
						}
						if len(shPids) != 1 {
							return fmt.Errorf("expected only one serve_hostname process; found %d", len(shPids))
						}
						return validateOOMScoreAdjSetting(shPids[0], 1000)
					}, 2*time.Minute, time.Second*4).Should(BeNil())
				})
				// Log the running containers here to help debugging. Use `docker ps`
				// directly for now because the test is already docker specific.
				AfterEach(func() {
					if CurrentGinkgoTestDescription().Failed {
						By("Dump all running docker containers")
						output, err := exec.Command("docker", "ps").CombinedOutput()
						Expect(err).NotTo(HaveOccurred())
						framework.Logf("Running docker containers:\n%s", string(output))
					}
				})
			})
			It("guaranteed container's oom-score-adj should be -998", func() {
				podClient := f.PodClient()
				podName := "guaranteed" + string(uuid.NewUUID())
				podClient.Create(&v1.Pod{
					ObjectMeta: metav1.ObjectMeta{
						Name: podName,
					},
					Spec: v1.PodSpec{
						Containers: []v1.Container{
							{
								Image: "gcr.io/google_containers/nginx-slim:0.7",
								Name:  podName,
								Resources: v1.ResourceRequirements{
									Limits: v1.ResourceList{
										"cpu":    resource.MustParse("100m"),
										"memory": resource.MustParse("50Mi"),
									},
								},
							},
						},
					},
				})
				var (
					ngPids []int
					err    error
				)
				Eventually(func() error {
					ngPids, err = getPidsForProcess("nginx", "")
					if err != nil {
						return fmt.Errorf("failed to get list of nginx process pids: %v", err)
					}
					for _, pid := range ngPids {
						if err := validateOOMScoreAdjSetting(pid, -998); err != nil {
							return err
						}
					}

					return nil
				}, 2*time.Minute, time.Second*4).Should(BeNil())

			})
			It("burstable container's oom-score-adj should be between [2, 1000)", func() {
				podClient := f.PodClient()
				podName := "burstable" + string(uuid.NewUUID())
				podClient.Create(&v1.Pod{
					ObjectMeta: metav1.ObjectMeta{
						Name: podName,
					},
					Spec: v1.PodSpec{
						Containers: []v1.Container{
							{
								Image: "gcr.io/google_containers/test-webserver:e2e",
								Name:  podName,
								Resources: v1.ResourceRequirements{
									Requests: v1.ResourceList{
										"cpu":    resource.MustParse("100m"),
										"memory": resource.MustParse("50Mi"),
									},
								},
							},
						},
					},
				})
				var (
					wsPids []int
					err    error
				)
				Eventually(func() error {
					wsPids, err = getPidsForProcess("test-webserver", "")
					if err != nil {
						return fmt.Errorf("failed to get list of test-webserver process pids: %v", err)
					}
					for _, pid := range wsPids {
						if err := validateOOMScoreAdjSettingIsInRange(pid, 2, 1000); err != nil {
							return err
						}
					}
					return nil
				}, 2*time.Minute, time.Second*4).Should(BeNil())

				// TODO: Test the oom-score-adj logic for burstable more accurately.
			})
		})
	})
})
<|endoftext|>


<commit_before>/*
Copyright 2016 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 main

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"k8s.io/kubernetes/test/e2e_node/builder"
	"k8s.io/kubernetes/test/e2e_node/system"
	"k8s.io/kubernetes/test/utils"

	"k8s.io/klog/v2"
)

var buildDependencies = flag.Bool("build-dependencies", true, "If true, build all dependencies.")
var ginkgoFlags = flag.String("ginkgo-flags", "", "Space-separated list of arguments to pass to Ginkgo test runner.")
var testFlags = flag.String("test-flags", "", "Space-separated list of arguments to pass to node e2e test.")
var systemSpecName = flag.String("system-spec-name", "", fmt.Sprintf("The name of the system spec used for validating the image in the node conformance test. The specs are at %s. If unspecified, the default built-in spec (system.DefaultSpec) will be used.", system.SystemSpecPath))
var extraEnvs = flag.String("extra-envs", "", "The extra environment variables needed for node e2e tests. Format: a list of key=value pairs, e.g., env1=val1,env2=val2")

func main() {
	klog.InitFlags(nil)
	flag.Parse()

	// Build dependencies - ginkgo, kubelet and apiserver.
	if *buildDependencies {
		if err := builder.BuildGo(); err != nil {
			klog.Fatalf("Failed to build the dependencies: %v", err)
		}
	}

	// Run node e2e test
	outputDir, err := utils.GetK8sBuildOutputDir()
	if err != nil {
		klog.Fatalf("Failed to get build output directory: %v", err)
	}
	klog.Infof("Got build output dir: %v", outputDir)
	ginkgo := filepath.Join(outputDir, "ginkgo")
	test := filepath.Join(outputDir, "e2e_node.test")

	args := []string{*ginkgoFlags, test, "--", *testFlags}
	if *systemSpecName != "" {
		rootDir, err := utils.GetK8sRootDir()
		if err != nil {
			klog.Fatalf("Failed to get k8s root directory: %v", err)
		}
		systemSpecFile := filepath.Join(rootDir, system.SystemSpecPath, *systemSpecName+".yaml")
		args = append(args, fmt.Sprintf("--system-spec-name=%s --system-spec-file=%s --extra-envs=%s", *systemSpecName, systemSpecFile, *extraEnvs))
	}
	if err := runCommand(ginkgo, args...); err != nil {
		klog.Exitf("Test failed: %v", err)
	}
	return
}

func runCommand(name string, args ...string) error {
	klog.Infof("Running command: %v %v", name, strings.Join(args, " "))
	cmd := exec.Command("sudo", "sh", "-c", strings.Join(append([]string{name}, args...), " "))
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}
<commit_msg>Update dependencies in local node test runner<commit_after>/*
Copyright 2016 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 main

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"k8s.io/kubernetes/test/e2e_node/builder"
	"k8s.io/kubernetes/test/e2e_node/system"
	"k8s.io/kubernetes/test/utils"

	"k8s.io/klog/v2"
)

var buildDependencies = flag.Bool("build-dependencies", true, "If true, build all dependencies.")
var ginkgoFlags = flag.String("ginkgo-flags", "", "Space-separated list of arguments to pass to Ginkgo test runner.")
var testFlags = flag.String("test-flags", "", "Space-separated list of arguments to pass to node e2e test.")
var systemSpecName = flag.String("system-spec-name", "", fmt.Sprintf("The name of the system spec used for validating the image in the node conformance test. The specs are at %s. If unspecified, the default built-in spec (system.DefaultSpec) will be used.", system.SystemSpecPath))
var extraEnvs = flag.String("extra-envs", "", "The extra environment variables needed for node e2e tests. Format: a list of key=value pairs, e.g., env1=val1,env2=val2")

func main() {
	klog.InitFlags(nil)
	flag.Parse()

	// Build dependencies - ginkgo, kubelet, e2e_node.test, and mounter.
	if *buildDependencies {
		if err := builder.BuildGo(); err != nil {
			klog.Fatalf("Failed to build the dependencies: %v", err)
		}
	}

	// Run node e2e test
	outputDir, err := utils.GetK8sBuildOutputDir()
	if err != nil {
		klog.Fatalf("Failed to get build output directory: %v", err)
	}
	klog.Infof("Got build output dir: %v", outputDir)
	ginkgo := filepath.Join(outputDir, "ginkgo")
	test := filepath.Join(outputDir, "e2e_node.test")

	args := []string{*ginkgoFlags, test, "--", *testFlags}
	if *systemSpecName != "" {
		rootDir, err := utils.GetK8sRootDir()
		if err != nil {
			klog.Fatalf("Failed to get k8s root directory: %v", err)
		}
		systemSpecFile := filepath.Join(rootDir, system.SystemSpecPath, *systemSpecName+".yaml")
		args = append(args, fmt.Sprintf("--system-spec-name=%s --system-spec-file=%s --extra-envs=%s", *systemSpecName, systemSpecFile, *extraEnvs))
	}
	if err := runCommand(ginkgo, args...); err != nil {
		klog.Exitf("Test failed: %v", err)
	}
	return
}

func runCommand(name string, args ...string) error {
	klog.Infof("Running command: %v %v", name, strings.Join(args, " "))
	cmd := exec.Command("sudo", "sh", "-c", strings.Join(append([]string{name}, args...), " "))
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	return cmd.Run()
}
<|endoftext|>


<commit_before>package module

import (
	"log"

	r "github.com/dancannon/gorethink"
)

// RSession rethink
var (
	RSession *r.Session
)

func init() {
	var err error

	host := "localhost"
	port := "28015"
	db := "mango"
	maxOpen := 40

	RSession, err = r.Connect(r.ConnectOpts{
		Address:  host + ":" + port,
		Database: db,
		MaxOpen:  maxOpen,
	})

	if err != nil {
		log.Fatalln(err.Error())
	}
}
<commit_msg>automaticall create db<commit_after>package module

import (
	"log"

	r "github.com/dancannon/gorethink"
)

// RSession rethink
var (
	RSession *r.Session
)

func init() {
	var err error

	host := "localhost"
	port := "28015"
	db := "mango"
	maxOpen := 40

	RSession, err = r.Connect(r.ConnectOpts{
		Address:  host + ":" + port,
		Database: db,
		MaxOpen:  maxOpen,
	})

	if err != nil {
		log.Fatalln(err.Error())
	}

	r.DBCreate(db).Run(RSession)
}
<|endoftext|>


<commit_before>package zoom

// File declares all the different errors that might be thrown
// by the package and provides constructors for each one.

import (
	"reflect"
)

// ---
// NameAlreadyRegistered
type NameAlreadyRegisteredError struct {
	name string
}

func (e *NameAlreadyRegisteredError) Error() string {
	return "The name '" + e.name + "' has already been registered."
}

func NewNameAlreadyRegisteredError(name string) *NameAlreadyRegisteredError {
	return &NameAlreadyRegisteredError{name}
}

// ---
// TypeAlreadyRegistered
type TypeAlreadyRegisteredError struct {
	typ reflect.Type
}

func (e *TypeAlreadyRegisteredError) Error() string {
	return "The type '" + e.typ.String() + "' has already been registered."
}

func NewTypeAlreadyRegisteredError(typ reflect.Type) *TypeAlreadyRegisteredError {
	return &TypeAlreadyRegisteredError{typ}
}

// ---
// ModelTypeNotRegistered
type ModelTypeNotRegisteredError struct {
	typ reflect.Type
}

func (e *ModelTypeNotRegisteredError) Error() string {
	return "The type '" + e.typ.String() + "' has not been registered."
}

func NewModelTypeNotRegisteredError(typ reflect.Type) *ModelTypeNotRegisteredError {
	return &ModelTypeNotRegisteredError{typ}
}

// ---
// ModelNameNotRegistered
type ModelNameNotRegisteredError struct {
	name string
}

func (e *ModelNameNotRegisteredError) Error() string {
	return "The model name '" + e.name + "' has not been registered."
}

func NewModelNameNotRegisteredError(name string) *ModelNameNotRegisteredError {
	return &ModelNameNotRegisteredError{name}
}

// ---
// KeyNotFound
type KeyNotFoundError struct {
	msg string
}

func (e *KeyNotFoundError) Error() string {
	return e.msg
}

func NewKeyNotFoundError(msg string) *KeyNotFoundError {
	e := KeyNotFoundError{msg}
	return &e
}
<commit_msg>Refactor errors.go. Add a zoom prefix to all errors.<commit_after>package zoom

// File declares all the different errors that might be thrown
// by the package and provides constructors for each one.

import (
	"reflect"
)

// ---
// NameAlreadyRegistered
type NameAlreadyRegisteredError struct {
	name string
}

func (e *NameAlreadyRegisteredError) Error() string {
	return "zoom: the name '" + e.name + "' has already been registered"
}

func NewNameAlreadyRegisteredError(name string) *NameAlreadyRegisteredError {
	return &NameAlreadyRegisteredError{name}
}

// ---
// TypeAlreadyRegistered
type TypeAlreadyRegisteredError struct {
	typ reflect.Type
}

func (e *TypeAlreadyRegisteredError) Error() string {
	return "zoom: the type '" + e.typ.String() + "' has already been registered"
}

func NewTypeAlreadyRegisteredError(typ reflect.Type) *TypeAlreadyRegisteredError {
	return &TypeAlreadyRegisteredError{typ}
}

// ---
// ModelTypeNotRegistered
type ModelTypeNotRegisteredError struct {
	typ reflect.Type
}

func (e *ModelTypeNotRegisteredError) Error() string {
	return "zoom: the type '" + e.typ.String() + "' has not been registered"
}

func NewModelTypeNotRegisteredError(typ reflect.Type) *ModelTypeNotRegisteredError {
	return &ModelTypeNotRegisteredError{typ}
}

// ---
// ModelNameNotRegistered
type ModelNameNotRegisteredError struct {
	name string
}

func (e *ModelNameNotRegisteredError) Error() string {
	return "zoom: the model name '" + e.name + "' has not been registered"
}

func NewModelNameNotRegisteredError(name string) *ModelNameNotRegisteredError {
	return &ModelNameNotRegisteredError{name}
}
<|endoftext|>


<commit_before>package plist

// #include <CoreFoundation/CoreFoundation.h>
import "C"
import "reflect"
import "strconv"

// An UnsupportedTypeError is returned by Marshal when attempting to encode an
// unsupported value type.
type UnsupportedTypeError struct {
	Type reflect.Type
}

func (e *UnsupportedTypeError) Error() string {
	return "plist: unsupported type: " + e.Type.String()
}

type UnsupportedValueError struct {
	Value reflect.Value
	Str   string
}

func (e *UnsupportedValueError) Error() string {
	return "json: unsupported value: " + e.Str
}

type UnknownCFTypeError struct {
	CFTypeID C.CFTypeID
}

func (e *UnknownCFTypeError) Error() string {
	return "plist: unknown CFTypeID " + strconv.Itoa(int(e.CFTypeID))
}

// UnsupportedKeyTypeError represents the case where a CFDictionary is being converted
// back into a map[string]interface{} but its key type is not a CFString.
//
// This should never occur in practice, because the only CFDictionaries that
// should be handled are coming from property lists, which require the keys to
// be strings.
type UnsupportedKeyTypeError struct {
	CFTypeID int
}

func (e *UnsupportedKeyTypeError) Error() string {
	return "plist: unexpected dictionary key CFTypeID " + strconv.Itoa(e.CFTypeID)
}
<commit_msg>Update UnknownCFTypeError to print the type name<commit_after>package plist

// #include <CoreFoundation/CoreFoundation.h>
import "C"
import "reflect"
import "strconv"

// An UnsupportedTypeError is returned by Marshal when attempting to encode an
// unsupported value type.
type UnsupportedTypeError struct {
	Type reflect.Type
}

func (e *UnsupportedTypeError) Error() string {
	return "plist: unsupported type: " + e.Type.String()
}

type UnsupportedValueError struct {
	Value reflect.Value
	Str   string
}

func (e *UnsupportedValueError) Error() string {
	return "json: unsupported value: " + e.Str
}

type UnknownCFTypeError struct {
	CFTypeID C.CFTypeID
}

func (e *UnknownCFTypeError) Error() string {
	cfStr := C.CFCopyTypeIDDescription(e.CFTypeID)
	str := convertCFStringToString(cfStr)
	cfRelease(cfTypeRef(cfStr))
	return "plist: unknown CFTypeID " + strconv.Itoa(int(e.CFTypeID)) + " (" + str + ")"
}

// UnsupportedKeyTypeError represents the case where a CFDictionary is being converted
// back into a map[string]interface{} but its key type is not a CFString.
//
// This should never occur in practice, because the only CFDictionaries that
// should be handled are coming from property lists, which require the keys to
// be strings.
type UnsupportedKeyTypeError struct {
	CFTypeID int
}

func (e *UnsupportedKeyTypeError) Error() string {
	return "plist: unexpected dictionary key CFTypeID " + strconv.Itoa(e.CFTypeID)
}
<|endoftext|>


<commit_before>// benchmark.go
//
// vim: ft=go sw=4 ts=4
//
// A set of (micro-) benchmarks for the Go programming language
//

package main

import (
	"benchmark/fib"
	"benchmark/mandelbrot"
	"benchmark/perfectnumber"
	"fmt"
	"time"
)

// main entry point
func main() {

	var tic, toc time.Time

	fmt.Println("Fibonacci numbers")
	fmt.Println("=================")

	tic = time.Now()
	res0 := fib.FibNaive(35)
	toc = time.Now()
	fmt.Printf("FibNaive(35) = %d\tElapsed time: %fs\n", res0, toc.Sub(tic).Seconds())

	tic = time.Now()
	res1 := fib.Fib(35).String()
	toc = time.Now()
	fmt.Printf("Fib(35)      = %s\tElapsed time: %fs\n", res1, toc.Sub(tic).Seconds())

	tic = time.Now()
	res2 := fib.Fib(1000).String()
	toc = time.Now()
	fmt.Printf("Fib(1000)    = %s\tElapsed time: %fs\n", res2, toc.Sub(tic).Seconds())

	fmt.Println()
	fmt.Println("Perfect numbers")
	fmt.Println("===============")

	tic = time.Now()
	res3 := perfectnumber.PerfectNumbers(10000)
	toc = time.Now()
	fmt.Printf("PerfectNumbers(10000) = %v\tElapsed time: %fs\n", res3, toc.Sub(tic).Seconds())
	tic = time.Now()
	res4 := []int{}
	for pn := range perfectnumber.PerfectNumbersAsync(10000) {
		res4 = append(res4, pn)
	}
	toc = time.Now()
	fmt.Printf("PerfectNumbersAsync(10000) = %v\tElapsed time: %fs\n", res4, toc.Sub(tic).Seconds())
	fmt.Println()

	fmt.Println("Mandelbrot set")
	fmt.Println("==============")
	tic = time.Now()
	img1 := mandelbrot.Mandelbrot(640, 480, -0.5, 0.0, 4.0/640)
	toc = time.Now()
	fmt.Printf("Mandelbrot(%d x %d)\tElapsed time: %fs\n",
		img1.Rect.Max.X, img1.Rect.Max.Y, toc.Sub(tic).Seconds())

	tic = time.Now()
	img2 := mandelbrot.Mandelbrot(1920, 1200, -0.5, 0.0, 4.0/1920)
	toc = time.Now()
	fmt.Printf("Mandelbrot(%d x %d)\tElapsed time: %fs\n",
		img2.Rect.Max.X, img2.Rect.Max.Y, toc.Sub(tic).Seconds())

	tic = time.Now()
	mbAsync := mandelbrot.MandelbrotAsync(1920, 1200, -0.5, 0.0, 4.0/1920)
	img3 := <-mbAsync
	toc = time.Now()
	fmt.Printf("Mandelbrot(%d x %d)\tElapsed time: %fs\n",
		img3.Rect.Max.X, img3.Rect.Max.Y, toc.Sub(tic).Seconds())

	tic = time.Now()
	err1 := mandelbrot.WritePng("mandelbrot_640x480.png", img1)
	toc = time.Now()
	fmt.Printf("Mandelbrot(640 x 480) written to file. Error: %v\tElapsed time: %fs\n", err1, toc.Sub(tic).Seconds())

	tic = time.Now()
	err2 := mandelbrot.WritePng("mandelbrot_1920x1200.png", img2)
	toc = time.Now()
	fmt.Printf("Mandelbrot(1920 x 1200) written to file. Error: %v\tElapsed time: %fs\n", err2, toc.Sub(tic).Seconds())
	fmt.Println()
}
<commit_msg>fix function name in printed output<commit_after>// benchmark.go
//
// vim: ft=go sw=4 ts=4
//
// A set of (micro-) benchmarks for the Go programming language
//

package main

import (
	"benchmark/fib"
	"benchmark/mandelbrot"
	"benchmark/perfectnumber"
	"fmt"
	"time"
)

// main entry point
func main() {

	var tic, toc time.Time

	fmt.Println("Fibonacci numbers")
	fmt.Println("=================")

	tic = time.Now()
	res0 := fib.FibNaive(35)
	toc = time.Now()
	fmt.Printf("FibNaive(35) = %d\tElapsed time: %fs\n", res0, toc.Sub(tic).Seconds())

	tic = time.Now()
	res1 := fib.Fib(35).String()
	toc = time.Now()
	fmt.Printf("Fib(35)      = %s\tElapsed time: %fs\n", res1, toc.Sub(tic).Seconds())

	tic = time.Now()
	res2 := fib.Fib(1000).String()
	toc = time.Now()
	fmt.Printf("Fib(1000)    = %s\tElapsed time: %fs\n", res2, toc.Sub(tic).Seconds())

	fmt.Println()
	fmt.Println("Perfect numbers")
	fmt.Println("===============")

	tic = time.Now()
	res3 := perfectnumber.PerfectNumbers(10000)
	toc = time.Now()
	fmt.Printf("PerfectNumbers(10000) = %v\tElapsed time: %fs\n", res3, toc.Sub(tic).Seconds())
	tic = time.Now()
	res4 := []int{}
	for pn := range perfectnumber.PerfectNumbersAsync(10000) {
		res4 = append(res4, pn)
	}
	toc = time.Now()
	fmt.Printf("PerfectNumbersAsync(10000) = %v\tElapsed time: %fs\n", res4, toc.Sub(tic).Seconds())
	fmt.Println()

	fmt.Println("Mandelbrot set")
	fmt.Println("==============")
	tic = time.Now()
	img1 := mandelbrot.Mandelbrot(640, 480, -0.5, 0.0, 4.0/640)
	toc = time.Now()
	fmt.Printf("Mandelbrot(%d x %d)\tElapsed time: %fs\n",
		img1.Rect.Max.X, img1.Rect.Max.Y, toc.Sub(tic).Seconds())

	tic = time.Now()
	img2 := mandelbrot.Mandelbrot(1920, 1200, -0.5, 0.0, 4.0/1920)
	toc = time.Now()
	fmt.Printf("Mandelbrot(%d x %d)\tElapsed time: %fs\n",
		img2.Rect.Max.X, img2.Rect.Max.Y, toc.Sub(tic).Seconds())

	tic = time.Now()
	mbAsync := mandelbrot.MandelbrotAsync(1920, 1200, -0.5, 0.0, 4.0/1920)
	img3 := <-mbAsync
	toc = time.Now()
	fmt.Printf("MandelbrotAsync(%d x %d)\tElapsed time: %fs\n",
		img3.Rect.Max.X, img3.Rect.Max.Y, toc.Sub(tic).Seconds())

	tic = time.Now()
	err1 := mandelbrot.WritePng("mandelbrot_640x480.png", img1)
	toc = time.Now()
	fmt.Printf("Mandelbrot(640 x 480) written to file. Error: %v\tElapsed time: %fs\n", err1, toc.Sub(tic).Seconds())

	tic = time.Now()
	err2 := mandelbrot.WritePng("mandelbrot_1920x1200.png", img2)
	toc = time.Now()
	fmt.Printf("Mandelbrot(1920 x 1200) written to file. Error: %v\tElapsed time: %fs\n", err2, toc.Sub(tic).Seconds())
	fmt.Println()
}
<|endoftext|>


<commit_before>// Copyright 2015 Davis Webb
// Copyright 2015 Guntas Grewal
// Copyright 2015 Luke Shumaker

package store

import (
	"encoding/json"
	"errors"
	"github.com/jinzhu/gorm"
	"golang.org/x/crypto/bcrypt"
	he "httpentity"
	"httpentity/util" // heutil
	"io"
	"jsonpatch"
	"periwinkle/util" // putil
	"strings"
)

var _ he.Entity = &User{}
var _ he.NetEntity = &User{}
var dirUsers he.Entity = newDirUsers()

// Model /////////////////////////////////////////////////////////////

type User struct {
	Id        string        `json:"user_id"`
	FullName  string        `json:"fullname"`
	PwHash    []byte        `json:"-"`
	Addresses []UserAddress `json:"addresses"`
}

func (o User) schema(db *gorm.DB) {
	db.CreateTable(&o)
}

type UserAddress struct {
	Id      int64  `json:"-"`
	UserId  string `json:"-"`
	Medium  string `json:"medium"`
	Address string `json:"address"`
}

func (o UserAddress) schema(db *gorm.DB) {
	table := db.CreateTable(&o)
	table.AddForeignKey("user_id", "users(id)", "RESTRICT", "RESTRICT")
	table.AddForeignKey("medium", "media(id)", "RESTRICT", "RESTRICT")
	table.AddUniqueIndex("uniqueness_idx", "medium", "address")
}

func GetUserById(db *gorm.DB, id string) *User {
	id = strings.ToLower(id)
	var o User
	if result := db.First(&o, "id = ?", id); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	db.Model(&o).Related(&o.Addresses)
	return &o
}

func GetUserByAddress(db *gorm.DB, medium string, address string) *User {
	var o User
	result := db.Joins("inner join user_addresses on user_addresses.user_id=users.id").Where("user_addresses.medium=? and user_addresses.address=?", medium, address).Find(&o)
	if result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	db.Model(&o).Related(&o.Addresses)
	return &o
}

func (u *User) SetPassword(password string) error {
	hash, err := bcrypt.GenerateFromPassword([]byte(password), -1)
	u.PwHash = hash
	return err
}

func (u *User) CheckPassword(password string) bool {
	err := bcrypt.CompareHashAndPassword(u.PwHash, []byte(password))
	return err == nil
}

var BadPasswordErr = errors.New("Password was incorrect")

func (u *User) UpdatePassword(db *gorm.DB, newPass string, oldPass string) error {
	if !u.CheckPassword(oldPass) {
		return BadPasswordErr
	}
	if err := u.SetPassword(newPass); err != nil {
		return err
	}
	u.Save(db)
	return nil
}

func (u *User) UpdateEmail(db *gorm.DB, newEmail string, pw string) {
	if !u.CheckPassword(pw) {
		panic("Password was incorrect")
	}
	for _, addr := range u.Addresses {
		if addr.Medium == "email" {
			addr.Address = newEmail
			if err := db.Save(&addr).Error; err != nil {
				panic(err)
			}
		}
	}
}

func NewUser(db *gorm.DB, name string, password string, email string) *User {
	o := User{
		Id:        name,
		FullName:  "",
		Addresses: []UserAddress{{Medium: "email", Address: email}},
	}
	if err := o.SetPassword(password); err != nil {
		panic(err)
	}
	if err := db.Create(&o).Error; err != nil {
		panic(err)
	}
	return &o
}

func (o *User) Save(db *gorm.DB) {
	if err := db.Save(o).Error; err != nil {
		panic(err)
	}
}

func (o *User) Subentity(name string, req he.Request) he.Entity {
	return nil
}

func (o *User) patchPassword(patch *jsonpatch.Patch) putil.HTTPError {
	// this is in the running for the grossest code I've ever
	// written, but I think it's the best way to do it --lukeshu
	type patchop struct {
		Op    string
		Path  string
		Value string
	}
	str, err := json.Marshal(patch)
	if err != nil {
		panic(err)
	}
	var ops []patchop
	err = json.Unmarshal(str, &ops)
	if err != nil {
		return nil
	}
	out_ops := make([]patchop, 0, len(ops))
	checkedpass := false
	for _, op := range ops {
		if op.Path == "/password" {
			switch op.Op {
			case "test":
				if !o.CheckPassword(op.Value) {
					return putil.HTTPErrorf(409, "old password didn't match")
				}
				checkedpass = true
			case "replace":
				if !checkedpass {
					return putil.HTTPErrorf(409, "you must submit and old password (using 'test') before setting a new one")
				}
				o.SetPassword(op.Value)
			default:
				return putil.HTTPErrorf(415, "you may only 'set' or 'replace' the password")
			}
		} else {
			out_ops = append(out_ops, op)
		}
	}
	str, err = json.Marshal(out_ops)
	if err != nil {
		panic(err)
	}
	var out jsonpatch.JSONPatch
	err = json.Unmarshal(str, &out)
	if err != nil {
		panic(out)
	}
	*patch = out
	return nil
}

func (o *User) Methods() map[string]func(he.Request) he.Response {
	return map[string]func(he.Request) he.Response{
		"GET": func(req he.Request) he.Response {
			return he.StatusOK(o)
		},
		"PUT": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			sess := req.Things["session"].(*Session)
			if sess.UserId != o.Id {
				return he.StatusForbidden(heutil.NetString("Unauthorized user"))
			}
			var new_user User
			err := safeDecodeJSON(req.Entity, &new_user)
			if err != nil {
				return err.Response()
			}
			if o.Id != new_user.Id {
				return he.StatusConflict(heutil.NetString("Cannot change user id"))
			}
			*o = new_user
			o.Save(db)
			return he.StatusOK(o)
		},
		"PATCH": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			sess := req.Things["session"].(*Session)
			if sess.UserId != o.Id {
				return he.StatusForbidden(heutil.NetString("Unauthorized user"))
			}
			patch, ok := req.Entity.(jsonpatch.Patch)
			if !ok {
				return putil.HTTPErrorf(415, "PATCH request must have a patch media type").Response()
			}
			httperr := o.patchPassword(&patch)
			if httperr != nil {
				return httperr.Response()
			}
			var new_user User
			err := patch.Apply(o, &new_user)
			if err != nil {
				return putil.HTTPErrorf(409, "%v", err).Response()
			}
			if o.Id != new_user.Id {
				return he.StatusConflict(heutil.NetString("Cannot change user id"))
			}
			*o = new_user
			o.Save(db)
			return he.StatusOK(o)
		},
		"DELETE": func(req he.Request) he.Response {
			panic("TODO: API: (*User).Methods()[\"DELETE\"]")
		},
	}
}

// View //////////////////////////////////////////////////////////////

func (o *User) Encoders() map[string]func(io.Writer) error {
	return defaultEncoders(o)
}

// Directory ("Controller") //////////////////////////////////////////

type t_dirUsers struct {
	methods map[string]func(he.Request) he.Response
}

func newDirUsers() t_dirUsers {
	r := t_dirUsers{}
	r.methods = map[string]func(he.Request) he.Response{
		"POST": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			type postfmt struct {
				Username             string `json:"username"`
				Email                string `json:"email"`
				Password             string `json:"password"`
				PasswordVerification string `json:"password_verification,omitempty`
			}
			var entity postfmt
			httperr := safeDecodeJSON(req.Entity, &entity)
			if httperr != nil {
				return httperr.Response()
			}

			if entity.PasswordVerification != "" {
				if entity.Password != entity.PasswordVerification {
					// Passwords don't match
					return he.StatusConflict(heutil.NetString("password and password_verification don't match"))
				}
			}

			entity.Username = strings.ToLower(entity.Username)

			user := NewUser(db, entity.Username, entity.Password, entity.Email)
			if user == nil {
				return putil.HTTPErrorf(409, "either that username or password is already taken").Response()
			} else {
				return he.StatusCreated(r, entity.Username, req)
			}
		},
	}
	return r
}

func (d t_dirUsers) Methods() map[string]func(he.Request) he.Response {
	return d.methods
}

func (d t_dirUsers) Subentity(name string, req he.Request) he.Entity {
	sess := req.Things["session"].(*Session)
	if sess == nil && req.Method == "POST" {
		type postfmt struct {
			Username             string `json:"username"`
			Email                string `json:"email"`
			Password             string `json:"password"`
			PasswordVerification string `json:"password_verification,omitempty`
		}
		var entity postfmt
		httperr := safeDecodeJSON(req.Entity, &entity)
		if httperr != nil {
			return nil
		}
		db := req.Things["db"].(*gorm.DB)
		user := GetUserById(db, entity.Username)
		if !user.CheckPassword(entity.Password) {
			return nil
		} else {
			return user
		}
	} else if sess.UserId != name {
		return nil
	}
	db := req.Things["db"].(*gorm.DB)
	return GetUserById(db, name)
}
<commit_msg>govet<commit_after>// Copyright 2015 Davis Webb
// Copyright 2015 Guntas Grewal
// Copyright 2015 Luke Shumaker

package store

import (
	"encoding/json"
	"errors"
	"github.com/jinzhu/gorm"
	"golang.org/x/crypto/bcrypt"
	he "httpentity"
	"httpentity/util" // heutil
	"io"
	"jsonpatch"
	"periwinkle/util" // putil
	"strings"
)

var _ he.Entity = &User{}
var _ he.NetEntity = &User{}
var dirUsers he.Entity = newDirUsers()

// Model /////////////////////////////////////////////////////////////

type User struct {
	Id        string        `json:"user_id"`
	FullName  string        `json:"fullname"`
	PwHash    []byte        `json:"-"`
	Addresses []UserAddress `json:"addresses"`
}

func (o User) schema(db *gorm.DB) {
	db.CreateTable(&o)
}

type UserAddress struct {
	Id      int64  `json:"-"`
	UserId  string `json:"-"`
	Medium  string `json:"medium"`
	Address string `json:"address"`
}

func (o UserAddress) schema(db *gorm.DB) {
	table := db.CreateTable(&o)
	table.AddForeignKey("user_id", "users(id)", "RESTRICT", "RESTRICT")
	table.AddForeignKey("medium", "media(id)", "RESTRICT", "RESTRICT")
	table.AddUniqueIndex("uniqueness_idx", "medium", "address")
}

func GetUserById(db *gorm.DB, id string) *User {
	id = strings.ToLower(id)
	var o User
	if result := db.First(&o, "id = ?", id); result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	db.Model(&o).Related(&o.Addresses)
	return &o
}

func GetUserByAddress(db *gorm.DB, medium string, address string) *User {
	var o User
	result := db.Joins("inner join user_addresses on user_addresses.user_id=users.id").Where("user_addresses.medium=? and user_addresses.address=?", medium, address).Find(&o)
	if result.Error != nil {
		if result.RecordNotFound() {
			return nil
		}
		panic(result.Error)
	}
	db.Model(&o).Related(&o.Addresses)
	return &o
}

func (u *User) SetPassword(password string) error {
	hash, err := bcrypt.GenerateFromPassword([]byte(password), -1)
	u.PwHash = hash
	return err
}

func (u *User) CheckPassword(password string) bool {
	err := bcrypt.CompareHashAndPassword(u.PwHash, []byte(password))
	return err == nil
}

var BadPasswordErr = errors.New("Password was incorrect")

func (u *User) UpdatePassword(db *gorm.DB, newPass string, oldPass string) error {
	if !u.CheckPassword(oldPass) {
		return BadPasswordErr
	}
	if err := u.SetPassword(newPass); err != nil {
		return err
	}
	u.Save(db)
	return nil
}

func (u *User) UpdateEmail(db *gorm.DB, newEmail string, pw string) {
	if !u.CheckPassword(pw) {
		panic("Password was incorrect")
	}
	for _, addr := range u.Addresses {
		if addr.Medium == "email" {
			addr.Address = newEmail
			if err := db.Save(&addr).Error; err != nil {
				panic(err)
			}
		}
	}
}

func NewUser(db *gorm.DB, name string, password string, email string) *User {
	o := User{
		Id:        name,
		FullName:  "",
		Addresses: []UserAddress{{Medium: "email", Address: email}},
	}
	if err := o.SetPassword(password); err != nil {
		panic(err)
	}
	if err := db.Create(&o).Error; err != nil {
		panic(err)
	}
	return &o
}

func (o *User) Save(db *gorm.DB) {
	if err := db.Save(o).Error; err != nil {
		panic(err)
	}
}

func (o *User) Subentity(name string, req he.Request) he.Entity {
	return nil
}

func (o *User) patchPassword(patch *jsonpatch.Patch) putil.HTTPError {
	// this is in the running for the grossest code I've ever
	// written, but I think it's the best way to do it --lukeshu
	type patchop struct {
		Op    string
		Path  string
		Value string
	}
	str, err := json.Marshal(patch)
	if err != nil {
		panic(err)
	}
	var ops []patchop
	err = json.Unmarshal(str, &ops)
	if err != nil {
		return nil
	}
	out_ops := make([]patchop, 0, len(ops))
	checkedpass := false
	for _, op := range ops {
		if op.Path == "/password" {
			switch op.Op {
			case "test":
				if !o.CheckPassword(op.Value) {
					return putil.HTTPErrorf(409, "old password didn't match")
				}
				checkedpass = true
			case "replace":
				if !checkedpass {
					return putil.HTTPErrorf(409, "you must submit and old password (using 'test') before setting a new one")
				}
				o.SetPassword(op.Value)
			default:
				return putil.HTTPErrorf(415, "you may only 'set' or 'replace' the password")
			}
		} else {
			out_ops = append(out_ops, op)
		}
	}
	str, err = json.Marshal(out_ops)
	if err != nil {
		panic(err)
	}
	var out jsonpatch.JSONPatch
	err = json.Unmarshal(str, &out)
	if err != nil {
		panic(out)
	}
	*patch = out
	return nil
}

func (o *User) Methods() map[string]func(he.Request) he.Response {
	return map[string]func(he.Request) he.Response{
		"GET": func(req he.Request) he.Response {
			return he.StatusOK(o)
		},
		"PUT": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			sess := req.Things["session"].(*Session)
			if sess.UserId != o.Id {
				return he.StatusForbidden(heutil.NetString("Unauthorized user"))
			}
			var new_user User
			err := safeDecodeJSON(req.Entity, &new_user)
			if err != nil {
				return err.Response()
			}
			if o.Id != new_user.Id {
				return he.StatusConflict(heutil.NetString("Cannot change user id"))
			}
			*o = new_user
			o.Save(db)
			return he.StatusOK(o)
		},
		"PATCH": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			sess := req.Things["session"].(*Session)
			if sess.UserId != o.Id {
				return he.StatusForbidden(heutil.NetString("Unauthorized user"))
			}
			patch, ok := req.Entity.(jsonpatch.Patch)
			if !ok {
				return putil.HTTPErrorf(415, "PATCH request must have a patch media type").Response()
			}
			httperr := o.patchPassword(&patch)
			if httperr != nil {
				return httperr.Response()
			}
			var new_user User
			err := patch.Apply(o, &new_user)
			if err != nil {
				return putil.HTTPErrorf(409, "%v", err).Response()
			}
			if o.Id != new_user.Id {
				return he.StatusConflict(heutil.NetString("Cannot change user id"))
			}
			*o = new_user
			o.Save(db)
			return he.StatusOK(o)
		},
		"DELETE": func(req he.Request) he.Response {
			panic("TODO: API: (*User).Methods()[\"DELETE\"]")
		},
	}
}

// View //////////////////////////////////////////////////////////////

func (o *User) Encoders() map[string]func(io.Writer) error {
	return defaultEncoders(o)
}

// Directory ("Controller") //////////////////////////////////////////

type t_dirUsers struct {
	methods map[string]func(he.Request) he.Response
}

func newDirUsers() t_dirUsers {
	r := t_dirUsers{}
	r.methods = map[string]func(he.Request) he.Response{
		"POST": func(req he.Request) he.Response {
			db := req.Things["db"].(*gorm.DB)
			type postfmt struct {
				Username             string `json:"username"`
				Email                string `json:"email"`
				Password             string `json:"password"`
				PasswordVerification string `json:"password_verification,omitempty"`
			}
			var entity postfmt
			httperr := safeDecodeJSON(req.Entity, &entity)
			if httperr != nil {
				return httperr.Response()
			}

			if entity.PasswordVerification != "" {
				if entity.Password != entity.PasswordVerification {
					// Passwords don't match
					return he.StatusConflict(heutil.NetString("password and password_verification don't match"))
				}
			}

			entity.Username = strings.ToLower(entity.Username)

			user := NewUser(db, entity.Username, entity.Password, entity.Email)
			if user == nil {
				return putil.HTTPErrorf(409, "either that username or password is already taken").Response()
			} else {
				return he.StatusCreated(r, entity.Username, req)
			}
		},
	}
	return r
}

func (d t_dirUsers) Methods() map[string]func(he.Request) he.Response {
	return d.methods
}

func (d t_dirUsers) Subentity(name string, req he.Request) he.Entity {
	sess := req.Things["session"].(*Session)
	if sess == nil && req.Method == "POST" {
		type postfmt struct {
			Username             string `json:"username"`
			Email                string `json:"email"`
			Password             string `json:"password"`
			PasswordVerification string `json:"password_verification,omitempty"`
		}
		var entity postfmt
		httperr := safeDecodeJSON(req.Entity, &entity)
		if httperr != nil {
			return nil
		}
		db := req.Things["db"].(*gorm.DB)
		user := GetUserById(db, entity.Username)
		if !user.CheckPassword(entity.Password) {
			return nil
		} else {
			return user
		}
	} else if sess.UserId != name {
		return nil
	}
	db := req.Things["db"].(*gorm.DB)
	return GetUserById(db, name)
}
<|endoftext|>


<commit_before>package consensus

import (
	"container/heap"
	"container/vector"
	"goprotobuf.googlecode.com/hg/proto"
)

type packet struct {
	Addr string
	M
}

func (p packet) Less(y interface{}) bool {
	return *p.Seqn < *y.(packet).Seqn
}

type Packet struct {
	Addr string
	Data []byte
}

type Stats struct {
	Runs        int
	WaitPackets int
}

type Manager <-chan Stats

func NewManager(in <-chan Packet, out chan<- packet, runs <-chan *run) Manager {
	statCh := make(chan Stats)
	running := make(map[int64]*run)
	packets := new(vector.Vector)
	ticks := make(chan int64)

	var nextRun int64

	go func() {
		var stats Stats
		for {
			stats.Runs = len(running)
			stats.WaitPackets = packets.Len()

			select {
			case run := <-runs:
				running[run.seqn] = run
				nextRun = run.seqn + 1
				run.ticks = ticks
			case p := <-in:
				recvPacket(packets, p)
			case n := <-ticks:
				schedTick(packets, n)
			case statCh <- stats:
			}

			for packets.Len() > 0 {
				p := packets.At(0).(packet)

				seqn := *p.Seqn

				if seqn >= nextRun {
					break
				}

				heap.Pop(packets)

				running[seqn].deliver(p)
			}
		}
	}()

	return statCh
}

func recvPacket(q heap.Interface, P Packet) {
	var p packet

	err := proto.Unmarshal(P.Data, &p.M)
	if err != nil {
		return
	}

	if p.M.Seqn == nil {
		return
	}

	heap.Push(q, p)
}

func schedTick(q heap.Interface, n int64) {
	heap.Push(q, packet{M: M{Seqn: proto.Int64(n), Cmd: tick}})
}
<commit_msg>refactor<commit_after>package consensus

import (
	"container/heap"
	"container/vector"
	"goprotobuf.googlecode.com/hg/proto"
)

type packet struct {
	Addr string
	M
}

func (p packet) Less(y interface{}) bool {
	return *p.Seqn < *y.(packet).Seqn
}

type Packet struct {
	Addr string
	Data []byte
}

type Stats struct {
	Runs        int
	WaitPackets int
}

type Manager <-chan Stats

func NewManager(in <-chan Packet, out chan<- packet, runs <-chan *run) Manager {
	statCh := make(chan Stats)

	go func() {
		running := make(map[int64]*run)
		packets := new(vector.Vector)
		ticks := make(chan int64)
		var nextRun int64
		var stats Stats

		for {
			stats.Runs = len(running)
			stats.WaitPackets = packets.Len()

			select {
			case run := <-runs:
				running[run.seqn] = run
				nextRun = run.seqn + 1
				run.ticks = ticks
			case p := <-in:
				recvPacket(packets, p)
			case n := <-ticks:
				schedTick(packets, n)
			case statCh <- stats:
			}

			for packets.Len() > 0 {
				p := packets.At(0).(packet)

				seqn := *p.Seqn

				if seqn >= nextRun {
					break
				}

				heap.Pop(packets)

				running[seqn].deliver(p)
			}
		}
	}()

	return statCh
}

func recvPacket(q heap.Interface, P Packet) {
	var p packet

	err := proto.Unmarshal(P.Data, &p.M)
	if err != nil {
		return
	}

	if p.M.Seqn == nil {
		return
	}

	heap.Push(q, p)
}

func schedTick(q heap.Interface, n int64) {
	heap.Push(q, packet{M: M{Seqn: proto.Int64(n), Cmd: tick}})
}
<|endoftext|>