<commit_before>// MIT License
//
// Copyright (c) 2018 Stefan Wichmann
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
package main

import "net/http"
import "io/ioutil"
import "encoding/json"
import log "github.com/Sirupsen/logrus"
import "github.com/btittelbach/astrotime"
import "time"

// Geolocation represents a position on earth for which we can
// calculate sunrise and sunset times.
// If no location is configured Kelvin will try a geo IP lookup.
type Geolocation struct {
	IP          string  `json:"ip"`
	CountryCode string  `json:"country_code"`
	CountryName string  `json:"country_name"`
	RegionCode  string  `json:"region_code"`
	RegionName  string  `json:"region_name"`
	City        string  `json:"city"`
	ZipCode     string  `json:"zip_code"`
	TimeZone    string  `json:"time_zone"`
	Latitude    float64 `json:"latitude"`
	Longitude   float64 `json:"longitude"`
	MetroCode   float64 `json:"metro_code"`
}

const geolocationURL = "https://freegeoip.net/json/"

// InitializeLocation creates and return a geolocation for the current system.
func InitializeLocation(configuration *Configuration) (Geolocation, error) {
	var location Geolocation
	if configuration.Location.Latitude == 0 || configuration.Location.Longitude == 0 {
		log.Println("🌍 Location not configured. Detecting by IP")
		err := location.updateByIP()
		if err != nil {
			return location, err
		}
		configuration.Location.Latitude = location.Latitude
		configuration.Location.Longitude = location.Longitude
	} else {
		location.Latitude = configuration.Location.Latitude
		location.Longitude = configuration.Location.Longitude
		log.Printf("🌍 Working with location %v, %v from configuration", location.Latitude, location.Longitude)
	}
	return location, nil
}

func (location *Geolocation) updateByIP() error {
	resp, err := http.Get(geolocationURL)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	var data Geolocation
	err = json.Unmarshal(body, &data)
	if err != nil {
		return err
	}

	log.Printf("🌍 Detected location: %s, %s (%v, %v).", data.City, data.CountryName, data.Latitude, data.Longitude)
	location.Latitude = data.Latitude
	location.Longitude = data.Longitude
	return nil
}

// CalculateSunset calculates the sunset for the given day based on
// the configured position on earth.
func CalculateSunset(date time.Time, latitude float64, longitude float64) time.Time {
	// calculate start of day
	yr, mth, day := date.Date()
	startOfDay := time.Date(yr, mth, day, 0, 0, 0, 0, date.Location())

	return astrotime.NextSunset(startOfDay, latitude, longitude)
}

// CalculateSunrise calculates the sunrise for the given day based on
// the configured position on earth.
func CalculateSunrise(date time.Time, latitude float64, longitude float64) time.Time {
	// calculate start of day
	yr, mth, day := date.Date()
	startOfDay := time.Date(yr, mth, day, 0, 0, 0, 0, date.Location())

	return astrotime.NextSunrise(startOfDay, latitude, longitude)
}
<commit_msg>Update geolocation provider<commit_after>// MIT License
//
// Copyright (c) 2018 Stefan Wichmann
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
package main

import "net/http"
import "io/ioutil"
import "encoding/json"
import log "github.com/Sirupsen/logrus"
import "github.com/btittelbach/astrotime"
import "time"

// Geolocation represents a position on earth for which we can
// calculate sunrise and sunset times.
// If no location is configured Kelvin will try a geo IP lookup.
type Geolocation struct {
	City      string
	Latitude  float64
	Longitude float64
}

type GeoApiResponse struct {
	City     string                 `json:"city"`
	Location GeoApiLocationResponse `json:"location"`
}

type GeoApiLocationResponse struct {
	Latitude  float64 `json:"latitude"`
	Longitude float64 `json:"longitude"`
}

const geolocationApiURL = "https://geoip.nekudo.com/api/"

// InitializeLocation creates and return a geolocation for the current system.
func InitializeLocation(configuration *Configuration) (Geolocation, error) {
	var location Geolocation
	if configuration.Location.Latitude == 0 || configuration.Location.Longitude == 0 {
		log.Println("🌍 Location not configured. Detecting by IP")
		err := location.updateByIP()
		if err != nil {
			return location, err
		}
		configuration.Location.Latitude = location.Latitude
		configuration.Location.Longitude = location.Longitude
	} else {
		location.Latitude = configuration.Location.Latitude
		location.Longitude = configuration.Location.Longitude
		log.Printf("🌍 Working with location %v, %v from configuration", location.Latitude, location.Longitude)
	}
	return location, nil
}

func (location *Geolocation) updateByIP() error {
	response, err := http.Get(geolocationApiURL)
	if response != nil {
		defer response.Body.Close()
	}
	if err != nil {
		return err
	}

	body, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return err
	}

	var data GeoApiResponse
	err = json.Unmarshal(body, &data)
	if err != nil {
		return err
	}

	log.Printf("🌍 Detected location: %s (%v, %v).", data.City, data.Location.Latitude, data.Location.Longitude)
	location.Latitude = data.Location.Latitude
	location.Longitude = data.Location.Longitude
	return nil
}

// CalculateSunset calculates the sunset for the given day based on
// the configured position on earth.
func CalculateSunset(date time.Time, latitude float64, longitude float64) time.Time {
	// calculate start of day
	yr, mth, day := date.Date()
	startOfDay := time.Date(yr, mth, day, 0, 0, 0, 0, date.Location())

	return astrotime.NextSunset(startOfDay, latitude, longitude)
}

// CalculateSunrise calculates the sunrise for the given day based on
// the configured position on earth.
func CalculateSunrise(date time.Time, latitude float64, longitude float64) time.Time {
	// calculate start of day
	yr, mth, day := date.Date()
	startOfDay := time.Date(yr, mth, day, 0, 0, 0, 0, date.Location())

	return astrotime.NextSunrise(startOfDay, latitude, longitude)
}
<|endoftext|>


<commit_before>package wechat

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"encoding/xml"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"net/http/cookiejar"
	"net/http/httputil"
	"os"
	"strings"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/allegro/bigcache"
	"github.com/KevinGong2013/ggbot/utils"
)

var logger = log.WithFields(log.Fields{
	"module": "wechat",
})

// Debug is a flag, if turn it on, will record all wx `send` api result to json file.
var Debug = true

// Version is wechat's main version
var Version = `0.9.0`

const httpOK = `200`

var debugPath = `.ggbot/debug/`

// BaseRequest is a base for all wx api request.
type BaseRequest struct {
	XMLName xml.Name `xml:"error" json:"-"`

	Ret        int    `xml:"ret" json:"-"`
	Message    string `xml:"message" json:"-"`
	Wxsid      string `xml:"wxsid" json:"Sid"`
	Skey       string `xml:"skey"`
	DeviceID   string `xml:"-"`
	Wxuin      int64  `xml:"wxuin" json:"Uin"`
	PassTicket string `xml:"pass_ticket" json:"-"`
}

// Caller is a interface, All response need implement this.
type Caller interface {
	IsSuccess() bool
	Error() error
}

// Response is a wrapper.
type Response struct {
	BaseResponse *BaseResponse
}

// IsSuccess flag this request is success or failed.
func (response *Response) IsSuccess() bool {
	return response.BaseResponse.Ret == 0
}

// response's error msg.
func (response *Response) Error() error {
	return fmt.Errorf("error message:[%s]", response.BaseResponse.ErrMsg)
}

// BaseResponse for all api resp.
type BaseResponse struct {
	Ret    int
	ErrMsg string
}

// WeChat container a default http client and base request.
type WeChat struct {
	Client        *http.Client
	BaseURL       string
	BaseRequest   *BaseRequest
	UUIDProcessor UUIDProcessor
	MySelf        Contact
	IsLogin       bool
	contactCache  *bigcache.BigCache
	nicknameCache *bigcache.BigCache
	syncKey       map[string]interface{}
	syncHost      string
}

// NewWeChat is desined for Create a new Wechat instance.
func newWeChat(up UUIDProcessor) (*WeChat, error) {

	if up == nil {
		return nil, errors.New(`UUID Processor must be not nil`)
	}
	if _, err := os.Stat(debugPath); err != nil {
		if os.IsNotExist(err) {
			err = os.MkdirAll(debugPath, os.ModePerm)
			if err != nil {
				return nil, err
			}
		} else {
			return nil, err
		}
	}

	client, err := newClient()
	if err != nil {
		return nil, err
	}

	bc, err := bigcache.NewBigCache(bigcache.DefaultConfig(7 * 24 * time.Hour))
	if err != nil {
		return nil, err
	}
	nc, err := bigcache.NewBigCache(bigcache.DefaultConfig(7 * 24 * time.Hour))
	if err != nil {
		return nil, err
	}

	baseReq := new(BaseRequest)
	baseReq.Ret = 1

	wechat := &WeChat{
		Client:        client,
		BaseRequest:   baseReq,
		UUIDProcessor: up,
		IsLogin:       false,
		contactCache:  bc,
		nicknameCache: nc,
	}

	return wechat, nil
}

func newClient() (*http.Client, error) {

	jar, err := cookiejar.New(nil)
	if err != nil {
		return nil, err
	}

	transport := http.Transport{
		Dial: (&net.Dialer{
			Timeout: 30 * time.Second,
		}).Dial,
		TLSHandshakeTimeout: 30 * time.Second,
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
	}

	client := &http.Client{
		Transport: &transport,
		Jar:       jar,
		Timeout:   30 * time.Second,
	}

	return client, nil
}

// WeekUp is start point for wx bot.
func WeekUp(up UUIDProcessor) (*WeChat, error) {

	if up == nil {
		up = new(defaultUUIDProcessor)
	}

	wechat, err := newWeChat(up)
	if err != nil {
		return nil, err
	}

	wechat.handleServerEvent()
	wechat.keepAlive()

	// 处理群消息的
	wechat.RegisterModule(newFlatten(wechat))

	return wechat, nil
}

// ExcuteRequest is desined for perform http request
func (wechat *WeChat) ExcuteRequest(req *http.Request, call Caller) error {

	ps := strings.Split(req.URL.Path, `/`)
	lastP := strings.Split(ps[len(ps)-1], `?`)[0][5:]
	filename := debugPath + lastP

	if Debug {
		reqData, _ := httputil.DumpRequest(req, true)
		utils.CreateFile(filename+`_req.kv`, reqData, false)
	}

	resp, err := wechat.Client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	reader := resp.Body.(io.Reader)

	if Debug {

		data, e := ioutil.ReadAll(reader)
		if e != nil {
			return e
		}

		utils.CreateFile(filename+`_resp.json`, data, true)
		reader = bytes.NewReader(data)
	}

	if err = json.NewDecoder(reader).Decode(call); err != nil {
		return err
	}

	if !call.IsSuccess() {
		return call.Error()
	}

	return nil
}

// Excute a http request by default http client.
func (wechat *WeChat) Excute(path string, body io.Reader, call Caller) error {
	method := "GET"
	if body != nil {
		method = "POST"
	}
	req, err := http.NewRequest(method, path, body)
	if err != nil {
		return err
	}

	req.Header.Set("Content-Type", "application/json; charset=UTF-8")
	req.Header.Set(`User-Agent`, `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/602.3.12 (KHTML, like Gecko) Version/10.0.2 Safari/602.3.12`)

	return wechat.ExcuteRequest(req, call)
}

// PassTicketKV return a string like `pass_ticket=sdfewsvdwd=`
func (wechat *WeChat) PassTicketKV() string {
	return fmt.Sprintf(`pass_ticket=%s`, wechat.BaseRequest.PassTicket)
}

// SkeyKV return a string like `skey=ewfwoefjwofjskfwes`
func (wechat *WeChat) SkeyKV() string {
	return fmt.Sprintf(`skey=%s`, wechat.BaseRequest.Skey)
}

// just for debug
type nopCloser struct {
	io.Reader
}

func (np *nopCloser) Close() error { return nil }
<commit_msg>fix typo.<commit_after>package wechat

import (
	"bytes"
	"crypto/tls"
	"encoding/json"
	"encoding/xml"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net"
	"net/http"
	"net/http/cookiejar"
	"net/http/httputil"
	"os"
	"strings"
	"time"

	log "github.com/Sirupsen/logrus"
	"github.com/allegro/bigcache"
	"github.com/KevinGong2013/ggbot/utils"
)

var logger = log.WithFields(log.Fields{
	"module": "wechat",
})

// Debug is a flag, if turn it on, will record all wx `send` api result to json file.
var Debug = true

// Version is wechat's main version
var Version = `0.9.0`

const httpOK = `200`

var debugPath = `.ggbot/debug/`

// BaseRequest is a base for all wx api request.
type BaseRequest struct {
	XMLName xml.Name `xml:"error" json:"-"`

	Ret        int    `xml:"ret" json:"-"`
	Message    string `xml:"message" json:"-"`
	Wxsid      string `xml:"wxsid" json:"Sid"`
	Skey       string `xml:"skey"`
	DeviceID   string `xml:"-"`
	Wxuin      int64  `xml:"wxuin" json:"Uin"`
	PassTicket string `xml:"pass_ticket" json:"-"`
}

// Caller is a interface, All response need implement this.
type Caller interface {
	IsSuccess() bool
	Error() error
}

// Response is a wrapper.
type Response struct {
	BaseResponse *BaseResponse
}

// IsSuccess flag this request is success or failed.
func (response *Response) IsSuccess() bool {
	return response.BaseResponse.Ret == 0
}

// response's error msg.
func (response *Response) Error() error {
	return fmt.Errorf("error message:[%s]", response.BaseResponse.ErrMsg)
}

// BaseResponse for all api resp.
type BaseResponse struct {
	Ret    int
	ErrMsg string
}

// WeChat container a default http client and base request.
type WeChat struct {
	Client        *http.Client
	BaseURL       string
	BaseRequest   *BaseRequest
	UUIDProcessor UUIDProcessor
	MySelf        Contact
	IsLogin       bool
	contactCache  *bigcache.BigCache
	nicknameCache *bigcache.BigCache
	syncKey       map[string]interface{}
	syncHost      string
}

// NewWeChat is desined for Create a new Wechat instance.
func newWeChat(up UUIDProcessor) (*WeChat, error) {

	if up == nil {
		return nil, errors.New(`UUID Processor must be not nil`)
	}
	if _, err := os.Stat(debugPath); err != nil {
		if os.IsNotExist(err) {
			err = os.MkdirAll(debugPath, os.ModePerm)
			if err != nil {
				return nil, err
			}
		} else {
			return nil, err
		}
	}

	client, err := newClient()
	if err != nil {
		return nil, err
	}

	bc, err := bigcache.NewBigCache(bigcache.DefaultConfig(7 * 24 * time.Hour))
	if err != nil {
		return nil, err
	}
	nc, err := bigcache.NewBigCache(bigcache.DefaultConfig(7 * 24 * time.Hour))
	if err != nil {
		return nil, err
	}

	baseReq := new(BaseRequest)
	baseReq.Ret = 1

	wechat := &WeChat{
		Client:        client,
		BaseRequest:   baseReq,
		UUIDProcessor: up,
		IsLogin:       false,
		contactCache:  bc,
		nicknameCache: nc,
	}

	return wechat, nil
}

func newClient() (*http.Client, error) {

	jar, err := cookiejar.New(nil)
	if err != nil {
		return nil, err
	}

	transport := http.Transport{
		Dial: (&net.Dialer{
			Timeout: 30 * time.Second,
		}).Dial,
		TLSHandshakeTimeout: 30 * time.Second,
		TLSClientConfig: &tls.Config{
			InsecureSkipVerify: true,
		},
	}

	client := &http.Client{
		Transport: &transport,
		Jar:       jar,
		Timeout:   30 * time.Second,
	}

	return client, nil
}

// WakeUp is start point for wx bot.
func WakeUp(up UUIDProcessor) (*WeChat, error) {

	if up == nil {
		up = new(defaultUUIDProcessor)
	}

	wechat, err := newWeChat(up)
	if err != nil {
		return nil, err
	}

	wechat.handleServerEvent()
	wechat.keepAlive()

	// 处理群消息的
	wechat.RegisterModule(newFlatten(wechat))

	return wechat, nil
}

// ExcuteRequest is desined for perform http request
func (wechat *WeChat) ExcuteRequest(req *http.Request, call Caller) error {

	ps := strings.Split(req.URL.Path, `/`)
	lastP := strings.Split(ps[len(ps)-1], `?`)[0][5:]
	filename := debugPath + lastP

	if Debug {
		reqData, _ := httputil.DumpRequest(req, true)
		utils.CreateFile(filename+`_req.kv`, reqData, false)
	}

	resp, err := wechat.Client.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	reader := resp.Body.(io.Reader)

	if Debug {

		data, e := ioutil.ReadAll(reader)
		if e != nil {
			return e
		}

		utils.CreateFile(filename+`_resp.json`, data, true)
		reader = bytes.NewReader(data)
	}

	if err = json.NewDecoder(reader).Decode(call); err != nil {
		return err
	}

	if !call.IsSuccess() {
		return call.Error()
	}

	return nil
}

// Excute a http request by default http client.
func (wechat *WeChat) Excute(path string, body io.Reader, call Caller) error {
	method := "GET"
	if body != nil {
		method = "POST"
	}
	req, err := http.NewRequest(method, path, body)
	if err != nil {
		return err
	}

	req.Header.Set("Content-Type", "application/json; charset=UTF-8")
	req.Header.Set(`User-Agent`, `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_2) AppleWebKit/602.3.12 (KHTML, like Gecko) Version/10.0.2 Safari/602.3.12`)

	return wechat.ExcuteRequest(req, call)
}

// PassTicketKV return a string like `pass_ticket=sdfewsvdwd=`
func (wechat *WeChat) PassTicketKV() string {
	return fmt.Sprintf(`pass_ticket=%s`, wechat.BaseRequest.PassTicket)
}

// SkeyKV return a string like `skey=ewfwoefjwofjskfwes`
func (wechat *WeChat) SkeyKV() string {
	return fmt.Sprintf(`skey=%s`, wechat.BaseRequest.Skey)
}

// just for debug
type nopCloser struct {
	io.Reader
}

func (np *nopCloser) Close() error { return nil }
<|endoftext|>


<commit_before>/*
 * lxc_test.go: Go bindings for lxc
 *
 * Copyright © 2013, S.Çağlar Onur
 *
 * Authors:
 * S.Çağlar Onur <caglar@10ur.org>
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2, as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

package lxc

import (
	"math/rand"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"testing"
	"time"
)

const (
	CONTAINER_NAME               = "rubik"
	CLONE_CONTAINER_NAME         = "O"
	CLONE_OVERLAY_CONTAINER_NAME = "O_o"
	CONFIG_FILE_PATH             = "/var/lib/lxc"
	CONFIG_FILE_NAME             = "/var/lib/lxc/rubik/config"
)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
}

func TestVersion(t *testing.T) {

	if Version() == "" {
		t.Errorf("Version failed...")
	}
}

func TestDefaultConfigPath(t *testing.T) {
	if DefaultConfigPath() != CONFIG_FILE_PATH {
		t.Errorf("DefaultConfigPath failed...")
	}
}

func TestContainerNames(t *testing.T) {
	t.Logf("Containers:%+v\n", ContainerNames())
}

func TestContainers(t *testing.T) {
	for _, v := range Containers() {
		t.Logf("%s: %s", v.Name(), v.State())
	}
}

func TestSetConfigPath(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	current_path := z.ConfigPath()
	z.SetConfigPath("/tmp")
	new_path := z.ConfigPath()

	if current_path == new_path {
		t.Errorf("SetConfigPath failed...")
	}
	PutContainer(z)
}

func TestConcurrentDefined_Negative(t *testing.T) {
	var wg sync.WaitGroup

	for i := 0; i <= 100; i++ {
		wg.Add(1)
		go func() {
			z := NewContainer(strconv.Itoa(rand.Intn(10)))

			// sleep for a while to simulate some dummy work
			time.Sleep(time.Millisecond * time.Duration(rand.Intn(250)))

			if z.Defined() {
				t.Errorf("Defined_Negative failed...")
			}
			PutContainer(z)
			wg.Done()
		}()
	}
	wg.Wait()
}

func TestDefined_Negative(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if z.Defined() {
		t.Errorf("Defined_Negative failed...")
	}
	PutContainer(z)
}

func TestCreate(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Creating the container...\n")
	if !z.Create("ubuntu", []string{"amd64", "quantal"}) {
		t.Errorf("Creating the container failed...")
	}
	PutContainer(z)
}

func TestClone(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Clone %v\n", z.Clone(CLONE_CONTAINER_NAME, DIRECTORY))
	t.Logf("Clone %v\n", z.Clone(CLONE_OVERLAY_CONTAINER_NAME, OVERLAYFS))
	PutContainer(z)
}

func TestConcurrentCreate(t *testing.T) {
	var wg sync.WaitGroup

	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(i int) {
			z := NewContainer(strconv.Itoa(i))

			// sleep for a while to simulate some dummy work
			time.Sleep(time.Millisecond * time.Duration(rand.Intn(250)))

			t.Logf("Creating the container...\n")
			if !z.Create("ubuntu", []string{"amd64", "quantal"}) {
				t.Errorf("Creating the container (%d) failed...", i)
			}
			PutContainer(z)
			wg.Done()
		}(i)
	}
	wg.Wait()
}

func TestConcurrentStart(t *testing.T) {
	var wg sync.WaitGroup

	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(i int) {
			z := NewContainer(strconv.Itoa(i))

			t.Logf("Starting the container...\n")

			z.SetDaemonize()
			z.Start(false, nil)
			z.Wait(RUNNING, 30)
			if !z.Running() {
				t.Errorf("Starting the container failed...")
			}

			PutContainer(z)
			wg.Done()
		}(i)
	}
	wg.Wait()
}

func TestConfigFileName(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)
	if z.ConfigFileName() != CONFIG_FILE_NAME {
		t.Errorf("ConfigFileName failed...")
	}
	PutContainer(z)
}

func TestDefined_Positive(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if !z.Defined() {
		t.Errorf("Defined_Positive failed...")
	}
	PutContainer(z)
}

func TestConcurrentDefined_Positive(t *testing.T) {
	var wg sync.WaitGroup

	for i := 0; i <= 100; i++ {
		wg.Add(1)
		go func() {
			z := NewContainer(strconv.Itoa(rand.Intn(10)))

			// sleep for a while to simulate some dummy work
			time.Sleep(time.Millisecond * time.Duration(rand.Intn(250)))

			if !z.Defined() {
				t.Errorf("Defined_Positive failed...")
			}
			PutContainer(z)
			wg.Done()
		}()
	}
	wg.Wait()
}

func TestInitPID_Negative(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if z.InitPID() != -1 {
		t.Errorf("InitPID failed...")
	}
	PutContainer(z)
}

func TestStart(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Starting the container...\n")
	z.SetDaemonize()
	z.Start(false, nil)

	z.Wait(RUNNING, 30)
	if !z.Running() {
		t.Errorf("Starting the container failed...")
	}
	PutContainer(z)
}

func TestSetDaemonize(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	z.SetDaemonize()
	if !z.Daemonize() {
		t.Errorf("Daemonize failed...")
	}
	PutContainer(z)
}

func TestInitPID_Positive(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if z.InitPID() == -1 {
		t.Errorf("InitPID failed...")
	}
	PutContainer(z)
}

func TestName(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if z.Name() != CONTAINER_NAME {
		t.Errorf("Name failed...")
	}
	PutContainer(z)
}

func TestFreeze(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Freezing the container...\n")
	z.Freeze()

	z.Wait(FROZEN, 30)
	if z.State() != FROZEN {
		t.Errorf("Freezing the container failed...")
	}
	PutContainer(z)
}

func TestUnfreeze(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Unfreezing the container...\n")
	z.Unfreeze()

	z.Wait(RUNNING, 30)
	if z.State() != RUNNING {
		t.Errorf("Unfreezing the container failed...")
	}
	PutContainer(z)
}

func TestLoadConfigFile(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if !z.LoadConfigFile(CONFIG_FILE_NAME) {
		t.Errorf("LoadConfigFile failed...")
	}
	PutContainer(z)
}

func TestSaveConfigFile(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if !z.SaveConfigFile(CONFIG_FILE_NAME) {
		t.Errorf("LoadConfigFile failed...")
	}
	PutContainer(z)
}

func TestConfigItem(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if z.ConfigItem("lxc.utsname")[0] != CONTAINER_NAME {
		t.Errorf("ConfigItem failed...")
	}
	PutContainer(z)
}

func TestSetConfigItem(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	z.SetConfigItem("lxc.utsname", CONTAINER_NAME)
	if z.ConfigItem("lxc.utsname")[0] != CONTAINER_NAME {
		t.Errorf("ConfigItem failed...")
	}
	PutContainer(z)
}

func TestSetCgroupItem(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	max_mem := z.CgroupItem("memory.max_usage_in_bytes")[0]
	current_mem := z.CgroupItem("memory.limit_in_bytes")[0]
	z.SetCgroupItem("memory.limit_in_bytes", max_mem)
	new_mem := z.CgroupItem("memory.limit_in_bytes")[0]

	if new_mem == current_mem {
		t.Errorf("SetCgroupItem failed...")
	}
	PutContainer(z)
}

func TestClearConfigItem(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	z.ClearConfigItem("lxc.cap.drop")
	if z.ConfigItem("lxc.cap.drop")[0] != "" {
		t.Errorf("ClearConfigItem failed...")
	}
	PutContainer(z)
}

func TestKeys(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	keys := strings.Join(z.Keys("lxc.network.0"), " ")
	if !strings.Contains(keys, "mtu") {
		t.Errorf("Keys failed...")
	}
	PutContainer(z)
}

func TestNumberOfNetworkInterfaces(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if z.NumberOfNetworkInterfaces() != 1 {
		t.Errorf("NumberOfNetworkInterfaces failed...")
	}
	PutContainer(z)
}

func TestMemoryUsageInBytes(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	mem_used, _ := z.MemoryUsageInBytes()
	swap_used, _ := z.SwapUsageInBytes()
	mem_limit, _ := z.MemoryLimitInBytes()
	swap_limit, _ := z.SwapLimitInBytes()

	t.Logf("Mem usage: %0.0f\n", mem_used)
	t.Logf("Mem usage: %s\n", mem_used)
	t.Logf("Swap usage: %0.0f\n", swap_used)
	t.Logf("Swap usage: %s\n", swap_used)
	t.Logf("Mem limit: %0.0f\n", mem_limit)
	t.Logf("Mem limit: %s\n", mem_limit)
	t.Logf("Swap limit: %0.0f\n", swap_limit)
	t.Logf("Swap limit: %s\n", swap_limit)

	PutContainer(z)
}

func TestConcurrentShutdown(t *testing.T) {
	var wg sync.WaitGroup

	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(i int) {
			z := NewContainer(strconv.Itoa(i))
			t.Logf("Shutting down the container...\n")
			z.Shutdown(30)

			if z.Running() {
				t.Errorf("Shutting down the container failed...")
			}

			PutContainer(z)
			wg.Done()
		}(i)
	}
	wg.Wait()
}

func TestShutdown(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Shutting down the container...\n")
	z.Shutdown(30)

	if z.Running() {
		t.Errorf("Shutting down the container failed...")
	}
	PutContainer(z)
}

func TestStop(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Stopping the container...\n")
	z.Stop()

	if z.Running() {
		t.Errorf("Stopping the container failed...")
	}
	PutContainer(z)
}

func TestDestroy(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Destroying the container...\n")
	if !z.Destroy() {
		t.Errorf("Destroying the container failed...")
	}
	PutContainer(z)

	z = NewContainer(CLONE_CONTAINER_NAME)
	if !z.Destroy() {
		t.Errorf("Destroying the container failed...")
	}
	PutContainer(z)

	z = NewContainer(CLONE_OVERLAY_CONTAINER_NAME)
	if !z.Destroy() {
		t.Errorf("Destroying the container failed...")
	}
	PutContainer(z)
}

func TestConcurrentDestroy(t *testing.T) {
	var wg sync.WaitGroup

	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(i int) {
			z := NewContainer(strconv.Itoa(i))

			// sleep for a while to simulate some dummy work
			time.Sleep(time.Millisecond * time.Duration(rand.Intn(250)))

			t.Logf("Destroying the container...\n")
			if !z.Destroy() {
				t.Errorf("Destroying the container failed...")
			}
			PutContainer(z)
			wg.Done()
		}(i)
	}
	wg.Wait()
}
<commit_msg>gofmt<commit_after>/*
 * lxc_test.go: Go bindings for lxc
 *
 * Copyright © 2013, S.Çağlar Onur
 *
 * Authors:
 * S.Çağlar Onur <caglar@10ur.org>
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2, as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

package lxc

import (
	"math/rand"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"testing"
	"time"
)

const (
	CONTAINER_NAME               = "rubik"
	CLONE_CONTAINER_NAME         = "O"
	CLONE_OVERLAY_CONTAINER_NAME = "O_o"
	CONFIG_FILE_PATH             = "/var/lib/lxc"
	CONFIG_FILE_NAME             = "/var/lib/lxc/rubik/config"
)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
}

func TestVersion(t *testing.T) {

	if Version() == "" {
		t.Errorf("Version failed...")
	}
}

func TestDefaultConfigPath(t *testing.T) {
	if DefaultConfigPath() != CONFIG_FILE_PATH {
		t.Errorf("DefaultConfigPath failed...")
	}
}

func TestContainerNames(t *testing.T) {
	t.Logf("Containers:%+v\n", ContainerNames())
}

func TestContainers(t *testing.T) {
	for _, v := range Containers() {
		t.Logf("%s: %s", v.Name(), v.State())
	}
}

func TestSetConfigPath(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	current_path := z.ConfigPath()
	z.SetConfigPath("/tmp")
	new_path := z.ConfigPath()

	if current_path == new_path {
		t.Errorf("SetConfigPath failed...")
	}
	PutContainer(z)
}

func TestConcurrentDefined_Negative(t *testing.T) {
	var wg sync.WaitGroup

	for i := 0; i <= 100; i++ {
		wg.Add(1)
		go func() {
			z := NewContainer(strconv.Itoa(rand.Intn(10)))

			// sleep for a while to simulate some dummy work
			time.Sleep(time.Millisecond * time.Duration(rand.Intn(250)))

			if z.Defined() {
				t.Errorf("Defined_Negative failed...")
			}
			PutContainer(z)
			wg.Done()
		}()
	}
	wg.Wait()
}

func TestDefined_Negative(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if z.Defined() {
		t.Errorf("Defined_Negative failed...")
	}
	PutContainer(z)
}

func TestCreate(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Creating the container...\n")
	if !z.Create("ubuntu", []string{"amd64", "quantal"}) {
		t.Errorf("Creating the container failed...")
	}
	PutContainer(z)
}

func TestClone(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Clone %v\n", z.Clone(CLONE_CONTAINER_NAME, DIRECTORY))
	t.Logf("Clone %v\n", z.Clone(CLONE_OVERLAY_CONTAINER_NAME, OVERLAYFS))
	PutContainer(z)
}

func TestConcurrentCreate(t *testing.T) {
	var wg sync.WaitGroup

	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(i int) {
			z := NewContainer(strconv.Itoa(i))

			// sleep for a while to simulate some dummy work
			time.Sleep(time.Millisecond * time.Duration(rand.Intn(250)))

			t.Logf("Creating the container...\n")
			if !z.Create("ubuntu", []string{"amd64", "quantal"}) {
				t.Errorf("Creating the container (%d) failed...", i)
			}
			PutContainer(z)
			wg.Done()
		}(i)
	}
	wg.Wait()
}

func TestConcurrentStart(t *testing.T) {
	var wg sync.WaitGroup

	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(i int) {
			z := NewContainer(strconv.Itoa(i))

			t.Logf("Starting the container...\n")

			z.SetDaemonize()
			z.Start(false, nil)
			z.Wait(RUNNING, 30)
			if !z.Running() {
				t.Errorf("Starting the container failed...")
			}

			PutContainer(z)
			wg.Done()
		}(i)
	}
	wg.Wait()
}

func TestConfigFileName(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)
	if z.ConfigFileName() != CONFIG_FILE_NAME {
		t.Errorf("ConfigFileName failed...")
	}
	PutContainer(z)
}

func TestDefined_Positive(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if !z.Defined() {
		t.Errorf("Defined_Positive failed...")
	}
	PutContainer(z)
}

func TestConcurrentDefined_Positive(t *testing.T) {
	var wg sync.WaitGroup

	for i := 0; i <= 100; i++ {
		wg.Add(1)
		go func() {
			z := NewContainer(strconv.Itoa(rand.Intn(10)))

			// sleep for a while to simulate some dummy work
			time.Sleep(time.Millisecond * time.Duration(rand.Intn(250)))

			if !z.Defined() {
				t.Errorf("Defined_Positive failed...")
			}
			PutContainer(z)
			wg.Done()
		}()
	}
	wg.Wait()
}

func TestInitPID_Negative(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if z.InitPID() != -1 {
		t.Errorf("InitPID failed...")
	}
	PutContainer(z)
}

func TestStart(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Starting the container...\n")
	z.SetDaemonize()
	z.Start(false, nil)

	z.Wait(RUNNING, 30)
	if !z.Running() {
		t.Errorf("Starting the container failed...")
	}
	PutContainer(z)
}

func TestSetDaemonize(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	z.SetDaemonize()
	if !z.Daemonize() {
		t.Errorf("Daemonize failed...")
	}
	PutContainer(z)
}

func TestInitPID_Positive(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if z.InitPID() == -1 {
		t.Errorf("InitPID failed...")
	}
	PutContainer(z)
}

func TestName(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if z.Name() != CONTAINER_NAME {
		t.Errorf("Name failed...")
	}
	PutContainer(z)
}

func TestFreeze(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Freezing the container...\n")
	z.Freeze()

	z.Wait(FROZEN, 30)
	if z.State() != FROZEN {
		t.Errorf("Freezing the container failed...")
	}
	PutContainer(z)
}

func TestUnfreeze(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Unfreezing the container...\n")
	z.Unfreeze()

	z.Wait(RUNNING, 30)
	if z.State() != RUNNING {
		t.Errorf("Unfreezing the container failed...")
	}
	PutContainer(z)
}

func TestLoadConfigFile(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if !z.LoadConfigFile(CONFIG_FILE_NAME) {
		t.Errorf("LoadConfigFile failed...")
	}
	PutContainer(z)
}

func TestSaveConfigFile(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if !z.SaveConfigFile(CONFIG_FILE_NAME) {
		t.Errorf("LoadConfigFile failed...")
	}
	PutContainer(z)
}

func TestConfigItem(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if z.ConfigItem("lxc.utsname")[0] != CONTAINER_NAME {
		t.Errorf("ConfigItem failed...")
	}
	PutContainer(z)
}

func TestSetConfigItem(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	z.SetConfigItem("lxc.utsname", CONTAINER_NAME)
	if z.ConfigItem("lxc.utsname")[0] != CONTAINER_NAME {
		t.Errorf("ConfigItem failed...")
	}
	PutContainer(z)
}

func TestSetCgroupItem(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	max_mem := z.CgroupItem("memory.max_usage_in_bytes")[0]
	current_mem := z.CgroupItem("memory.limit_in_bytes")[0]
	z.SetCgroupItem("memory.limit_in_bytes", max_mem)
	new_mem := z.CgroupItem("memory.limit_in_bytes")[0]

	if new_mem == current_mem {
		t.Errorf("SetCgroupItem failed...")
	}
	PutContainer(z)
}

func TestClearConfigItem(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	z.ClearConfigItem("lxc.cap.drop")
	if z.ConfigItem("lxc.cap.drop")[0] != "" {
		t.Errorf("ClearConfigItem failed...")
	}
	PutContainer(z)
}

func TestKeys(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	keys := strings.Join(z.Keys("lxc.network.0"), " ")
	if !strings.Contains(keys, "mtu") {
		t.Errorf("Keys failed...")
	}
	PutContainer(z)
}

func TestNumberOfNetworkInterfaces(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	if z.NumberOfNetworkInterfaces() != 1 {
		t.Errorf("NumberOfNetworkInterfaces failed...")
	}
	PutContainer(z)
}

func TestMemoryUsageInBytes(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	mem_used, _ := z.MemoryUsageInBytes()
	swap_used, _ := z.SwapUsageInBytes()
	mem_limit, _ := z.MemoryLimitInBytes()
	swap_limit, _ := z.SwapLimitInBytes()

	t.Logf("Mem usage: %0.0f\n", mem_used)
	t.Logf("Mem usage: %s\n", mem_used)
	t.Logf("Swap usage: %0.0f\n", swap_used)
	t.Logf("Swap usage: %s\n", swap_used)
	t.Logf("Mem limit: %0.0f\n", mem_limit)
	t.Logf("Mem limit: %s\n", mem_limit)
	t.Logf("Swap limit: %0.0f\n", swap_limit)
	t.Logf("Swap limit: %s\n", swap_limit)

	PutContainer(z)
}

func TestConcurrentShutdown(t *testing.T) {
	var wg sync.WaitGroup

	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(i int) {
			z := NewContainer(strconv.Itoa(i))
			t.Logf("Shutting down the container...\n")
			z.Shutdown(30)

			if z.Running() {
				t.Errorf("Shutting down the container failed...")
			}

			PutContainer(z)
			wg.Done()
		}(i)
	}
	wg.Wait()
}

func TestShutdown(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Shutting down the container...\n")
	z.Shutdown(30)

	if z.Running() {
		t.Errorf("Shutting down the container failed...")
	}
	PutContainer(z)
}

func TestStop(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Stopping the container...\n")
	z.Stop()

	if z.Running() {
		t.Errorf("Stopping the container failed...")
	}
	PutContainer(z)
}

func TestDestroy(t *testing.T) {
	z := NewContainer(CONTAINER_NAME)

	t.Logf("Destroying the container...\n")
	if !z.Destroy() {
		t.Errorf("Destroying the container failed...")
	}
	PutContainer(z)

	z = NewContainer(CLONE_CONTAINER_NAME)
	if !z.Destroy() {
		t.Errorf("Destroying the container failed...")
	}
	PutContainer(z)

	z = NewContainer(CLONE_OVERLAY_CONTAINER_NAME)
	if !z.Destroy() {
		t.Errorf("Destroying the container failed...")
	}
	PutContainer(z)
}

func TestConcurrentDestroy(t *testing.T) {
	var wg sync.WaitGroup

	for i := 0; i < 10; i++ {
		wg.Add(1)
		go func(i int) {
			z := NewContainer(strconv.Itoa(i))

			// sleep for a while to simulate some dummy work
			time.Sleep(time.Millisecond * time.Duration(rand.Intn(250)))

			t.Logf("Destroying the container...\n")
			if !z.Destroy() {
				t.Errorf("Destroying the container failed...")
			}
			PutContainer(z)
			wg.Done()
		}(i)
	}
	wg.Wait()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"math/rand"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/lxc/lxd/internal/gnuflag"
	"github.com/lxc/lxd/shared"
)

func main() {
	if err := run(); err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}
}

var verbose = gnuflag.Bool("v", false, "Enables verbose mode.")
var debug = gnuflag.Bool("debug", false, "Enables debug mode.")
var listenAddr = gnuflag.String("tcp", "", "TCP address <addr:port> to listen on in addition to the unix socket (e.g., 127.0.0.1:8443)")
var group = gnuflag.String("group", "", "Group which owns the shared socket")
var help = gnuflag.Bool("help", false, "Print this help message.")
var version = gnuflag.Bool("version", false, "Print LXD's version number and exit.")

func init() {
	myGroup, err := shared.GroupName(os.Getgid())
	if err != nil {
		shared.Debugf("Problem finding default group %s", err)
	}
	*group = myGroup

	rand.Seed(time.Now().UTC().UnixNano())
}

func run() error {
	gnuflag.Usage = func() {
		fmt.Printf("Usage: lxd [options]\n\nOptions:\n")
		gnuflag.PrintDefaults()
	}

	gnuflag.Parse(true)
	if *help {
		// The user asked for help via --help, so we shouldn't print to
		// stderr.
		gnuflag.SetOut(os.Stdout)
		gnuflag.Usage()
		return nil
	}

	if *version {
		fmt.Println(shared.Version)
		return nil
	}

	if *verbose || *debug {
		shared.SetLogger(log.New(os.Stderr, "", log.LstdFlags))
		shared.SetDebug(*debug)
	}

	d, err := StartDaemon(*listenAddr)

	if err != nil {
		if d.db != nil {
			d.db.Close()
		}
		return err
	}

	defer d.db.Close()

	ch := make(chan os.Signal)
	signal.Notify(ch, syscall.SIGINT)
	signal.Notify(ch, syscall.SIGTERM)
	<-ch
	return d.Stop()
}
<commit_msg>fixed startup crash if NewDaemon returns error<commit_after>package main

import (
	"fmt"
	"log"
	"math/rand"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/lxc/lxd/internal/gnuflag"
	"github.com/lxc/lxd/shared"
)

func main() {
	if err := run(); err != nil {
		fmt.Fprintf(os.Stderr, "error: %v\n", err)
		os.Exit(1)
	}
}

var verbose = gnuflag.Bool("v", false, "Enables verbose mode.")
var debug = gnuflag.Bool("debug", false, "Enables debug mode.")
var listenAddr = gnuflag.String("tcp", "", "TCP address <addr:port> to listen on in addition to the unix socket (e.g., 127.0.0.1:8443)")
var group = gnuflag.String("group", "", "Group which owns the shared socket")
var help = gnuflag.Bool("help", false, "Print this help message.")
var version = gnuflag.Bool("version", false, "Print LXD's version number and exit.")

func init() {
	myGroup, err := shared.GroupName(os.Getgid())
	if err != nil {
		shared.Debugf("Problem finding default group %s", err)
	}
	*group = myGroup

	rand.Seed(time.Now().UTC().UnixNano())
}

func run() error {
	gnuflag.Usage = func() {
		fmt.Printf("Usage: lxd [options]\n\nOptions:\n")
		gnuflag.PrintDefaults()
	}

	gnuflag.Parse(true)
	if *help {
		// The user asked for help via --help, so we shouldn't print to
		// stderr.
		gnuflag.SetOut(os.Stdout)
		gnuflag.Usage()
		return nil
	}

	if *version {
		fmt.Println(shared.Version)
		return nil
	}

	if *verbose || *debug {
		shared.SetLogger(log.New(os.Stderr, "", log.LstdFlags))
		shared.SetDebug(*debug)
	}

	d, err := StartDaemon(*listenAddr)

	if err != nil {
		if d != nil && d.db != nil {
			d.db.Close()
		}
		return err
	}

	defer d.db.Close()

	ch := make(chan os.Signal)
	signal.Notify(ch, syscall.SIGINT)
	signal.Notify(ch, syscall.SIGTERM)
	<-ch
	return d.Stop()
}
<|endoftext|>


<commit_before>package node

import (
	"context"
	"log"
	"net"
	"os/exec"
	"runtime"
	"strings"
	"syscall"

	"code.cloudfoundry.org/bytefmt"
	"github.com/cenkalti/backoff"
	"github.com/n0stack/n0stack/n0proto.go/pool/v0"
	"github.com/pkg/errors"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
)

// IPMIを持っていない場合が考えられるので、とりあえずエラーハンドリングはしていない
func GetIpmiAddress() string {
	out, err := exec.Command("ipmitool", "lan", "print").Output()
	if err != nil {
		return ""
	}

	for _, l := range strings.Split(string(out), "\n") {
		if strings.Contains(l, "IP Address              :") { // これで正しいのかよくわからず、要テスト
			s := strings.Split(l, " ")
			return s[len(s)-1]
		}
	}

	return ""
}

// Serialが取得できなくても動作に問題はないため、エラーハンドリングはしていない
func GetSerial() string {
	out, err := exec.Command("dmidecode", "-t", "system").Output()
	if err != nil {
		return ""
	}

	for _, l := range strings.Split(string(out), "\n") {
		if strings.Contains(l, "Serial Number:") {
			s := strings.Split(l, " ")
			return s[len(s)-1]
		}
	}

	return ""
}

func GetTotalMemory() (uint64, error) {
	si := &syscall.Sysinfo_t{}
	err := syscall.Sysinfo(si)
	if err != nil {
		return 0, errors.Wrap(err, "Failed to call syscall 'sysinfo'")
	}

	return si.Totalram / uint64(si.Unit), nil
}

func GetTotalCPUMilliCores() uint32 {
	return uint32(runtime.NumCPU())
}

// TODO: エラーハンドリング適当
func RegisterNodeToAPI(name, advertiseAddress, api string) error {
	conn, err := grpc.Dial(api, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()

	cli := ppool.NewNodeServiceClient(conn)

	mem, err := GetTotalMemory()
	if err != nil {
		return err
	}

	aip, err := net.ResolveIPAddr("ip", advertiseAddress)
	if err != nil {
		return err
	}

	ar := &ppool.ApplyNodeRequest{
		Name:          name,
		Address:       aip.String(),
		IpmiAddress:   GetIpmiAddress(),
		Serial:        GetSerial(),
		CpuMilliCores: GetTotalCPUMilliCores() * 1000,
		MemoryBytes:   mem,
		StorageBytes:  100. * bytefmt.GIGABYTE,
	}

	n, err := cli.GetNode(context.Background(), &ppool.GetNodeRequest{Name: name})
	if err != nil {
		if grpc.Code(err) != codes.NotFound {
			return err
		}
	} else {
		log.Printf("[INFO] Get res: '%+v'", n)
		ar.Version = n.Version
		ar.Annotations = n.Annotations
	}

	log.Printf("[INFO] Apply req: '%+v'", ar)

	b := backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 5)
	err = backoff.Retry(func() error {
		n, err = cli.ApplyNode(context.Background(), ar)
		if err != nil {
			return err
		}

		log.Printf("[INFO] Applied Node to APi on registerNodeToAPI, Node:%v", n)

		return nil
	}, b)
	if err != nil {
		return err
	}

	return nil
}

// func joinNodeToMemberlist(name, advertiseAddress, api string) (*memberlist.Memberlist, error) {
// 	c := memberlist.DefaultLANConfig()
// 	c.Name = name
// 	c.AdvertiseAddr = advertiseAddress
// 	// c.AdvertisePort = int(a.Connection.Port)

// 	list, err := memberlist.Create(c)
// 	if err != nil {
// 		return nil, err
// 	}

// 	_, err = list.Join([]string{api})
// 	if err != nil {
// 		return nil, err
// 	}

// 	log.Printf("[INFO] Join Node to memberlist on joinNodeToMemberlist, LocalNode:%v", list.LocalNode())

// 	return list, nil
// }

// func JoinNode(name, advertiseAddress, apiAddress string, apiPort int) error {
// 	addr, err := net.ResolveIPAddr("ip", advertiseAddress)
// 	if err != nil {
// 		return err
// 	}

// 	if err := registerNodeToAPI(name, addr.String(), fmt.Sprintf("%s:%d", apiAddress, apiPort)); err != nil {
// 		return err
// 	}

// 	list, err := joinNodeToMemberlist(name, addr.String(), apiAddress)
// 	if err != nil {
// 		return err
// 	}

// 	c := make(chan os.Signal, 1)
// 	signal.Notify(c, os.Interrupt)
// 	go func() {
// 		for _ = range c {
// 			if err := LeaveNode(list); err != nil {
// 				log.Fatalf("Failed to LeaveNode, err:%s", err.Error())
// 			}
// 			os.Exit(0)
// 		}
// 	}()

// 	return nil
// }

// func LeaveNode(list *memberlist.Memberlist) error {
// 	list.Leave(3 * time.Second)

// 	return nil
// }
<commit_msg>fix test small<commit_after>package node

import (
	"context"
	"log"
	"net"
	"os/exec"
	"runtime"
	"strings"
	"syscall"

	"code.cloudfoundry.org/bytefmt"
	"github.com/cenkalti/backoff"
	"github.com/n0stack/n0stack/n0proto.go/pool/v0"
	"github.com/pkg/errors"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
)

// IPMIを持っていない場合が考えられるので、とりあえずエラーハンドリングはしていない
func GetIpmiAddress() string {
	out, err := exec.Command("ipmitool", "lan", "print").Output()
	if err != nil {
		return ""
	}

	for _, l := range strings.Split(string(out), "\n") {
		if strings.Contains(l, "IP Address              :") { // これで正しいのかよくわからず、要テスト
			s := strings.Split(l, " ")
			return s[len(s)-1]
		}
	}

	return ""
}

// Serialが取得できなくても動作に問題はないため、エラーハンドリングはしていない
func GetSerial() string {
	out, err := exec.Command("dmidecode", "-t", "system").Output()
	if err != nil {
		return ""
	}

	for _, l := range strings.Split(string(out), "\n") {
		if strings.Contains(l, "Serial Number:") {
			s := strings.Split(l, " ")
			return s[len(s)-1]
		}
	}

	return ""
}

func GetTotalMemory() (uint64, error) {
	si := &syscall.Sysinfo_t{}
	err := syscall.Sysinfo(si)
	if err != nil {
		return 0, errors.Wrap(err, "Failed to call syscall 'sysinfo'")
	}

	return si.Totalram / uint64(si.Unit), nil
}

func GetTotalCPUMilliCores() uint32 {
	return uint32(runtime.NumCPU())
}

// TODO: エラーハンドリング適当
// TODO: versionをとる
func RegisterNodeToAPI(name, advertiseAddress, api string) error {
	conn, err := grpc.Dial(api, grpc.WithInsecure())
	if err != nil {
		return err
	}
	defer conn.Close()

	cli := ppool.NewNodeServiceClient(conn)

	mem, err := GetTotalMemory()
	if err != nil {
		return err
	}

	aip, err := net.ResolveIPAddr("ip", advertiseAddress)
	if err != nil {
		return err
	}

	ar := &ppool.ApplyNodeRequest{
		Name:          name,
		Address:       aip.String(),
		IpmiAddress:   GetIpmiAddress(),
		Serial:        GetSerial(),
		CpuMilliCores: GetTotalCPUMilliCores() * 1000,
		MemoryBytes:   mem,
		StorageBytes:  100. * bytefmt.GIGABYTE,
	}

	n, err := cli.GetNode(context.Background(), &ppool.GetNodeRequest{Name: name})
	if err != nil {
		if grpc.Code(err) != codes.NotFound {
			return err
		}
	} else {
		log.Printf("[INFO] Get res: '%+v'", n)
		ar.Version = n.Version
		ar.Annotations = n.Annotations
	}

	log.Printf("[INFO] Apply req: '%+v'", ar)

	b := backoff.WithMaxRetries(backoff.NewExponentialBackOff(), 5)
	err = backoff.Retry(func() error {
		n, err = cli.ApplyNode(context.Background(), ar)
		if err != nil {
			return err
		}

		log.Printf("[INFO] Applied Node to APi on registerNodeToAPI, Node:%v", n)

		return nil
	}, b)
	if err != nil {
		return err
	}

	return nil
}

// func joinNodeToMemberlist(name, advertiseAddress, api string) (*memberlist.Memberlist, error) {
// 	c := memberlist.DefaultLANConfig()
// 	c.Name = name
// 	c.AdvertiseAddr = advertiseAddress
// 	// c.AdvertisePort = int(a.Connection.Port)

// 	list, err := memberlist.Create(c)
// 	if err != nil {
// 		return nil, err
// 	}

// 	_, err = list.Join([]string{api})
// 	if err != nil {
// 		return nil, err
// 	}

// 	log.Printf("[INFO] Join Node to memberlist on joinNodeToMemberlist, LocalNode:%v", list.LocalNode())

// 	return list, nil
// }

// func JoinNode(name, advertiseAddress, apiAddress string, apiPort int) error {
// 	addr, err := net.ResolveIPAddr("ip", advertiseAddress)
// 	if err != nil {
// 		return err
// 	}

// 	if err := registerNodeToAPI(name, addr.String(), fmt.Sprintf("%s:%d", apiAddress, apiPort)); err != nil {
// 		return err
// 	}

// 	list, err := joinNodeToMemberlist(name, addr.String(), apiAddress)
// 	if err != nil {
// 		return err
// 	}

// 	c := make(chan os.Signal, 1)
// 	signal.Notify(c, os.Interrupt)
// 	go func() {
// 		for _ = range c {
// 			if err := LeaveNode(list); err != nil {
// 				log.Fatalf("Failed to LeaveNode, err:%s", err.Error())
// 			}
// 			os.Exit(0)
// 		}
// 	}()

// 	return nil
// }

// func LeaveNode(list *memberlist.Memberlist) error {
// 	list.Leave(3 * time.Second)

// 	return nil
// }
<|endoftext|>


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

package tpm2

import (
	"crypto/elliptic"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"fmt"
	"hash"

	"github.com/google/go-tpm/tpmutil"
)

func init() {
	tpmutil.UseTPM20LengthPrefixSize()
}

// Algorithm represents a TPM_ALG_ID value.
type Algorithm uint16

// IsNull returns true if a is AlgNull or zero (unset).
func (a Algorithm) IsNull() bool {
	return a == AlgNull || a == AlgUnknown
}

// UsesCount returns true if a signature algorithm uses count value.
func (a Algorithm) UsesCount() bool {
	return a == AlgECDAA
}

// HashConstructor returns a function that can be used to make a
// hash.Hash using the specified algorithm. An error is returned
// if the algorithm is not a hash algorithm.
func (a Algorithm) HashConstructor() (func() hash.Hash, error) {
	c, ok := hashConstructors[a]
	if !ok {
		return nil, fmt.Errorf("algorithm not supported: 0x%x", a)
	}
	return c, nil
}

// Supported Algorithms.
const (
	AlgUnknown   Algorithm = 0x0000
	AlgRSA       Algorithm = 0x0001
	AlgSHA1      Algorithm = 0x0004
	AlgAES       Algorithm = 0x0006
	AlgKeyedHash Algorithm = 0x0008
	AlgSHA256    Algorithm = 0x000B
	AlgSHA384    Algorithm = 0x000C
	AlgSHA512    Algorithm = 0x000D
	AlgNull      Algorithm = 0x0010
	AlgRSASSA    Algorithm = 0x0014
	AlgRSAES     Algorithm = 0x0015
	AlgRSAPSS    Algorithm = 0x0016
	AlgOAEP      Algorithm = 0x0017
	AlgECDSA     Algorithm = 0x0018
	AlgECDH      Algorithm = 0x0019
	AlgECDAA     Algorithm = 0x001A
	AlgKDF2      Algorithm = 0x0021
	AlgECC       Algorithm = 0x0023
	AlgCTR       Algorithm = 0x0040
	AlgOFB       Algorithm = 0x0041
	AlgCBC       Algorithm = 0x0042
	AlgCFB       Algorithm = 0x0043
	AlgECB       Algorithm = 0x0044
)

// SessionType defines the type of session created in StartAuthSession.
type SessionType uint8

// Supported session types.
const (
	SessionHMAC   SessionType = 0x00
	SessionPolicy SessionType = 0x01
	SessionTrial  SessionType = 0x03
)

// SessionAttributes represents an attribute of a session.
type SessionAttributes byte

const (
	AttrContinueSession SessionAttributes = 1 << iota
	AttrAuditExclusive
	AttrAuditReset
	_ // bit 3 reserved
	_ // bit 4 reserved
	AttrDecrypt
	AttrEcrypt
	AttrAudit
)

// EmptyAuth represents the empty authorization value.
var EmptyAuth []byte

// KeyProp is a bitmask used in Attributes field of key templates. Individual
// flags should be OR-ed to form a full mask.
type KeyProp uint32

// Key properties.
const (
	FlagFixedTPM            KeyProp = 0x00000002
	FlagFixedParent         KeyProp = 0x00000010
	FlagSensitiveDataOrigin KeyProp = 0x00000020
	FlagUserWithAuth        KeyProp = 0x00000040
	FlagAdminWithPolicy     KeyProp = 0x00000080
	FlagNoDA                KeyProp = 0x00000400
	FlagRestricted          KeyProp = 0x00010000
	FlagDecrypt             KeyProp = 0x00020000
	FlagSign                KeyProp = 0x00040000

	FlagSealDefault   = FlagFixedTPM | FlagFixedParent
	FlagSignerDefault = FlagSign | FlagRestricted | FlagFixedTPM |
		FlagFixedParent | FlagSensitiveDataOrigin | FlagUserWithAuth
	FlagStorageDefault = FlagDecrypt | FlagRestricted | FlagFixedTPM |
		FlagFixedParent | FlagSensitiveDataOrigin | FlagUserWithAuth
)

// TPMProp represents the index of a TPM property in a call to GetCapability().
type TPMProp uint32

// TPM Capability Properties.
const (
	NVMaxBufferSize TPMProp = 0x100 + 44
)

// Reserved Handles.
const (
	HandleOwner tpmutil.Handle = 0x40000001 + iota
	HandleRevoke
	HandleTransport
	HandleOperator
	HandleAdmin
	HandleEK
	HandleNull
	HandleUnassigned
	HandlePasswordSession
	HandleLockout
	HandleEndorsement
	HandlePlatform
)

// Capability identifies some TPM property or state type.
type Capability uint32

// TPM Capabilies.
const (
	CapabilityAlgs Capability = iota
	CapabilityHandles
	CapabilityCommands
	CapabilityPPCommands
	CapabilityAuditCommands
	CapabilityPCRs
	CapabilityTPMProperties
	CapabilityPCRProperties
	CapabilityECCCurves
	CapabilityAuthPolicies
)

// TPM Structure Tags. Tags are used to disambiguate structures, similar to Alg
// values: tag value defines what kind of data lives in a nested field.
const (
	TagNull           tpmutil.Tag = 0x8000
	TagNoSessions     tpmutil.Tag = 0x8001
	TagSessions       tpmutil.Tag = 0x8002
	TagAttestCertify  tpmutil.Tag = 0x8017
	TagAttestCreation tpmutil.Tag = 0x801a
	TagHashCheck      tpmutil.Tag = 0x8024
)

// StartupType instructs the TPM on how to handle its state during Shutdown or
// Startup.
type StartupType uint16

// Startup types
const (
	StartupClear StartupType = iota
	StartupState
)

// EllipticCurve identifies specific EC curves.
type EllipticCurve uint16

// ECC curves supported by TPM 2.0 spec.
const (
	CurveNISTP192 = EllipticCurve(iota + 1)
	CurveNISTP224
	CurveNISTP256
	CurveNISTP384
	CurveNISTP521

	CurveBNP256 = EllipticCurve(iota + 10)
	CurveBNP638

	CurveSM2P256 = EllipticCurve(0x0020)
)

var toGoCurve = map[EllipticCurve]elliptic.Curve{
	CurveNISTP224: elliptic.P224(),
	CurveNISTP256: elliptic.P256(),
	CurveNISTP384: elliptic.P384(),
	CurveNISTP521: elliptic.P521(),
}

// Supported TPM operations.
const (
	cmdEvictControl       tpmutil.Command = 0x00000120
	cmdUndefineSpace      tpmutil.Command = 0x00000122
	cmdClockSet           tpmutil.Command = 0x00000128
	cmdDefineSpace        tpmutil.Command = 0x0000012A
	cmdPCRAllocate        tpmutil.Command = 0x0000012B
	cmdCreatePrimary      tpmutil.Command = 0x00000131
	cmdIncrementNVCounter tpmutil.Command = 0x00000134
	cmdWriteNV            tpmutil.Command = 0x00000137
	cmdPCREvent           tpmutil.Command = 0x0000013C
	cmdStartup            tpmutil.Command = 0x00000144
	cmdShutdown           tpmutil.Command = 0x00000145
	cmdStirRandom         tpmutil.Command = 0x00000146
	cmdActivateCredential tpmutil.Command = 0x00000147
	cmdCertify            tpmutil.Command = 0x00000148
	cmdCertifyCreation    tpmutil.Command = 0x0000014A
	cmdReadNV             tpmutil.Command = 0x0000014E
	cmdCreate             tpmutil.Command = 0x00000153
	cmdLoad               tpmutil.Command = 0x00000157
	cmdQuote              tpmutil.Command = 0x00000158
	cmdSign               tpmutil.Command = 0x0000015D
	cmdUnseal             tpmutil.Command = 0x0000015E
	cmdContextLoad        tpmutil.Command = 0x00000161
	cmdContextSave        tpmutil.Command = 0x00000162
	cmdFlushContext       tpmutil.Command = 0x00000165
	cmdLoadExternal       tpmutil.Command = 0x00000167
	cmdMakeCredential     tpmutil.Command = 0x00000168
	cmdReadPublicNV       tpmutil.Command = 0x00000169
	cmdReadPublic         tpmutil.Command = 0x00000173
	cmdStartAuthSession   tpmutil.Command = 0x00000176
	cmdGetCapability      tpmutil.Command = 0x0000017A
	cmdGetRandom          tpmutil.Command = 0x0000017B
	cmdHash               tpmutil.Command = 0x0000017D
	cmdPCRRead            tpmutil.Command = 0x0000017E
	cmdPolicyPCR          tpmutil.Command = 0x0000017F
	cmdReadClock          tpmutil.Command = 0x00000181
	cmdPCRExtend          tpmutil.Command = 0x00000182
	cmdPolicyGetDigest    tpmutil.Command = 0x00000189
	cmdPolicyPassword     tpmutil.Command = 0x0000018C
)

// Regular TPM 2.0 devices use 24-bit mask (3 bytes) for PCR selection.
const sizeOfPCRSelect = 3

// digestSize returns the size of a digest for hashing algorithm alg, or 0 if
// it's not recognized.
func digestSize(alg Algorithm) int {
	switch alg {
	case AlgSHA1:
		return sha1.Size
	case AlgSHA256:
		return sha256.Size
	case AlgSHA512:
		return sha512.Size
	default:
		return 0
	}
}

const defaultRSAExponent = 1<<16 + 1

var hashConstructors = map[Algorithm]func() hash.Hash{
	AlgSHA1:   sha1.New,
	AlgSHA256: sha256.New,
	AlgSHA384: sha512.New384,
	AlgSHA512: sha512.New,
}
<commit_msg>Add command code for PolicySecret (#55)<commit_after>// Copyright (c) 2018, Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package tpm2

import (
	"crypto/elliptic"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"fmt"
	"hash"

	"github.com/google/go-tpm/tpmutil"
)

func init() {
	tpmutil.UseTPM20LengthPrefixSize()
}

// Algorithm represents a TPM_ALG_ID value.
type Algorithm uint16

// IsNull returns true if a is AlgNull or zero (unset).
func (a Algorithm) IsNull() bool {
	return a == AlgNull || a == AlgUnknown
}

// UsesCount returns true if a signature algorithm uses count value.
func (a Algorithm) UsesCount() bool {
	return a == AlgECDAA
}

// HashConstructor returns a function that can be used to make a
// hash.Hash using the specified algorithm. An error is returned
// if the algorithm is not a hash algorithm.
func (a Algorithm) HashConstructor() (func() hash.Hash, error) {
	c, ok := hashConstructors[a]
	if !ok {
		return nil, fmt.Errorf("algorithm not supported: 0x%x", a)
	}
	return c, nil
}

// Supported Algorithms.
const (
	AlgUnknown   Algorithm = 0x0000
	AlgRSA       Algorithm = 0x0001
	AlgSHA1      Algorithm = 0x0004
	AlgAES       Algorithm = 0x0006
	AlgKeyedHash Algorithm = 0x0008
	AlgSHA256    Algorithm = 0x000B
	AlgSHA384    Algorithm = 0x000C
	AlgSHA512    Algorithm = 0x000D
	AlgNull      Algorithm = 0x0010
	AlgRSASSA    Algorithm = 0x0014
	AlgRSAES     Algorithm = 0x0015
	AlgRSAPSS    Algorithm = 0x0016
	AlgOAEP      Algorithm = 0x0017
	AlgECDSA     Algorithm = 0x0018
	AlgECDH      Algorithm = 0x0019
	AlgECDAA     Algorithm = 0x001A
	AlgKDF2      Algorithm = 0x0021
	AlgECC       Algorithm = 0x0023
	AlgCTR       Algorithm = 0x0040
	AlgOFB       Algorithm = 0x0041
	AlgCBC       Algorithm = 0x0042
	AlgCFB       Algorithm = 0x0043
	AlgECB       Algorithm = 0x0044
)

// SessionType defines the type of session created in StartAuthSession.
type SessionType uint8

// Supported session types.
const (
	SessionHMAC   SessionType = 0x00
	SessionPolicy SessionType = 0x01
	SessionTrial  SessionType = 0x03
)

// SessionAttributes represents an attribute of a session.
type SessionAttributes byte

const (
	AttrContinueSession SessionAttributes = 1 << iota
	AttrAuditExclusive
	AttrAuditReset
	_ // bit 3 reserved
	_ // bit 4 reserved
	AttrDecrypt
	AttrEcrypt
	AttrAudit
)

// EmptyAuth represents the empty authorization value.
var EmptyAuth []byte

// KeyProp is a bitmask used in Attributes field of key templates. Individual
// flags should be OR-ed to form a full mask.
type KeyProp uint32

// Key properties.
const (
	FlagFixedTPM            KeyProp = 0x00000002
	FlagFixedParent         KeyProp = 0x00000010
	FlagSensitiveDataOrigin KeyProp = 0x00000020
	FlagUserWithAuth        KeyProp = 0x00000040
	FlagAdminWithPolicy     KeyProp = 0x00000080
	FlagNoDA                KeyProp = 0x00000400
	FlagRestricted          KeyProp = 0x00010000
	FlagDecrypt             KeyProp = 0x00020000
	FlagSign                KeyProp = 0x00040000

	FlagSealDefault   = FlagFixedTPM | FlagFixedParent
	FlagSignerDefault = FlagSign | FlagRestricted | FlagFixedTPM |
		FlagFixedParent | FlagSensitiveDataOrigin | FlagUserWithAuth
	FlagStorageDefault = FlagDecrypt | FlagRestricted | FlagFixedTPM |
		FlagFixedParent | FlagSensitiveDataOrigin | FlagUserWithAuth
)

// TPMProp represents the index of a TPM property in a call to GetCapability().
type TPMProp uint32

// TPM Capability Properties.
const (
	NVMaxBufferSize TPMProp = 0x100 + 44
)

// Reserved Handles.
const (
	HandleOwner tpmutil.Handle = 0x40000001 + iota
	HandleRevoke
	HandleTransport
	HandleOperator
	HandleAdmin
	HandleEK
	HandleNull
	HandleUnassigned
	HandlePasswordSession
	HandleLockout
	HandleEndorsement
	HandlePlatform
)

// Capability identifies some TPM property or state type.
type Capability uint32

// TPM Capabilies.
const (
	CapabilityAlgs Capability = iota
	CapabilityHandles
	CapabilityCommands
	CapabilityPPCommands
	CapabilityAuditCommands
	CapabilityPCRs
	CapabilityTPMProperties
	CapabilityPCRProperties
	CapabilityECCCurves
	CapabilityAuthPolicies
)

// TPM Structure Tags. Tags are used to disambiguate structures, similar to Alg
// values: tag value defines what kind of data lives in a nested field.
const (
	TagNull           tpmutil.Tag = 0x8000
	TagNoSessions     tpmutil.Tag = 0x8001
	TagSessions       tpmutil.Tag = 0x8002
	TagAttestCertify  tpmutil.Tag = 0x8017
	TagAttestCreation tpmutil.Tag = 0x801a
	TagHashCheck      tpmutil.Tag = 0x8024
)

// StartupType instructs the TPM on how to handle its state during Shutdown or
// Startup.
type StartupType uint16

// Startup types
const (
	StartupClear StartupType = iota
	StartupState
)

// EllipticCurve identifies specific EC curves.
type EllipticCurve uint16

// ECC curves supported by TPM 2.0 spec.
const (
	CurveNISTP192 = EllipticCurve(iota + 1)
	CurveNISTP224
	CurveNISTP256
	CurveNISTP384
	CurveNISTP521

	CurveBNP256 = EllipticCurve(iota + 10)
	CurveBNP638

	CurveSM2P256 = EllipticCurve(0x0020)
)

var toGoCurve = map[EllipticCurve]elliptic.Curve{
	CurveNISTP224: elliptic.P224(),
	CurveNISTP256: elliptic.P256(),
	CurveNISTP384: elliptic.P384(),
	CurveNISTP521: elliptic.P521(),
}

// Supported TPM operations.
const (
	cmdEvictControl       tpmutil.Command = 0x00000120
	cmdUndefineSpace      tpmutil.Command = 0x00000122
	cmdClockSet           tpmutil.Command = 0x00000128
	cmdDefineSpace        tpmutil.Command = 0x0000012A
	cmdPCRAllocate        tpmutil.Command = 0x0000012B
	cmdCreatePrimary      tpmutil.Command = 0x00000131
	cmdIncrementNVCounter tpmutil.Command = 0x00000134
	cmdWriteNV            tpmutil.Command = 0x00000137
	cmdPCREvent           tpmutil.Command = 0x0000013C
	cmdStartup            tpmutil.Command = 0x00000144
	cmdShutdown           tpmutil.Command = 0x00000145
	cmdStirRandom         tpmutil.Command = 0x00000146
	cmdActivateCredential tpmutil.Command = 0x00000147
	cmdCertify            tpmutil.Command = 0x00000148
	cmdCertifyCreation    tpmutil.Command = 0x0000014A
	cmdReadNV             tpmutil.Command = 0x0000014E
	// CmdPolicySecret is a command code for TPM2_PolicySecret.
	// It's exported for computing of default AuthPolicy value.
	CmdPolicySecret     tpmutil.Command = 0x00000151
	cmdCreate           tpmutil.Command = 0x00000153
	cmdLoad             tpmutil.Command = 0x00000157
	cmdQuote            tpmutil.Command = 0x00000158
	cmdSign             tpmutil.Command = 0x0000015D
	cmdUnseal           tpmutil.Command = 0x0000015E
	cmdContextLoad      tpmutil.Command = 0x00000161
	cmdContextSave      tpmutil.Command = 0x00000162
	cmdFlushContext     tpmutil.Command = 0x00000165
	cmdLoadExternal     tpmutil.Command = 0x00000167
	cmdMakeCredential   tpmutil.Command = 0x00000168
	cmdReadPublicNV     tpmutil.Command = 0x00000169
	cmdReadPublic       tpmutil.Command = 0x00000173
	cmdStartAuthSession tpmutil.Command = 0x00000176
	cmdGetCapability    tpmutil.Command = 0x0000017A
	cmdGetRandom        tpmutil.Command = 0x0000017B
	cmdHash             tpmutil.Command = 0x0000017D
	cmdPCRRead          tpmutil.Command = 0x0000017E
	cmdPolicyPCR        tpmutil.Command = 0x0000017F
	cmdReadClock        tpmutil.Command = 0x00000181
	cmdPCRExtend        tpmutil.Command = 0x00000182
	cmdPolicyGetDigest  tpmutil.Command = 0x00000189
	cmdPolicyPassword   tpmutil.Command = 0x0000018C
)

// Regular TPM 2.0 devices use 24-bit mask (3 bytes) for PCR selection.
const sizeOfPCRSelect = 3

// digestSize returns the size of a digest for hashing algorithm alg, or 0 if
// it's not recognized.
func digestSize(alg Algorithm) int {
	switch alg {
	case AlgSHA1:
		return sha1.Size
	case AlgSHA256:
		return sha256.Size
	case AlgSHA512:
		return sha512.Size
	default:
		return 0
	}
}

const defaultRSAExponent = 1<<16 + 1

var hashConstructors = map[Algorithm]func() hash.Hash{
	AlgSHA1:   sha1.New,
	AlgSHA256: sha256.New,
	AlgSHA384: sha512.New384,
	AlgSHA512: sha512.New,
}
<|endoftext|>


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

package tests_test

import (
	"fmt"
	"os"
	"path"
	"strconv"
	"testing"

	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/config"
	ginkgo_reporters "github.com/onsi/ginkgo/reporters"

	"kubevirt.io/kubevirt/tests/flags"

	"kubevirt.io/kubevirt/tests/reporter"

	"kubevirt.io/kubevirt/tests"
	qe_reporters "kubevirt.io/qe-tools/pkg/ginkgo-reporters"

	_ "kubevirt.io/kubevirt/tests/launchsecurity"
	_ "kubevirt.io/kubevirt/tests/monitoring"
	_ "kubevirt.io/kubevirt/tests/network"
	_ "kubevirt.io/kubevirt/tests/numa"
	_ "kubevirt.io/kubevirt/tests/performance"
	_ "kubevirt.io/kubevirt/tests/realtime"
	_ "kubevirt.io/kubevirt/tests/storage"
	_ "kubevirt.io/kubevirt/tests/virtoperatorbasic"
)

var justAfterEachReporter = []reporter.JustAfterEachReporter{}

func TestTests(t *testing.T) {
	flags.NormalizeFlags()
	tests.CalculateNamespaces()
	maxFails := getMaxFailsFromEnv()
	artifactsPath := path.Join(flags.ArtifactsDir, "k8s-reporter")
	junitOutput := path.Join(flags.ArtifactsDir, "junit.functest.xml")
	if qe_reporters.JunitOutput != "" {
		junitOutput = qe_reporters.JunitOutput
	}
	if config.GinkgoConfig.ParallelTotal > 1 {
		artifactsPath = path.Join(artifactsPath, strconv.Itoa(config.GinkgoConfig.ParallelNode))
		junitOutput = path.Join(flags.ArtifactsDir, fmt.Sprintf("partial.junit.functest.%d.xml", config.GinkgoConfig.ParallelNode))
	}

	outputEnricherReporter := reporter.NewCapturedOutputEnricher(
		ginkgo_reporters.NewJUnitReporter(junitOutput),
	)
	k8sReporter := reporter.NewKubernetesReporter(artifactsPath, maxFails)
	justAfterEachReporter = append(justAfterEachReporter, outputEnricherReporter, k8sReporter)
	reporters := []Reporter{
		outputEnricherReporter,
		k8sReporter,
	}
	if qe_reporters.Polarion.Run {
		reporters = append(reporters, &qe_reporters.Polarion)
	}

	RunSpecsWithDefaultAndCustomReporters(t, "Tests Suite", reporters)
}

var _ = SynchronizedBeforeSuite(tests.SynchronizedBeforeTestSetup, tests.BeforeTestSuitSetup)

var _ = SynchronizedAfterSuite(tests.AfterTestSuitCleanup, tests.SynchronizedAfterTestSuiteCleanup)

func getMaxFailsFromEnv() int {
	maxFailsEnv := os.Getenv("REPORTER_MAX_FAILS")
	if maxFailsEnv == "" {
		return 10
	}

	maxFails, err := strconv.Atoi(maxFailsEnv)
	if err != nil { // if the variable is set with a non int value
		fmt.Println("Invalid REPORTER_MAX_FAILS variable, defaulting to 10")
		return 10
	}

	return maxFails
}

// Collect info directly after each `It` execution with our reporters
// to collect the state directly after the spec.
var _ = JustAfterEach(func() {
	for _, reporter := range justAfterEachReporter {
		reporter.JustAfterEach(CurrentGinkgoTestDescription())
	}
})
<commit_msg>Adjust file names to use parallelnode<commit_after>/*
 * This file is part of the KubeVirt project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Copyright 2017 Red Hat, Inc.
 *
 */

package tests_test

import (
	"fmt"
	"os"
	"path/filepath"
	"strconv"
	"testing"

	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/config"
	ginkgo_reporters "github.com/onsi/ginkgo/reporters"

	"kubevirt.io/kubevirt/tests/flags"

	"kubevirt.io/kubevirt/tests/reporter"

	"kubevirt.io/kubevirt/tests"
	qe_reporters "kubevirt.io/qe-tools/pkg/ginkgo-reporters"

	_ "kubevirt.io/kubevirt/tests/launchsecurity"
	_ "kubevirt.io/kubevirt/tests/monitoring"
	_ "kubevirt.io/kubevirt/tests/network"
	_ "kubevirt.io/kubevirt/tests/numa"
	_ "kubevirt.io/kubevirt/tests/performance"
	_ "kubevirt.io/kubevirt/tests/realtime"
	_ "kubevirt.io/kubevirt/tests/storage"
	_ "kubevirt.io/kubevirt/tests/virtoperatorbasic"
)

var justAfterEachReporter = []reporter.JustAfterEachReporter{}

func TestTests(t *testing.T) {
	flags.NormalizeFlags()
	tests.CalculateNamespaces()
	maxFails := getMaxFailsFromEnv()
	artifactsPath := filepath.Join(flags.ArtifactsDir, "k8s-reporter")
	junitOutput := filepath.Join(flags.ArtifactsDir, "junit.functest.xml")
	if qe_reporters.JunitOutput != "" {
		junitOutput = qe_reporters.JunitOutput
	}
	if config.GinkgoConfig.ParallelTotal > 1 {
		artifactsPath = filepath.Join(artifactsPath, strconv.Itoa(config.GinkgoConfig.ParallelNode))
		junitOutput = filepath.Join(flags.ArtifactsDir, fmt.Sprintf("partial.junit.functest.%d.xml", config.GinkgoConfig.ParallelNode))
	}

	outputEnricherReporter := reporter.NewCapturedOutputEnricher(
		ginkgo_reporters.NewJUnitReporter(junitOutput),
	)
	k8sReporter := reporter.NewKubernetesReporter(artifactsPath, maxFails)
	justAfterEachReporter = append(justAfterEachReporter, outputEnricherReporter, k8sReporter)
	reporters := []Reporter{
		outputEnricherReporter,
		k8sReporter,
	}
	if qe_reporters.Polarion.Run {
		if config.GinkgoConfig.ParallelTotal > 1 {
			qe_reporters.Polarion.Filename = filepath.Join(flags.ArtifactsDir, fmt.Sprintf("partial.polarion.functest.%d.xml", config.GinkgoConfig.ParallelNode))
		}
		reporters = append(reporters, &qe_reporters.Polarion)
	}

	RunSpecsWithDefaultAndCustomReporters(t, "Tests Suite", reporters)
}

var _ = SynchronizedBeforeSuite(tests.SynchronizedBeforeTestSetup, tests.BeforeTestSuitSetup)

var _ = SynchronizedAfterSuite(tests.AfterTestSuitCleanup, tests.SynchronizedAfterTestSuiteCleanup)

func getMaxFailsFromEnv() int {
	maxFailsEnv := os.Getenv("REPORTER_MAX_FAILS")
	if maxFailsEnv == "" {
		return 10
	}

	maxFails, err := strconv.Atoi(maxFailsEnv)
	if err != nil { // if the variable is set with a non int value
		fmt.Println("Invalid REPORTER_MAX_FAILS variable, defaulting to 10")
		return 10
	}

	return maxFails
}

// Collect info directly after each `It` execution with our reporters
// to collect the state directly after the spec.
var _ = JustAfterEach(func() {
	for _, reporter := range justAfterEachReporter {
		reporter.JustAfterEach(CurrentGinkgoTestDescription())
	}
})
<|endoftext|>


<commit_before>package radosAPI

import (
	"os"
	"testing"
	"time"

	. "github.com/smartystreets/goconvey/convey"
)

func TestNewAPI(t *testing.T) {
	Convey("Testing New API", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		So(api, ShouldNotBeNil)
	})
}

func TestNewAPIWithPrefix(t *testing.T) {
	Convey("Testing New API with prefix", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"), "admin")

		So(api, ShouldNotBeNil)
	})
}

func TestCreateUser(t *testing.T) {
	Convey("Testing Create user", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"), "admin")

		user, err := api.CreateUser(UserConfig{
			UID:         "UnitTest",
			DisplayName: "Unit Test",
		})
		So(err, ShouldBeNil)
		So(user, ShouldNotBeNil)
		So(user.DisplayName, ShouldEqual, "Unit Test")
	})
}

func TestCreateUserWithoutUID(t *testing.T) {
	Convey("Testing Create user without UID", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"), "admin")

		user, err := api.CreateUser(UserConfig{
			DisplayName: "Unit Test",
		})
		So(err, ShouldNotBeNil)
		So(user, ShouldBeNil)
	})
}

func TestCreateUserWithoutName(t *testing.T) {
	Convey("Testing Create user without name", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"), "admin")

		user, err := api.CreateUser(UserConfig{
			UID: "UnitTest",
		})
		So(err, ShouldNotBeNil)
		So(user, ShouldBeNil)
	})
}

func TestGetUser(t *testing.T) {
	Convey("Testing Get user", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		user, err := api.GetUser("UnitTest")
		So(err, ShouldBeNil)
		So(user, ShouldNotBeNil)
	})
}

func TestUpdateUser(t *testing.T) {
	Convey("Testing Update user", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		user, err := api.UpdateUser(UserConfig{
			UID:   "UnitTest",
			Email: "UnitTest@test.com",
		})
		So(err, ShouldBeNil)
		So(user, ShouldNotBeNil)
		So(user.Email, ShouldEqual, "UnitTest@test.com")
	})
}

func TestUpdateUserWithoutUID(t *testing.T) {
	Convey("Testing Update user without UID", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		user, err := api.UpdateUser(UserConfig{
			Email: "UnitTest@test.com",
		})
		So(err, ShouldNotBeNil)
		So(user, ShouldBeNil)
	})
}

func TestRemoveUser(t *testing.T) {
	Convey("Testing Remove user", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		err := api.RemoveUser(UserConfig{
			UID:       "UnitTest",
			PurgeData: true,
		})
		So(err, ShouldBeNil)
		user, err := api.GetUser("UnitTest")
		So(err, ShouldNotBeNil)
		So(user, ShouldBeNil)
	})
}

func TestRemoveUserWithoutUID(t *testing.T) {
	Convey("Testing Remove user without UID", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		err := api.RemoveUser(UserConfig{
			PurgeData: true,
		})
		So(err, ShouldNotBeNil)
	})
}

func TestGetUsageEmpty(t *testing.T) {
	Convey("Testing Get Usage with empty struct", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		usage, err := api.GetUsage(UsageConfig{})
		So(err, ShouldBeNil)
		So(usage, ShouldNotBeNil)
		So(usage.Entries, ShouldBeNil)
		So(usage.Summary, ShouldBeNil)
	})
}

func TestGetUsageSummary(t *testing.T) {
	Convey("Testing Get Usage summary field", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		usage, err := api.GetUsage(UsageConfig{
			ShowSummary: true,
		})
		So(err, ShouldBeNil)
		So(usage, ShouldNotBeNil)
		So(usage.Entries, ShouldBeNil)
		So(usage.Summary, ShouldNotBeNil)
	})
}

func TestGetUsageEntries(t *testing.T) {
	Convey("Testing Get Usage entries field", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		usage, err := api.GetUsage(UsageConfig{
			ShowEntries: true,
		})
		So(err, ShouldBeNil)
		So(usage, ShouldNotBeNil)
		So(usage.Entries, ShouldNotBeNil)
		So(usage.Summary, ShouldBeNil)
	})
}

func TestGetUsageEntriesSummary(t *testing.T) {
	Convey("Testing Get Usage entries/summary field", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		usage, err := api.GetUsage(UsageConfig{
			ShowEntries: true,
			ShowSummary: true,
		})
		So(err, ShouldBeNil)
		So(usage, ShouldNotBeNil)
		So(usage.Entries, ShouldNotBeNil)
		So(usage.Summary, ShouldNotBeNil)
	})
}

func TestGetUsageEntriesSummaryWithUID(t *testing.T) {
	Convey("Testing Get Usage entries/summary field with specified uid", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		usage, err := api.GetUsage(UsageConfig{
			UID:         "UnitTest",
			ShowEntries: true,
			ShowSummary: true,
		})
		So(err, ShouldBeNil)
		So(usage, ShouldNotBeNil)
		So(usage.Entries, ShouldNotBeNil)
		So(usage.Summary, ShouldNotBeNil)
	})
}

func TestGetUsageEntriesSummaryWithUIDStartTime(t *testing.T) {
	Convey("Testing Get Usage entries/summary field with specified uid, and start Time", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		now := time.Now().AddDate(0, 0, -1)
		usage, err := api.GetUsage(UsageConfig{
			UID:         "UnitTest",
			ShowEntries: true,
			ShowSummary: true,
			Start:       &now,
		})
		So(err, ShouldBeNil)
		So(usage, ShouldNotBeNil)
		So(usage.Entries, ShouldNotBeNil)
		So(usage.Summary, ShouldNotBeNil)
	})
}

func TestDeleteAllUsages(t *testing.T) {
	Convey("Testing Delete all usages", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		err := api.DeleteUsage(UsageConfig{
			UID:       "UnitTest",
			RemoveAll: true,
		})
		So(err, ShouldBeNil)
	})
}
<commit_msg>test: add key<commit_after>package radosAPI

import (
	"os"
	"testing"
	"time"

	. "github.com/smartystreets/goconvey/convey"
)

func TestNewAPI(t *testing.T) {
	Convey("Testing New API", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		So(api, ShouldNotBeNil)
	})
}

func TestNewAPIWithPrefix(t *testing.T) {
	Convey("Testing New API with prefix", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"), "admin")

		So(api, ShouldNotBeNil)
	})
}

func TestCreateUser(t *testing.T) {
	Convey("Testing Create user", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"), "admin")

		user, err := api.CreateUser(UserConfig{
			UID:         "UnitTest",
			DisplayName: "Unit Test",
		})
		So(err, ShouldBeNil)
		So(user, ShouldNotBeNil)
		So(user.DisplayName, ShouldEqual, "Unit Test")
	})
}

func TestCreateUserWithoutUID(t *testing.T) {
	Convey("Testing Create user without UID", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"), "admin")

		user, err := api.CreateUser(UserConfig{
			DisplayName: "Unit Test",
		})
		So(err, ShouldNotBeNil)
		So(user, ShouldBeNil)
	})
}

func TestCreateUserWithoutName(t *testing.T) {
	Convey("Testing Create user without name", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"), "admin")

		user, err := api.CreateUser(UserConfig{
			UID: "UnitTest",
		})
		So(err, ShouldNotBeNil)
		So(user, ShouldBeNil)
	})
}

func TestGetUser(t *testing.T) {
	Convey("Testing Get user", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		user, err := api.GetUser("UnitTest")
		So(err, ShouldBeNil)
		So(user, ShouldNotBeNil)
	})
}

func TestUpdateUser(t *testing.T) {
	Convey("Testing Update user", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		user, err := api.UpdateUser(UserConfig{
			UID:   "UnitTest",
			Email: "UnitTest@test.com",
		})
		So(err, ShouldBeNil)
		So(user, ShouldNotBeNil)
		So(user.Email, ShouldEqual, "UnitTest@test.com")
	})
}

func TestUpdateUserWithoutUID(t *testing.T) {
	Convey("Testing Update user without UID", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		user, err := api.UpdateUser(UserConfig{
			Email: "UnitTest@test.com",
		})
		So(err, ShouldNotBeNil)
		So(user, ShouldBeNil)
	})
}

func TestRemoveUser(t *testing.T) {
	Convey("Testing Remove user", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		err := api.RemoveUser(UserConfig{
			UID:       "UnitTest",
			PurgeData: true,
		})
		So(err, ShouldBeNil)
		user, err := api.GetUser("UnitTest")
		So(err, ShouldNotBeNil)
		So(user, ShouldBeNil)
	})
}

func TestRemoveUserWithoutUID(t *testing.T) {
	Convey("Testing Remove user without UID", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		err := api.RemoveUser(UserConfig{
			PurgeData: true,
		})
		So(err, ShouldNotBeNil)
	})
}

func TestGetUsageEmpty(t *testing.T) {
	Convey("Testing Get Usage with empty struct", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		usage, err := api.GetUsage(UsageConfig{})
		So(err, ShouldBeNil)
		So(usage, ShouldNotBeNil)
		So(usage.Entries, ShouldBeNil)
		So(usage.Summary, ShouldBeNil)
	})
}

func TestGetUsageSummary(t *testing.T) {
	Convey("Testing Get Usage summary field", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		usage, err := api.GetUsage(UsageConfig{
			ShowSummary: true,
		})
		So(err, ShouldBeNil)
		So(usage, ShouldNotBeNil)
		So(usage.Entries, ShouldBeNil)
		So(usage.Summary, ShouldNotBeNil)
	})
}

func TestGetUsageEntries(t *testing.T) {
	Convey("Testing Get Usage entries field", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		usage, err := api.GetUsage(UsageConfig{
			ShowEntries: true,
		})
		So(err, ShouldBeNil)
		So(usage, ShouldNotBeNil)
		So(usage.Entries, ShouldNotBeNil)
		So(usage.Summary, ShouldBeNil)
	})
}

func TestGetUsageEntriesSummary(t *testing.T) {
	Convey("Testing Get Usage entries/summary field", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		usage, err := api.GetUsage(UsageConfig{
			ShowEntries: true,
			ShowSummary: true,
		})
		So(err, ShouldBeNil)
		So(usage, ShouldNotBeNil)
		So(usage.Entries, ShouldNotBeNil)
		So(usage.Summary, ShouldNotBeNil)
	})
}

func TestGetUsageEntriesSummaryWithUID(t *testing.T) {
	Convey("Testing Get Usage entries/summary field with specified uid", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		usage, err := api.GetUsage(UsageConfig{
			UID:         "UnitTest",
			ShowEntries: true,
			ShowSummary: true,
		})
		So(err, ShouldBeNil)
		So(usage, ShouldNotBeNil)
		So(usage.Entries, ShouldNotBeNil)
		So(usage.Summary, ShouldNotBeNil)
	})
}

func TestGetUsageEntriesSummaryWithUIDStartTime(t *testing.T) {
	Convey("Testing Get Usage entries/summary field with specified uid, and start Time", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		now := time.Now().AddDate(0, 0, -1)
		usage, err := api.GetUsage(UsageConfig{
			UID:         "UnitTest",
			ShowEntries: true,
			ShowSummary: true,
			Start:       &now,
		})
		So(err, ShouldBeNil)
		So(usage, ShouldNotBeNil)
		So(usage.Entries, ShouldNotBeNil)
		So(usage.Summary, ShouldNotBeNil)
	})
}

func TestDeleteAllUsages(t *testing.T) {
	Convey("Testing Delete all usages", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		err := api.DeleteUsage(UsageConfig{
			UID:       "UnitTest",
			RemoveAll: true,
		})
		So(err, ShouldBeNil)
	})
}

func TestCreateKey(t *testing.T) {
	Convey("Testing Create Key", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		user, err := api.CreateUser(UserConfig{
			UID:         "UnitTest",
			DisplayName: "Unit Test",
		})
		So(err, ShouldBeNil)
		So(user, ShouldNotBeNil)
		So(user.DisplayName, ShouldEqual, "Unit Test")

		keys, err := api.CreateKey(KeyConfig{
			UID: "UnitTest",
		})
		So(err, ShouldBeNil)
		So(keys, ShouldNotBeNil)

		err = api.RemoveUser(UserConfig{
			UID:       "UnitTest",
			PurgeData: true,
		})
		So(err, ShouldBeNil)
	})
}

func TestCreateKeyWithoutUID(t *testing.T) {
	Convey("Testing Create Key without UID", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		user, err := api.CreateUser(UserConfig{
			UID:         "UnitTest",
			DisplayName: "Unit Test",
		})
		So(err, ShouldBeNil)
		So(user, ShouldNotBeNil)
		So(user.DisplayName, ShouldEqual, "Unit Test")

		keys, err := api.CreateKey(KeyConfig{})
		So(err, ShouldNotBeNil)
		So(keys, ShouldBeNil)

		err = api.RemoveUser(UserConfig{
			UID:       "UnitTest",
			PurgeData: true,
		})
		So(err, ShouldBeNil)
	})
}

func TestRemoveKey(t *testing.T) {
	Convey("Testing Remove Key", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		user, err := api.CreateUser(UserConfig{
			UID:         "UnitTest",
			DisplayName: "Unit Test",
		})
		So(err, ShouldBeNil)
		So(user, ShouldNotBeNil)
		So(user.DisplayName, ShouldEqual, "Unit Test")

		keys, err := api.CreateKey(KeyConfig{
			UID: "UnitTest",
		})
		So(err, ShouldBeNil)
		So(keys, ShouldNotBeNil)

		err = api.RemoveKey(KeyConfig{
			AccessKey: (*keys)[0].AccessKey,
		})

		So(err, ShouldBeNil)

		err = api.RemoveUser(UserConfig{
			UID:       "UnitTest",
			PurgeData: true,
		})
		So(err, ShouldBeNil)
	})
}

func TestRemoveKeyWithoutAccessKey(t *testing.T) {
	Convey("Testing Remove Key without access key", t, func() {
		api := New(os.Getenv("RADOSGW_API"), os.Getenv("RADOSGW_ACCESS"), os.Getenv("RADOSGW_SECRET"))

		user, err := api.CreateUser(UserConfig{
			UID:         "UnitTest",
			DisplayName: "Unit Test",
		})
		So(err, ShouldBeNil)
		So(user, ShouldNotBeNil)
		So(user.DisplayName, ShouldEqual, "Unit Test")

		keys, err := api.CreateKey(KeyConfig{
			UID: "UnitTest",
		})
		So(err, ShouldBeNil)
		So(keys, ShouldNotBeNil)

		err = api.RemoveKey(KeyConfig{})

		So(err, ShouldNotBeNil)

		err = api.RemoveUser(UserConfig{
			UID:       "UnitTest",
			PurgeData: true,
		})
		So(err, ShouldBeNil)
	})
}
<|endoftext|>


<commit_before>// Copyright 2012-present Oliver Eilhard. All rights reserved.
// Use of this source code is governed by a MIT-license.
// See http://olivere.mit-license.org/license.txt for details.

package elastic

// AdjacencyMatrixAggregation  returning a form of adjacency matrix.
// The request provides a collection of named filter expressions,
// similar to the filters aggregation request. Each bucket in the
// response represents a non-empty cell in the matrix of intersecting filters.
//
// For details, see
// https://www.elastic.co/guide/en/elasticsearch/reference/6.0/search-aggregations-bucket-adjacency-matrix-aggregation.html
type AdjacencyMatrixAggregation struct {
	filters         map[string]Query
	subAggregations map[string]Aggregation
	meta            map[string]interface{}
}

// NewAdjacencyMatrixAggregation initializes a new AdjacencyMatrixAggregation.
func NewAdjacencyMatrixAggregation() *AdjacencyMatrixAggregation {
	return &AdjacencyMatrixAggregation{
		filters:         make(map[string]Query),
		subAggregations: make(map[string]Aggregation),
	}
}

// Filters adds the filter
func (a *AdjacencyMatrixAggregation) Filters(name string, filter Query) *AdjacencyMatrixAggregation {
	a.filters[name] = filter
	return a
}

// SubAggregation adds a sub-aggregation to this aggregation.
func (a *AdjacencyMatrixAggregation) SubAggregation(name string, subAggregation Aggregation) *AdjacencyMatrixAggregation {
	a.subAggregations[name] = subAggregation
	return a
}

// Meta sets the meta data to be included in the aggregation response.
func (a *AdjacencyMatrixAggregation) Meta(metaData map[string]interface{}) *AdjacencyMatrixAggregation {
	a.meta = metaData
	return a
}

// Source returns the a JSON-serializable interface.
func (a *AdjacencyMatrixAggregation) Source() (interface{}, error) {
	// Example:
	//	{
	//  "aggs" : {
	//		"interactions" : {
	//			"adjacency_matrix" : {
	//				"filters" : {
	//					"grpA" : { "terms" : { "accounts" : ["hillary", "sidney"] }},
	//					"grpB" : { "terms" : { "accounts" : ["donald", "mitt"] }},
	//					"grpC" : { "terms" : { "accounts" : ["vladimir", "nigel"] }}
	//				}
	//			}
	//		}
	//	}
	// This method returns only the (outer) { "adjacency_matrix" : {} } part.

	source := make(map[string]interface{})
	adjacencyMatrix := make(map[string]interface{})
	source["adjacency_matrix"] = adjacencyMatrix

	dict := make(map[string]interface{})
	for key, filter := range a.filters {
		src, err := filter.Source()
		if err != nil {
			return nil, err
		}
		dict[key] = src
	}
	adjacencyMatrix["filters"] = dict

	// AggregationBuilder (SubAggregations)
	if len(a.subAggregations) > 0 {
		aggsMap := make(map[string]interface{})
		source["aggregations"] = aggsMap
		for name, aggregate := range a.subAggregations {
			src, err := aggregate.Source()
			if err != nil {
				return nil, err
			}
			aggsMap[name] = src
		}
	}

	// Add Meta data if available
	if len(a.meta) > 0 {
		source["meta"] = a.meta
	}

	return source, nil
}
<commit_msg>Fix typo and link<commit_after>// Copyright 2012-present Oliver Eilhard. All rights reserved.
// Use of this source code is governed by a MIT-license.
// See http://olivere.mit-license.org/license.txt for details.

package elastic

// AdjacencyMatrixAggregation returning a form of adjacency matrix.
// The request provides a collection of named filter expressions,
// similar to the filters aggregation request. Each bucket in the
// response represents a non-empty cell in the matrix of intersecting filters.
//
// For details, see
// https://www.elastic.co/guide/en/elasticsearch/reference/6.2/search-aggregations-bucket-adjacency-matrix-aggregation.html
type AdjacencyMatrixAggregation struct {
	filters         map[string]Query
	subAggregations map[string]Aggregation
	meta            map[string]interface{}
}

// NewAdjacencyMatrixAggregation initializes a new AdjacencyMatrixAggregation.
func NewAdjacencyMatrixAggregation() *AdjacencyMatrixAggregation {
	return &AdjacencyMatrixAggregation{
		filters:         make(map[string]Query),
		subAggregations: make(map[string]Aggregation),
	}
}

// Filters adds the filter
func (a *AdjacencyMatrixAggregation) Filters(name string, filter Query) *AdjacencyMatrixAggregation {
	a.filters[name] = filter
	return a
}

// SubAggregation adds a sub-aggregation to this aggregation.
func (a *AdjacencyMatrixAggregation) SubAggregation(name string, subAggregation Aggregation) *AdjacencyMatrixAggregation {
	a.subAggregations[name] = subAggregation
	return a
}

// Meta sets the meta data to be included in the aggregation response.
func (a *AdjacencyMatrixAggregation) Meta(metaData map[string]interface{}) *AdjacencyMatrixAggregation {
	a.meta = metaData
	return a
}

// Source returns the a JSON-serializable interface.
func (a *AdjacencyMatrixAggregation) Source() (interface{}, error) {
	// Example:
	//	{
	//  "aggs" : {
	//		"interactions" : {
	//			"adjacency_matrix" : {
	//				"filters" : {
	//					"grpA" : { "terms" : { "accounts" : ["hillary", "sidney"] }},
	//					"grpB" : { "terms" : { "accounts" : ["donald", "mitt"] }},
	//					"grpC" : { "terms" : { "accounts" : ["vladimir", "nigel"] }}
	//				}
	//			}
	//		}
	//	}
	// This method returns only the (outer) { "adjacency_matrix" : {} } part.

	source := make(map[string]interface{})
	adjacencyMatrix := make(map[string]interface{})
	source["adjacency_matrix"] = adjacencyMatrix

	dict := make(map[string]interface{})
	for key, filter := range a.filters {
		src, err := filter.Source()
		if err != nil {
			return nil, err
		}
		dict[key] = src
	}
	adjacencyMatrix["filters"] = dict

	// AggregationBuilder (SubAggregations)
	if len(a.subAggregations) > 0 {
		aggsMap := make(map[string]interface{})
		source["aggregations"] = aggsMap
		for name, aggregate := range a.subAggregations {
			src, err := aggregate.Source()
			if err != nil {
				return nil, err
			}
			aggsMap[name] = src
		}
	}

	// Add Meta data if available
	if len(a.meta) > 0 {
		source["meta"] = a.meta
	}

	return source, nil
}
<|endoftext|>