<commit_before>// Package sub provides the /subscriptions APIs
package sub

import (
	"fmt"
	"strconv"

	stripe "github.com/stripe/stripe-go"
)

const (
	Trialing stripe.SubStatus = "trialing"
	Active   stripe.SubStatus = "active"
	PastDue  stripe.SubStatus = "past_due"
	Canceled stripe.SubStatus = "canceled"
	Unpaid   stripe.SubStatus = "unpaid"
)

// Client is used to invoke /subscriptions APIs.
type Client struct {
	B   stripe.Backend
	Key string
}

// New POSTS a new subscription for a customer.
// For more details see https://stripe.com/docs/api#create_subscription.
func New(params *stripe.SubParams) (*stripe.Sub, error) {
	return getC().New(params)
}

func (c Client) New(params *stripe.SubParams) (*stripe.Sub, error) {
	var body *stripe.RequestValues
	var commonParams *stripe.Params
	token := c.Key

	if params != nil {
		body = &stripe.RequestValues{}
		body.Add("customer", params.Customer)

		if len(params.Items) > 0 {
			for i, item := range params.Items {
				key := fmt.Sprintf("items[%d]", i)
				if len(item.Plan) > 0 {
					body.Add(key+"[plan]", item.Plan)
				}
				if item.Quantity > 0 {
					body.Add(key+"[quantity]", strconv.FormatUint(item.Quantity, 10))
				} else if item.QuantityZero {
					body.Add(key+"[quantity]", "0")
				}
			}
		}

		if len(params.Plan) > 0 {
			body.Add("plan", params.Plan)
		}

		if len(params.Token) > 0 {
			body.Add("card", params.Token)
		} else if params.Card != nil {
			params.Card.AppendDetails(body, true)
		}

		if len(params.Coupon) > 0 {
			body.Add("coupon", params.Coupon)
		}

		if params.TrialPeriod > 0 {
			body.Add("trial_period_days", strconv.FormatInt(params.TrialEnd, 10))
		}

		if params.TrialEndNow {
			body.Add("trial_end", "now")
		} else if params.TrialEnd > 0 {
			body.Add("trial_end", strconv.FormatInt(params.TrialEnd, 10))
		}

		if params.TaxPercent > 0 {
			body.Add("tax_percent", strconv.FormatFloat(params.TaxPercent, 'f', 4, 64))
		} else if params.TaxPercentZero {
			body.Add("tax_percent", "0")
		}

		if params.Quantity > 0 {
			body.Add("quantity", strconv.FormatUint(params.Quantity, 10))
		} else if params.QuantityZero {
			body.Add("quantity", "0")
		}

		if params.FeePercent > 0 {
			body.Add("application_fee_percent", strconv.FormatFloat(params.FeePercent, 'f', 2, 64))
		}

		if params.BillingCycleAnchorNow {
			body.Add("billing_cycle_anchor", "now")
		} else if params.BillingCycleAnchor > 0 {
			body.Add("billing_cycle_anchor", strconv.FormatInt(params.BillingCycleAnchor, 10))
		}

		commonParams = &params.Params

		params.AppendTo(body)
	}

	sub := &stripe.Sub{}
	err := c.B.Call("POST", "/subscriptions", token, body, commonParams, sub)

	return sub, err
}

// Get returns the details of a subscription.
// For more details see https://stripe.com/docs/api#retrieve_subscription.
func Get(id string, params *stripe.SubParams) (*stripe.Sub, error) {
	return getC().Get(id, params)
}

func (c Client) Get(id string, params *stripe.SubParams) (*stripe.Sub, error) {
	var body *stripe.RequestValues
	var commonParams *stripe.Params

	if params != nil {
		body = &stripe.RequestValues{}
		params.AppendTo(body)
		commonParams = &params.Params
	}

	sub := &stripe.Sub{}
	err := c.B.Call("GET", fmt.Sprintf("/subscriptions/%v", id), c.Key, body, commonParams, sub)

	return sub, err
}

// Update updates a subscription's properties.
// For more details see https://stripe.com/docs/api#update_subscription.
func Update(id string, params *stripe.SubParams) (*stripe.Sub, error) {
	return getC().Update(id, params)
}

func (c Client) Update(id string, params *stripe.SubParams) (*stripe.Sub, error) {
	var body *stripe.RequestValues
	var commonParams *stripe.Params
	token := c.Key

	if params != nil {
		body = &stripe.RequestValues{}

		if len(params.Items) > 0 {
			for i, item := range params.Items {
				key := fmt.Sprintf("items[%d]", i)
				if len(item.ID) > 0 {
					body.Add(key+"[id]", item.ID)
				}
				if len(item.Plan) > 0 {
					body.Add(key+"[plan]", item.Plan)
				}
				if item.Quantity > 0 {
					body.Add(key+"[quantity]", strconv.FormatUint(item.Quantity, 10))
				} else if item.QuantityZero {
					body.Add(key+"[quantity]", "0")
				}
			}
		}

		if len(params.Plan) > 0 {
			body.Add("plan", params.Plan)
		}

		if params.NoProrate {
			body.Add("prorate", strconv.FormatBool(false))
		}

		if len(params.Token) > 0 {
			body.Add("card", params.Token)
		} else if params.Card != nil {
			if len(params.Card.Token) > 0 {
				body.Add("card", params.Card.Token)
			} else {
				params.Card.AppendDetails(body, true)
			}
		}

		if len(params.Coupon) > 0 {
			body.Add("coupon", params.Coupon)
		}

		if params.TrialEndNow {
			body.Add("trial_end", "now")
		} else if params.TrialEnd > 0 {
			body.Add("trial_end", strconv.FormatInt(params.TrialEnd, 10))
		}

		if params.Quantity > 0 {
			body.Add("quantity", strconv.FormatUint(params.Quantity, 10))
		} else if params.QuantityZero {
			body.Add("quantity", "0")
		}

		if params.FeePercent > 0 {
			body.Add("application_fee_percent", strconv.FormatFloat(params.FeePercent, 'f', 2, 64))
		}

		if params.TaxPercent > 0 {
			body.Add("tax_percent", strconv.FormatFloat(params.TaxPercent, 'f', 4, 64))
		} else if params.TaxPercentZero {
			body.Add("tax_percent", "0")
		}

		if params.ProrationDate > 0 {
			body.Add("proration_date", strconv.FormatInt(params.ProrationDate, 10))
		}

		commonParams = &params.Params
		params.AppendTo(body)
	}

	sub := &stripe.Sub{}
	err := c.B.Call("POST", fmt.Sprintf("/subscriptions/%v", id), token, body, commonParams, sub)

	return sub, err
}

// Cancel removes a subscription.
// For more details see https://stripe.com/docs/api#cancel_subscription.
func Cancel(id string, params *stripe.SubParams) (*stripe.Sub, error) {
	return getC().Cancel(id, params)
}

func (c Client) Cancel(id string, params *stripe.SubParams) (*stripe.Sub, error) {
	var body *stripe.RequestValues
	var commonParams *stripe.Params

	if params != nil {
		body = &stripe.RequestValues{}

		if params.EndCancel {
			body.Add("at_period_end", strconv.FormatBool(true))
		}

		params.AppendTo(body)
		commonParams = &params.Params
	}

	sub := &stripe.Sub{}
	err := c.B.Call("DELETE", fmt.Sprintf("/subscriptions/%v", id), c.Key, body, commonParams, sub)

	return sub, err
}

// List returns a list of subscriptions.
// For more details see https://stripe.com/docs/api#list_subscriptions.
func List(params *stripe.SubListParams) *Iter {
	return getC().List(params)
}

func (c Client) List(params *stripe.SubListParams) *Iter {
	var body *stripe.RequestValues
	var lp *stripe.ListParams
	var p *stripe.Params

	if params != nil {
		body = &stripe.RequestValues{}

		if len(params.Customer) > 0 {
			body.Add("customer", params.Customer)
		}

		if len(params.Plan) > 0 {
			body.Add("plan", params.Plan)
		}

		if len(params.Status) > 0 {
			body.Add("status", string(params.Status))
		}

		params.AppendTo(body)

		lp = &params.ListParams
		p = params.ToParams()
	}

	return &Iter{stripe.GetIter(lp, body, func(b *stripe.RequestValues) ([]interface{}, stripe.ListMeta, error) {
		list := &stripe.SubList{}
		err := c.B.Call("GET", "/subscriptions", c.Key, b, p, list)

		ret := make([]interface{}, len(list.Values))
		for i, v := range list.Values {
			ret[i] = v
		}

		return ret, list.ListMeta, err
	})}
}

// Iter is an iterator for lists of Subs.
// The embedded Iter carries methods with it;
// see its documentation for details.
type Iter struct {
	*stripe.Iter
}

// Sub returns the most recent Sub
// visited by a call to Next.
func (i *Iter) Sub() *stripe.Sub {
	return i.Current().(*stripe.Sub)
}

func getC() Client {
	return Client{stripe.GetBackend(stripe.APIBackend), stripe.Key}
}
<commit_msg>sub: fix the TrialPeriod param to use the proper value<commit_after>// Package sub provides the /subscriptions APIs
package sub

import (
	"fmt"
	"strconv"

	stripe "github.com/stripe/stripe-go"
)

const (
	Trialing stripe.SubStatus = "trialing"
	Active   stripe.SubStatus = "active"
	PastDue  stripe.SubStatus = "past_due"
	Canceled stripe.SubStatus = "canceled"
	Unpaid   stripe.SubStatus = "unpaid"
)

// Client is used to invoke /subscriptions APIs.
type Client struct {
	B   stripe.Backend
	Key string
}

// New POSTS a new subscription for a customer.
// For more details see https://stripe.com/docs/api#create_subscription.
func New(params *stripe.SubParams) (*stripe.Sub, error) {
	return getC().New(params)
}

func (c Client) New(params *stripe.SubParams) (*stripe.Sub, error) {
	var body *stripe.RequestValues
	var commonParams *stripe.Params
	token := c.Key

	if params != nil {
		body = &stripe.RequestValues{}
		body.Add("customer", params.Customer)

		if len(params.Items) > 0 {
			for i, item := range params.Items {
				key := fmt.Sprintf("items[%d]", i)
				if len(item.Plan) > 0 {
					body.Add(key+"[plan]", item.Plan)
				}
				if item.Quantity > 0 {
					body.Add(key+"[quantity]", strconv.FormatUint(item.Quantity, 10))
				} else if item.QuantityZero {
					body.Add(key+"[quantity]", "0")
				}
			}
		}

		if len(params.Plan) > 0 {
			body.Add("plan", params.Plan)
		}

		if len(params.Token) > 0 {
			body.Add("card", params.Token)
		} else if params.Card != nil {
			params.Card.AppendDetails(body, true)
		}

		if len(params.Coupon) > 0 {
			body.Add("coupon", params.Coupon)
		}

		if params.TrialPeriod > 0 {
			body.Add("trial_period_days", strconv.FormatInt(params.TrialPeriod, 10))
		}

		if params.TrialEndNow {
			body.Add("trial_end", "now")
		} else if params.TrialEnd > 0 {
			body.Add("trial_end", strconv.FormatInt(params.TrialEnd, 10))
		}

		if params.TaxPercent > 0 {
			body.Add("tax_percent", strconv.FormatFloat(params.TaxPercent, 'f', 4, 64))
		} else if params.TaxPercentZero {
			body.Add("tax_percent", "0")
		}

		if params.Quantity > 0 {
			body.Add("quantity", strconv.FormatUint(params.Quantity, 10))
		} else if params.QuantityZero {
			body.Add("quantity", "0")
		}

		if params.FeePercent > 0 {
			body.Add("application_fee_percent", strconv.FormatFloat(params.FeePercent, 'f', 2, 64))
		}

		if params.BillingCycleAnchorNow {
			body.Add("billing_cycle_anchor", "now")
		} else if params.BillingCycleAnchor > 0 {
			body.Add("billing_cycle_anchor", strconv.FormatInt(params.BillingCycleAnchor, 10))
		}

		commonParams = &params.Params

		params.AppendTo(body)
	}

	sub := &stripe.Sub{}
	err := c.B.Call("POST", "/subscriptions", token, body, commonParams, sub)

	return sub, err
}

// Get returns the details of a subscription.
// For more details see https://stripe.com/docs/api#retrieve_subscription.
func Get(id string, params *stripe.SubParams) (*stripe.Sub, error) {
	return getC().Get(id, params)
}

func (c Client) Get(id string, params *stripe.SubParams) (*stripe.Sub, error) {
	var body *stripe.RequestValues
	var commonParams *stripe.Params

	if params != nil {
		body = &stripe.RequestValues{}
		params.AppendTo(body)
		commonParams = &params.Params
	}

	sub := &stripe.Sub{}
	err := c.B.Call("GET", fmt.Sprintf("/subscriptions/%v", id), c.Key, body, commonParams, sub)

	return sub, err
}

// Update updates a subscription's properties.
// For more details see https://stripe.com/docs/api#update_subscription.
func Update(id string, params *stripe.SubParams) (*stripe.Sub, error) {
	return getC().Update(id, params)
}

func (c Client) Update(id string, params *stripe.SubParams) (*stripe.Sub, error) {
	var body *stripe.RequestValues
	var commonParams *stripe.Params
	token := c.Key

	if params != nil {
		body = &stripe.RequestValues{}

		if len(params.Items) > 0 {
			for i, item := range params.Items {
				key := fmt.Sprintf("items[%d]", i)
				if len(item.ID) > 0 {
					body.Add(key+"[id]", item.ID)
				}
				if len(item.Plan) > 0 {
					body.Add(key+"[plan]", item.Plan)
				}
				if item.Quantity > 0 {
					body.Add(key+"[quantity]", strconv.FormatUint(item.Quantity, 10))
				} else if item.QuantityZero {
					body.Add(key+"[quantity]", "0")
				}
			}
		}

		if len(params.Plan) > 0 {
			body.Add("plan", params.Plan)
		}

		if params.NoProrate {
			body.Add("prorate", strconv.FormatBool(false))
		}

		if len(params.Token) > 0 {
			body.Add("card", params.Token)
		} else if params.Card != nil {
			if len(params.Card.Token) > 0 {
				body.Add("card", params.Card.Token)
			} else {
				params.Card.AppendDetails(body, true)
			}
		}

		if len(params.Coupon) > 0 {
			body.Add("coupon", params.Coupon)
		}

		if params.TrialEndNow {
			body.Add("trial_end", "now")
		} else if params.TrialEnd > 0 {
			body.Add("trial_end", strconv.FormatInt(params.TrialEnd, 10))
		}

		if params.Quantity > 0 {
			body.Add("quantity", strconv.FormatUint(params.Quantity, 10))
		} else if params.QuantityZero {
			body.Add("quantity", "0")
		}

		if params.FeePercent > 0 {
			body.Add("application_fee_percent", strconv.FormatFloat(params.FeePercent, 'f', 2, 64))
		}

		if params.TaxPercent > 0 {
			body.Add("tax_percent", strconv.FormatFloat(params.TaxPercent, 'f', 4, 64))
		} else if params.TaxPercentZero {
			body.Add("tax_percent", "0")
		}

		if params.ProrationDate > 0 {
			body.Add("proration_date", strconv.FormatInt(params.ProrationDate, 10))
		}

		commonParams = &params.Params
		params.AppendTo(body)
	}

	sub := &stripe.Sub{}
	err := c.B.Call("POST", fmt.Sprintf("/subscriptions/%v", id), token, body, commonParams, sub)

	return sub, err
}

// Cancel removes a subscription.
// For more details see https://stripe.com/docs/api#cancel_subscription.
func Cancel(id string, params *stripe.SubParams) (*stripe.Sub, error) {
	return getC().Cancel(id, params)
}

func (c Client) Cancel(id string, params *stripe.SubParams) (*stripe.Sub, error) {
	var body *stripe.RequestValues
	var commonParams *stripe.Params

	if params != nil {
		body = &stripe.RequestValues{}

		if params.EndCancel {
			body.Add("at_period_end", strconv.FormatBool(true))
		}

		params.AppendTo(body)
		commonParams = &params.Params
	}

	sub := &stripe.Sub{}
	err := c.B.Call("DELETE", fmt.Sprintf("/subscriptions/%v", id), c.Key, body, commonParams, sub)

	return sub, err
}

// List returns a list of subscriptions.
// For more details see https://stripe.com/docs/api#list_subscriptions.
func List(params *stripe.SubListParams) *Iter {
	return getC().List(params)
}

func (c Client) List(params *stripe.SubListParams) *Iter {
	var body *stripe.RequestValues
	var lp *stripe.ListParams
	var p *stripe.Params

	if params != nil {
		body = &stripe.RequestValues{}

		if len(params.Customer) > 0 {
			body.Add("customer", params.Customer)
		}

		if len(params.Plan) > 0 {
			body.Add("plan", params.Plan)
		}

		if len(params.Status) > 0 {
			body.Add("status", string(params.Status))
		}

		params.AppendTo(body)

		lp = &params.ListParams
		p = params.ToParams()
	}

	return &Iter{stripe.GetIter(lp, body, func(b *stripe.RequestValues) ([]interface{}, stripe.ListMeta, error) {
		list := &stripe.SubList{}
		err := c.B.Call("GET", "/subscriptions", c.Key, b, p, list)

		ret := make([]interface{}, len(list.Values))
		for i, v := range list.Values {
			ret[i] = v
		}

		return ret, list.ListMeta, err
	})}
}

// Iter is an iterator for lists of Subs.
// The embedded Iter carries methods with it;
// see its documentation for details.
type Iter struct {
	*stripe.Iter
}

// Sub returns the most recent Sub
// visited by a call to Next.
func (i *Iter) Sub() *stripe.Sub {
	return i.Current().(*stripe.Sub)
}

func getC() Client {
	return Client{stripe.GetBackend(stripe.APIBackend), stripe.Key}
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"net/http"
)

// synthesizeResponse calls middleware to populate response data, nothing gets pass proxy
func synthesizeResponse(req *http.Request, middleware string) *http.Response {

	b := bufio.NewScanner(req.Body)

	bodyStr := b.Text()

	request := requestDetails{
		Path:        req.URL.Path,
		Method:      req.Method,
		Destination: req.Host,
		Query:       req.URL.RawQuery,
		Body:        bodyStr,
		RemoteAddr:  req.RemoteAddr,
		Headers:     req.Header,
	}
	payload := Payload{Request: request}

	c := NewConstructor(req, payload)

	if middleware != "" {
		err := c.ApplyMiddleware(middleware)
		if err != nil {
			var errorPayload Payload
			errorPayload.Response.Status = 503
			errorPayload.Response.Body = fmt.Sprintf("Middleware error: %s", err.Error())
			c.payload = errorPayload
		}
	} else {
		c.payload.Response.Body = "Precondition failed: middleware not provided."
		c.payload.Response.Status = 428
	}

	response := c.reconstructResponse()
	return response

}
<commit_msg>more logging, correct reading<commit_after>package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"

	log "github.com/Sirupsen/logrus"
)

// synthesizeResponse calls middleware to populate response data, nothing gets pass proxy
func synthesizeResponse(req *http.Request, middleware string) *http.Response {

	// this is mainly for testing, since when you create
	if req.Body == nil {
		req.Body = ioutil.NopCloser(bytes.NewBuffer([]byte("")))
	}
	responseBody, err := ioutil.ReadAll(req.Body)
	req.Body.Close()

	var bodyStr string
	if err != nil {
		log.WithFields(log.Fields{
			"middleware": middleware,
			"error":      err.Error(),
		}).Error("Failed to read request body when synthesizing response")
	} else {
		bodyStr = string(responseBody)
	}

	request := requestDetails{
		Path:        req.URL.Path,
		Method:      req.Method,
		Destination: req.Host,
		Query:       req.URL.RawQuery,
		Body:        bodyStr,
		RemoteAddr:  req.RemoteAddr,
		Headers:     req.Header,
	}
	payload := Payload{Request: request}

	log.WithFields(log.Fields{
		"middleware":  middleware,
		"body":        bodyStr,
		"destination": request.Destination,
	}).Debug("Synthesizing new response")

	c := NewConstructor(req, payload)

	if middleware != "" {
		err := c.ApplyMiddleware(middleware)
		if err != nil {
			var errorPayload Payload
			errorPayload.Response.Status = 503
			errorPayload.Response.Body = fmt.Sprintf("Middleware error: %s", err.Error())
			c.payload = errorPayload
		}
	} else {
		c.payload.Response.Body = "Precondition failed: middleware not provided."
		c.payload.Response.Status = 428
	}

	response := c.reconstructResponse()
	return response

}
<|endoftext|>


<commit_before>package model

import (
	"crypto/sha256"
	"encoding/base64"
	"errors"
	"strconv"
	"strings"
)

type Password string

func (self *Password) Get() string {
	return string(*self)
}

func (self *Password) Set(value string) {
	*self = Password(value)
}

// todo salt
func (self *Password) SetHashed(value string) {
	self.Set(PasswordHash(value))
}

func (self *Password) EqualsHashed(value string) bool {
	return self.Get() == PasswordHash(value)
}

func (self *Password) IsEmpty() bool {
	return len(*self) == 0
}

func (self *Password) String() string {
	return self.Get()
}

func (self *Password) SetString(str string) error {
	self.Set(str)
	return nil
}

func (self *Password) FixValue(metaData *MetaData) {
}

func (self *Password) Required(metaData *MetaData) bool {
	if minlen, ok, _ := self.Minlen(metaData); ok {
		if minlen > 0 {
			return true
		}
	}
	return metaData.BoolAttrib(StructTagKey, "required")
}

func (self *Password) Validate(metaData *MetaData) error {
	value := string(*self)

	pos := strings.IndexAny(value, "\n\r")
	if pos != -1 {
		return errors.New("Line breaks not allowed")
	}

	if self.Required(metaData) && self.IsEmpty() {
		return NewRequiredError(metaData)
	}

	minlen, ok, err := self.Minlen(metaData)
	if ok && len(value) < minlen {
		err = &StringTooShort{value, minlen}
	}
	if err != nil {
		return err
	}

	maxlen, ok, err := self.Maxlen(metaData)
	if ok && len(value) > maxlen {
		err = &StringTooLong{value, maxlen}
	}
	if err != nil {
		return err
	}

	return nil
}

func (self *Password) Minlen(metaData *MetaData) (minlen int, ok bool, err error) {
	var str string
	if str, ok = metaData.Attrib(StructTagKey, "minlen"); ok {
		minlen, err = strconv.Atoi(str)
		ok = err == nil
	}
	return minlen, ok, err
}

func (self *Password) Maxlen(metaData *MetaData) (maxlen int, ok bool, err error) {
	var str string
	if str, ok = metaData.Attrib(StructTagKey, "maxlen"); ok {
		maxlen, err = strconv.Atoi(str)
		ok = err == nil
	}
	return maxlen, ok, err
}

func PasswordHash(password string) (hash string) {
	sha := sha256.New()
	sha.Write([]byte(password))
	return base64.StdEncoding.EncodeToString(sha.Sum(nil))
}
<commit_msg>added password generation to model/password<commit_after>package model

import (
	"crypto/sha256"
	"encoding/base64"
	"errors"
	"strconv"
	"strings"
	"crypto/rand"
	"io"
)

type Password string

func (self *Password) Get() string {
	return string(*self)
}

func (self *Password) Set(value string) {
	*self = Password(value)
}

// todo salt
func (self *Password) SetHashed(value string) {
	self.Set(PasswordHash(value))
}

func (self *Password) EqualsHashed(value string) bool {
	return self.Get() == PasswordHash(value)
}

func (self *Password) IsEmpty() bool {
	return len(*self) == 0
}

func (self *Password) String() string {
	return self.Get()
}

func (self *Password) SetString(str string) error {
	self.Set(str)
	return nil
}

func (self *Password) FixValue(metaData *MetaData) {
}

func (self *Password) Required(metaData *MetaData) bool {
	if minlen, ok, _ := self.Minlen(metaData); ok {
		if minlen > 0 {
			return true
		}
	}
	return metaData.BoolAttrib(StructTagKey, "required")
}

func (self *Password) Validate(metaData *MetaData) error {
	value := string(*self)

	pos := strings.IndexAny(value, "\n\r")
	if pos != -1 {
		return errors.New("Line breaks not allowed")
	}

	if self.Required(metaData) && self.IsEmpty() {
		return NewRequiredError(metaData)
	}

	minlen, ok, err := self.Minlen(metaData)
	if ok && len(value) < minlen {
		err = &StringTooShort{value, minlen}
	}
	if err != nil {
		return err
	}

	maxlen, ok, err := self.Maxlen(metaData)
	if ok && len(value) > maxlen {
		err = &StringTooLong{value, maxlen}
	}
	if err != nil {
		return err
	}

	return nil
}

func (self *Password) Minlen(metaData *MetaData) (minlen int, ok bool, err error) {
	var str string
	if str, ok = metaData.Attrib(StructTagKey, "minlen"); ok {
		minlen, err = strconv.Atoi(str)
		ok = err == nil
	}
	return minlen, ok, err
}

func (self *Password) Maxlen(metaData *MetaData) (maxlen int, ok bool, err error) {
	var str string
	if str, ok = metaData.Attrib(StructTagKey, "maxlen"); ok {
		maxlen, err = strconv.Atoi(str)
		ok = err == nil
	}
	return maxlen, ok, err
}

func PasswordHash(password string) (string) {
	sha := sha256.New()
	sha.Write([]byte(password))
	return base64.StdEncoding.EncodeToString(sha.Sum(nil))
}

func GenerateRandomPassword(length int) (string, error) {
	validChars := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"

	b := make([]byte, length)
	r := make([]byte, length+(length/4))
	clen := byte(len(validChars))
	maxrb := byte(256 - (256 % len(validChars)))
	i := 0
	for {
		if _, err := io.ReadFull(rand.Reader, r); err != nil {
			return "", errors.New("error reading from random source: " + err.Error())
		}
		for _, c := range r {
			if c >= maxrb {
				continue
			}
			b[i] = validChars[c%clen]
			i++
			if i == length {
				return string(b), nil
			}
		}
	}
	return "",errors.New("password generation unreachable")

}

<|endoftext|>


<commit_before>package cmd

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
	"testing"

	"path/filepath"

	"github.com/kylelemons/godebug/diff"
)

var Fixtures = os.ExpandEnv("$GOPATH/src/github.com/kedgeproject/kedge/tests/cmd/fixtures/")
var ProjectPath = "$GOPATH/src/github.com/kedgeproject/kedge/"
var BinaryLocation = os.ExpandEnv(ProjectPath + "kedge")
var imagename = "testrun"
var context = "kedge-build/"

func TestKedgeGenerate(t *testing.T) {
	testCases := []struct {
		name        string
		path        string
		input       string
		wantSuccess bool
		error       string
	}{
		{
			name:        "multiple configmaps given and name not specified",
			path:        "multi-configmapname/app.yaml",
			wantSuccess: false,
			error:       "unable to perform controller operations: unable to fix data: unable to fix configMaps: please specify name for app.configMaps[1]",
		},
		{
			name:        "generating deploymentconfig",
			path:        "controllers/input",
			input:       Fixtures + "controllers/os.yaml",
			wantSuccess: true,
		},
		{
			name:        "multiple containers given and name not specified for 2nd contaniner",
			path:        "multi-containername/nginx.yaml",
			wantSuccess: false,
			error:       "unable to perform controller operations: unable to fix data: unable to fix deployments: unable to fix containers: please specify name for app.containers[1]",
		},
		{
			name:  "multiple volume claims with same name",
			path:  "multi-pvc-same-name/app.yaml",
			error: `unable to perform controller operations: unable to validate data: error validating volume claims: duplicate entry of volume claim "foo"`,
		},
	}

	for _, tt := range testCases {
		t.Run(tt.name, func(t *testing.T) {
			command := []string{"generate", "--skip-validation", "-f=" + Fixtures + tt.path}
			stdout, err := runCmd(t, command)
			if err != nil && !tt.wantSuccess {

				if stdout != tt.error {
					t.Fatalf("wanted error: %q\nbut got error: %q %v", tt.error, stdout, err)
				} else {
					t.Logf("failed with error: %q", stdout)
					return
				}
			} else if err != nil && tt.wantSuccess {
				t.Fatalf("wanted success, but test failed with error: %s %v", stdout, err)
			} else if err == nil && !tt.wantSuccess {
				t.Fatalf("expected to fail but passed")
			}

			// Read the data from the input file
			data, err := ioutil.ReadFile(tt.input)
			if err != nil {
				t.Fatal(err)
			}

			if diff := diff.Diff(string(data), fmt.Sprintf("%s\n", stdout)); diff != "" {
				t.Fatalf("wanted: \n%s\n======================\ngot: \n%s"+
					"\n======================\ndiff: %s", string(data), stdout, diff)
			}

		})
	}
}

func runCmd(t *testing.T, args []string) (string, error) {
	cmd := exec.Command(BinaryLocation, args...)

	var stdout bytes.Buffer
	cmd.Stdout = &stdout

	t.Logf("Running: %s", strings.Join(cmd.Args, " "))
	err := cmd.Run()
	if err != nil {
		return strings.TrimSpace(stdout.String()), err
	}
	return strings.TrimSpace(stdout.String()), nil
}

func Test_builderror(t *testing.T) {

	cmdStr := fmt.Sprintf("%s build -i %s -c %s", BinaryLocation, imagename, context)
	output, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
	if err != nil {
		fmt.Println("Error executing command", err)
	}
	cmdStr = fmt.Sprintf("docker images | grep %s | awk '{print $1}'", imagename)
	output, err = exec.Command("/bin/sh", "-c", cmdStr).Output()
	if err != nil {
		fmt.Println("Error executing command", err)
	}
	if strings.TrimSpace(string(output)) != imagename {
		t.Errorf("Test Failed")

	}
}

func Test_stdin(t *testing.T) {

	kjson := `{"name": "httpd","deployments": [{"containers": [{"image": "centos/httpd"}]}]}`
	cmdStr := fmt.Sprintf("%s generate -f - <<EOF\n%s\nEOF\n", BinaryLocation, kjson)
	subproc := exec.Command("/bin/sh", "-c", cmdStr)
	output, err := subproc.Output()
	if err != nil {
		fmt.Println("Error executing command", err)
	}
	g, err := ioutil.ReadFile(Fixtures + "stdin/output.yml")
	if !bytes.Equal(output, g) {
		t.Errorf("Test Failed")
	}
}

func Test_examples(t *testing.T) {
	fileList := []string{}
	for _, dir := range []string{"examples", "docs/examples"} {
		err := filepath.Walk(os.ExpandEnv(ProjectPath)+dir, func(path string, f os.FileInfo, err error) error {
			_, file := filepath.Split(path)
			if filepath.Ext(path) == ".yaml" || filepath.Ext(path) == ".yml" {
				if file != "cronjob.yaml" {
					fileList = append(fileList, path)
				}

			}
			return nil
		})
		if err != nil {
			t.Error(err)
		}
	}

	for _, file := range fileList {
		cmdStr := fmt.Sprintf("%s generate -f %s", BinaryLocation, file)
		output, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
		if err != nil {
			t.Errorf("kedge generate failed for - %s\n Error is - %s", file, output)
		}
	}
}

func Test_init(t *testing.T) {

	//cmdStr := fmt.Sprintf("%s --name httpd --image centos/httpd --ports 80", BinaryLocation)
	svcname := "httpd"
	image := "centos/httpd"
	ports := "80"
	outputFile := os.ExpandEnv(ProjectPath) + "tests/cmd/kedge.yml"

	testCases := []struct {
		name        string
		command     []string
		wantSuccess bool
		error       string
		input       string
	}{
		{
			name:        "kedge init",
			command:     []string{"init"},
			wantSuccess: false,
			error:       "--name and --image are mandatory flags, Please provide these flags",
		},
		{
			name:        "kedge init with name",
			command:     []string{"init", "--name", svcname},
			wantSuccess: false,
			error:       "--name and --image are mandatory flags, Please provide these flags",
		},
		{
			name:        "kedge init with image",
			command:     []string{"init", "--image", image},
			wantSuccess: false,
			error:       "--name and --image are mandatory flags, Please provide these flags",
		},
		{
			name:        "kedge init with ports",
			command:     []string{"init", "--ports", ports},
			wantSuccess: false,
			error:       "--name and --image are mandatory flags, Please provide these flags",
		},
		{
			name:        "kedge init with name & image",
			command:     []string{"init", "--name", svcname, "--image", image},
			wantSuccess: true,
			input:       Fixtures + "init/kedge1.yml",
		},
		{
			name:        "kedge init with name & image & ports",
			command:     []string{"init", "--name", svcname, "--image", image, "--ports", ports},
			wantSuccess: true,
			input:       Fixtures + "init/kedge2.yml",
		},
	}

	for _, tt := range testCases {
		t.Run(tt.name, func(t *testing.T) {

			stdout, err := runCmd(t, tt.command)

			if err != nil && !tt.wantSuccess {
				if stdout != tt.error {
					t.Fatalf("Expected Error %s, But got %s", tt.error, stdout)
				} else {
					t.Logf("failed with error: %q", stdout)
					return
				}
			} else if err != nil && tt.wantSuccess {
				t.Fatalf("wanted success, but test failed with error: %s %v", stdout, err)
			} else if err == nil && !tt.wantSuccess {
				t.Fatalf("expected to fail but passed")
			}
			// Read the data from the input file
			data, err := ioutil.ReadFile(tt.input)
			if err != nil {
				t.Fatal(err, data)
			}

			outputData, err := ioutil.ReadFile(outputFile)
			if err != nil {
				t.Log("File not found")
			}
			if diff := diff.Diff(string(data), string(outputData)); diff != "" {
				t.Fatalf("wanted: \n%s\n======================\ngot: \n%s"+
					"\n======================\ndiff: %s", string(data), string(outputData), diff)
			}

			if _, err := os.Stat(outputFile); err == nil {
				err = os.Remove(outputFile)
				if err != nil {
					t.Log("Error in removing file")
				}
			}
		})
	}

}
<commit_msg>Skipped validation test temporarily<commit_after>package cmd

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
	"testing"

	"path/filepath"

	"github.com/kylelemons/godebug/diff"
)

var Fixtures = os.ExpandEnv("$GOPATH/src/github.com/kedgeproject/kedge/tests/cmd/fixtures/")
var ProjectPath = "$GOPATH/src/github.com/kedgeproject/kedge/"
var BinaryLocation = os.ExpandEnv(ProjectPath + "kedge")
var imagename = "testrun"
var context = "kedge-build/"

func TestKedgeGenerate(t *testing.T) {
	testCases := []struct {
		name        string
		path        string
		input       string
		wantSuccess bool
		error       string
	}{
		{
			name:        "multiple configmaps given and name not specified",
			path:        "multi-configmapname/app.yaml",
			wantSuccess: false,
			error:       "unable to perform controller operations: unable to fix data: unable to fix configMaps: please specify name for app.configMaps[1]",
		},
		{
			name:        "generating deploymentconfig",
			path:        "controllers/input",
			input:       Fixtures + "controllers/os.yaml",
			wantSuccess: true,
		},
		{
			name:        "multiple containers given and name not specified for 2nd contaniner",
			path:        "multi-containername/nginx.yaml",
			wantSuccess: false,
			error:       "unable to perform controller operations: unable to fix data: unable to fix deployments: unable to fix containers: please specify name for app.containers[1]",
		},
		{
			name:  "multiple volume claims with same name",
			path:  "multi-pvc-same-name/app.yaml",
			error: `unable to perform controller operations: unable to validate data: error validating volume claims: duplicate entry of volume claim "foo"`,
		},
	}

	for _, tt := range testCases {
		t.Run(tt.name, func(t *testing.T) {
			command := []string{"generate", "--skip-validation", "-f=" + Fixtures + tt.path}
			stdout, err := runCmd(t, command)
			if err != nil && !tt.wantSuccess {

				if stdout != tt.error {
					t.Fatalf("wanted error: %q\nbut got error: %q %v", tt.error, stdout, err)
				} else {
					t.Logf("failed with error: %q", stdout)
					return
				}
			} else if err != nil && tt.wantSuccess {
				t.Fatalf("wanted success, but test failed with error: %s %v", stdout, err)
			} else if err == nil && !tt.wantSuccess {
				t.Fatalf("expected to fail but passed")
			}

			// Read the data from the input file
			data, err := ioutil.ReadFile(tt.input)
			if err != nil {
				t.Fatal(err)
			}

			if diff := diff.Diff(string(data), fmt.Sprintf("%s\n", stdout)); diff != "" {
				t.Fatalf("wanted: \n%s\n======================\ngot: \n%s"+
					"\n======================\ndiff: %s", string(data), stdout, diff)
			}

		})
	}
}

func runCmd(t *testing.T, args []string) (string, error) {
	cmd := exec.Command(BinaryLocation, args...)

	var stdout bytes.Buffer
	cmd.Stdout = &stdout

	t.Logf("Running: %s", strings.Join(cmd.Args, " "))
	err := cmd.Run()
	if err != nil {
		return strings.TrimSpace(stdout.String()), err
	}
	return strings.TrimSpace(stdout.String()), nil
}

func Test_builderror(t *testing.T) {

	cmdStr := fmt.Sprintf("%s build -i %s -c %s", BinaryLocation, imagename, context)
	output, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
	if err != nil {
		fmt.Println("Error executing command", err)
	}
	cmdStr = fmt.Sprintf("docker images | grep %s | awk '{print $1}'", imagename)
	output, err = exec.Command("/bin/sh", "-c", cmdStr).Output()
	if err != nil {
		fmt.Println("Error executing command", err)
	}
	if strings.TrimSpace(string(output)) != imagename {
		t.Errorf("Test Failed")

	}
}

func Test_stdin(t *testing.T) {

	kjson := `{"name": "httpd","deployments": [{"containers": [{"image": "centos/httpd"}]}]}`
	cmdStr := fmt.Sprintf("%s generate -f - <<EOF\n%s\nEOF\n", BinaryLocation, kjson)
	subproc := exec.Command("/bin/sh", "-c", cmdStr)
	output, err := subproc.Output()
	if err != nil {
		fmt.Println("Error executing command", err)
	}
	g, err := ioutil.ReadFile(Fixtures + "stdin/output.yml")
	if !bytes.Equal(output, g) {
		t.Errorf("Test Failed")
	}
}

func Test_examples(t *testing.T) {
	fileList := []string{}
	for _, dir := range []string{"examples", "docs/examples"} {
		err := filepath.Walk(os.ExpandEnv(ProjectPath)+dir, func(path string, f os.FileInfo, err error) error {
			_, file := filepath.Split(path)
			if filepath.Ext(path) == ".yaml" || filepath.Ext(path) == ".yml" {
				if file != "cronjob.yaml" {
					fileList = append(fileList, path)
				}

			}
			return nil
		})
		if err != nil {
			t.Error(err)
		}
	}

	for _, file := range fileList {
		cmdStr := fmt.Sprintf("%s generate -f %s --skip-validation", BinaryLocation, file)
		output, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
		if err != nil {
			t.Errorf("kedge generate failed for - %s\n Error is - %s", file, output)
		}
	}
}

func Test_init(t *testing.T) {

	//cmdStr := fmt.Sprintf("%s --name httpd --image centos/httpd --ports 80", BinaryLocation)
	svcname := "httpd"
	image := "centos/httpd"
	ports := "80"
	outputFile := os.ExpandEnv(ProjectPath) + "tests/cmd/kedge.yml"

	testCases := []struct {
		name        string
		command     []string
		wantSuccess bool
		error       string
		input       string
	}{
		{
			name:        "kedge init",
			command:     []string{"init"},
			wantSuccess: false,
			error:       "--name and --image are mandatory flags, Please provide these flags",
		},
		{
			name:        "kedge init with name",
			command:     []string{"init", "--name", svcname},
			wantSuccess: false,
			error:       "--name and --image are mandatory flags, Please provide these flags",
		},
		{
			name:        "kedge init with image",
			command:     []string{"init", "--image", image},
			wantSuccess: false,
			error:       "--name and --image are mandatory flags, Please provide these flags",
		},
		{
			name:        "kedge init with ports",
			command:     []string{"init", "--ports", ports},
			wantSuccess: false,
			error:       "--name and --image are mandatory flags, Please provide these flags",
		},
		{
			name:        "kedge init with name & image",
			command:     []string{"init", "--name", svcname, "--image", image},
			wantSuccess: true,
			input:       Fixtures + "init/kedge1.yml",
		},
		{
			name:        "kedge init with name & image & ports",
			command:     []string{"init", "--name", svcname, "--image", image, "--ports", ports},
			wantSuccess: true,
			input:       Fixtures + "init/kedge2.yml",
		},
	}

	for _, tt := range testCases {
		t.Run(tt.name, func(t *testing.T) {

			stdout, err := runCmd(t, tt.command)

			if err != nil && !tt.wantSuccess {
				if stdout != tt.error {
					t.Fatalf("Expected Error %s, But got %s", tt.error, stdout)
				} else {
					t.Logf("failed with error: %q", stdout)
					return
				}
			} else if err != nil && tt.wantSuccess {
				t.Fatalf("wanted success, but test failed with error: %s %v", stdout, err)
			} else if err == nil && !tt.wantSuccess {
				t.Fatalf("expected to fail but passed")
			}
			// Read the data from the input file
			data, err := ioutil.ReadFile(tt.input)
			if err != nil {
				t.Fatal(err, data)
			}

			outputData, err := ioutil.ReadFile(outputFile)
			if err != nil {
				t.Log("File not found")
			}
			if diff := diff.Diff(string(data), string(outputData)); diff != "" {
				t.Fatalf("wanted: \n%s\n======================\ngot: \n%s"+
					"\n======================\ndiff: %s", string(data), string(outputData), diff)
			}

			if _, err := os.Stat(outputFile); err == nil {
				err = os.Remove(outputFile)
				if err != nil {
					t.Log("Error in removing file")
				}
			}
		})
	}

}
<|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 (
	"time"

	expect "github.com/google/goexpect"
	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/extensions/table"
	. "github.com/onsi/gomega"
	k8sv1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	v1 "kubevirt.io/client-go/api/v1"
	"kubevirt.io/client-go/kubecli"
	cdiv1 "kubevirt.io/containerized-data-importer/pkg/apis/core/v1alpha1"
	"kubevirt.io/kubevirt/tests"
	cd "kubevirt.io/kubevirt/tests/containerdisk"
)

var _ = Describe("[Serial][rfe_id:127][posneg:negative][crit:medium][vendor:cnv-qe@redhat.com][level:component]Console", func() {

	var virtClient kubecli.KubevirtClient

	BeforeEach(func() {
		var err error

		virtClient, err = kubecli.GetKubevirtClient()
		tests.PanicOnError(err)

		tests.BeforeTestCleanup()
	})

	RunVMIAndWaitForStart := func(vmi *v1.VirtualMachineInstance) {
		By("Creating a new VirtualMachineInstance")
		Expect(virtClient.RestClient().Post().Resource("virtualmachineinstances").Namespace(tests.NamespaceTestDefault).Body(vmi).Do().Error()).To(Succeed())

		By("Waiting until it starts")
		tests.WaitForSuccessfulVMIStart(vmi)
	}

	ExpectConsoleOutput := func(vmi *v1.VirtualMachineInstance, expected string) {
		By("Expecting the VirtualMachineInstance console")
		expecter, _, err := tests.NewConsoleExpecter(virtClient, vmi, 30*time.Second)
		Expect(err).ToNot(HaveOccurred())
		defer func() {
			By("Closing the opened expecter")
			expecter.Close()
		}()

		By("Checking that the console output equals to expected one")
		_, err = tests.ExpectBatchWithValidatedSend(expecter, []expect.Batcher{
			&expect.BSnd{S: "\n"},
			&expect.BExp{R: expected},
		}, 120*time.Second)
		Expect(err).ToNot(HaveOccurred())
	}

	OpenConsole := func(vmi *v1.VirtualMachineInstance) (expect.Expecter, <-chan error) {
		By("Expecting the VirtualMachineInstance console")
		expecter, errChan, err := tests.NewConsoleExpecter(virtClient, vmi, 30*time.Second)
		Expect(err).ToNot(HaveOccurred())
		return expecter, errChan
	}

	deleteDataVolume := func(dv *cdiv1.DataVolume) {
		if dv != nil {
			By("Deleting the DataVolume")
			ExpectWithOffset(1, virtClient.CdiClient().CdiV1alpha1().DataVolumes(dv.Namespace).Delete(dv.Name, &metav1.DeleteOptions{})).To(Succeed())
		}
	}

	Describe("[rfe_id:127][posneg:negative][crit:medium][vendor:cnv-qe@redhat.com][level:component]A new VirtualMachineInstance", func() {
		Context("with a serial console", func() {
			Context("with a cirros image", func() {

				It("[test_id:1588]should return that we are running cirros", func() {
					vmi := tests.NewRandomVMIWithEphemeralDiskAndUserdata(cd.ContainerDiskFor(cd.ContainerDiskCirros), "#!/bin/bash\necho 'hello'\n")
					RunVMIAndWaitForStart(vmi)
					ExpectConsoleOutput(
						vmi,
						"login as 'cirros' user",
					)
				})
			})

			Context("with a fedora image", func() {
				It("[test_id:1589]should return that we are running fedora", func() {
					vmi := tests.NewRandomVMIWithEphemeralDiskHighMemory(cd.ContainerDiskFor(cd.ContainerDiskFedora))
					RunVMIAndWaitForStart(vmi)
					ExpectConsoleOutput(
						vmi,
						"Welcome to",
					)
				})
			})

			Context("with an alpine image", func() {
				type vmiBuilder func() (*v1.VirtualMachineInstance, *cdiv1.DataVolume)

				newVirtualMachineInstanceWithAlpineContainerDisk := func() (*v1.VirtualMachineInstance, *cdiv1.DataVolume) {
					return tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine)), nil
				}

				newVirtualMachineInstanceWithAlpineOCSFileDisk := func() (*v1.VirtualMachineInstance, *cdiv1.DataVolume) {
					return tests.NewRandomVirtualMachineInstanceWithOCSDisk(tests.GetUrl(tests.AlpineHttpUrl), tests.NamespaceTestDefault, k8sv1.ReadWriteOnce, k8sv1.PersistentVolumeFilesystem)
				}

				newVirtualMachineInstanceWithAlpineOCSBlockDisk := func() (*v1.VirtualMachineInstance, *cdiv1.DataVolume) {
					return tests.NewRandomVirtualMachineInstanceWithOCSDisk(tests.GetUrl(tests.AlpineHttpUrl), tests.NamespaceTestDefault, k8sv1.ReadWriteOnce, k8sv1.PersistentVolumeBlock)
				}

				table.DescribeTable("should return that we are running alpine", func(createVMI vmiBuilder) {
					vmi, dv := createVMI()
					defer deleteDataVolume(dv)
					RunVMIAndWaitForStart(vmi)
					ExpectConsoleOutput(vmi, "login")
				},
					table.Entry("[test_id:4636]with ContainerDisk", newVirtualMachineInstanceWithAlpineContainerDisk),
					table.Entry("[test_id:4637]with OCS Filesystem Disk", newVirtualMachineInstanceWithAlpineOCSFileDisk),
					table.Entry("[test_id:4638]with OCS Block Disk", newVirtualMachineInstanceWithAlpineOCSBlockDisk),
				)
			})

			It("[test_id:1590]should be able to reconnect to console multiple times", func() {
				vmi := tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine))

				RunVMIAndWaitForStart(vmi)

				for i := 0; i < 5; i++ {
					ExpectConsoleOutput(vmi, "login")
				}
			})

			It("[test_id:1591]should close console connection when new console connection is opened", func(done Done) {
				vmi := tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine))

				RunVMIAndWaitForStart(vmi)

				By("opening 1st console connection")
				expecter, errChan := OpenConsole(vmi)
				defer expecter.Close()

				By("expecting error on 1st console connection")
				go func() {
					defer GinkgoRecover()
					select {
					case receivedErr := <-errChan:
						Expect(receivedErr.Error()).To(ContainSubstring("close"))
						close(done)
					case <-time.After(60 * time.Second):
						Fail("timed out waiting for closed 1st connection")
					}
				}()

				By("opening 2nd console connection")
				ExpectConsoleOutput(vmi, "login")
			}, 220)

			It("[test_id:1592]should wait until the virtual machine is in running state and return a stream interface", func() {
				vmi := tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine))
				By("Creating a new VirtualMachineInstance")
				_, err := virtClient.VirtualMachineInstance(tests.NamespaceTestDefault).Create(vmi)
				Expect(err).ToNot(HaveOccurred())

				_, err = virtClient.VirtualMachineInstance(vmi.Namespace).SerialConsole(vmi.Name, &kubecli.SerialConsoleOptions{ConnectionTimeout: 30 * time.Second})
				Expect(err).ToNot(HaveOccurred())
			})

			It("[test_id:1593]should fail waiting for the virtual machine instance to be running", func() {
				vmi := tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine))
				vmi.Spec.Affinity = &k8sv1.Affinity{
					NodeAffinity: &k8sv1.NodeAffinity{
						RequiredDuringSchedulingIgnoredDuringExecution: &k8sv1.NodeSelector{
							NodeSelectorTerms: []k8sv1.NodeSelectorTerm{
								{
									MatchExpressions: []k8sv1.NodeSelectorRequirement{
										{Key: "kubernetes.io/hostname", Operator: k8sv1.NodeSelectorOpIn, Values: []string{"notexist"}},
									},
								},
							},
						},
					},
				}

				By("Creating a new VirtualMachineInstance")
				Expect(virtClient.RestClient().Post().Resource("virtualmachineinstances").Namespace(tests.NamespaceTestDefault).Body(vmi).Do().Error()).To(Succeed())

				_, err := virtClient.VirtualMachineInstance(vmi.Namespace).SerialConsole(vmi.Name, &kubecli.SerialConsoleOptions{ConnectionTimeout: 30 * time.Second})
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(Equal("Timeout trying to connect to the virtual machine instance"))
			})

			It("[test_id:1594]should fail waiting for the expecter", func() {
				vmi := tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine))
				vmi.Spec.Affinity = &k8sv1.Affinity{
					NodeAffinity: &k8sv1.NodeAffinity{
						RequiredDuringSchedulingIgnoredDuringExecution: &k8sv1.NodeSelector{
							NodeSelectorTerms: []k8sv1.NodeSelectorTerm{
								{
									MatchExpressions: []k8sv1.NodeSelectorRequirement{
										{Key: "kubernetes.io/hostname", Operator: k8sv1.NodeSelectorOpIn, Values: []string{"notexist"}},
									},
								},
							},
						},
					},
				}

				By("Creating a new VirtualMachineInstance")
				Expect(virtClient.RestClient().Post().Resource("virtualmachineinstances").Namespace(tests.NamespaceTestDefault).Body(vmi).Do().Error()).To(Succeed())

				By("Expecting the VirtualMachineInstance console")
				_, _, err := tests.NewConsoleExpecter(virtClient, vmi, 30*time.Second)
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(Equal("Timeout trying to connect to the virtual machine instance"))
			})
		})

		Context("without a serial console", func() {
			var vmi *v1.VirtualMachineInstance

			BeforeEach(func() {
				vmi = tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine))
				f := false
				vmi.Spec.Domain.Devices.AutoattachSerialConsole = &f
			})

			It("[test_id:4116]should create the vmi without any issue", func() {
				tests.RunVMIAndExpectLaunch(vmi, 30)
			})

			It("[test_id:4117]should not have the  serial console in xml", func() {
				tests.RunVMIAndExpectLaunch(vmi, 30)

				runningVMISpec, err := tests.GetRunningVMIDomainSpec(vmi)
				Expect(err).ToNot(HaveOccurred(), "should get vmi spec without problem")

				Expect(len(runningVMISpec.Devices.Serials)).To(Equal(0), "should not have any serial consoles present")
				Expect(len(runningVMISpec.Devices.Consoles)).To(Equal(0), "should not have any virtio console for serial consoles")
			})

			It("[test_id:4118]should not connect to the serial console", func() {
				vmi = tests.RunVMIAndExpectLaunch(vmi, 30)

				_, err := virtClient.VirtualMachineInstance(vmi.ObjectMeta.Namespace).SerialConsole(vmi.ObjectMeta.Name, &kubecli.SerialConsoleOptions{})

				Expect(err.Error()).To(Equal("No serial consoles are present."), "serial console should not connect if there are no serial consoles present")
			})
		})
	})
})
<commit_msg>Allow console tests to run in parallel<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 (
	"time"

	expect "github.com/google/goexpect"
	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/extensions/table"
	. "github.com/onsi/gomega"
	k8sv1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	v1 "kubevirt.io/client-go/api/v1"
	"kubevirt.io/client-go/kubecli"
	cdiv1 "kubevirt.io/containerized-data-importer/pkg/apis/core/v1alpha1"
	"kubevirt.io/kubevirt/tests"
	cd "kubevirt.io/kubevirt/tests/containerdisk"
)

var _ = Describe("[rfe_id:127][posneg:negative][crit:medium][vendor:cnv-qe@redhat.com][level:component]Console", func() {

	var virtClient kubecli.KubevirtClient

	BeforeEach(func() {
		var err error

		virtClient, err = kubecli.GetKubevirtClient()
		tests.PanicOnError(err)

		tests.BeforeTestCleanup()
	})

	RunVMIAndWaitForStart := func(vmi *v1.VirtualMachineInstance) {
		By("Creating a new VirtualMachineInstance")
		Expect(virtClient.RestClient().Post().Resource("virtualmachineinstances").Namespace(tests.NamespaceTestDefault).Body(vmi).Do().Error()).To(Succeed())

		By("Waiting until it starts")
		tests.WaitForSuccessfulVMIStart(vmi)
	}

	ExpectConsoleOutput := func(vmi *v1.VirtualMachineInstance, expected string) {
		By("Expecting the VirtualMachineInstance console")
		expecter, _, err := tests.NewConsoleExpecter(virtClient, vmi, 30*time.Second)
		Expect(err).ToNot(HaveOccurred())
		defer func() {
			By("Closing the opened expecter")
			expecter.Close()
		}()

		By("Checking that the console output equals to expected one")
		_, err = tests.ExpectBatchWithValidatedSend(expecter, []expect.Batcher{
			&expect.BSnd{S: "\n"},
			&expect.BExp{R: expected},
		}, 120*time.Second)
		Expect(err).ToNot(HaveOccurred())
	}

	OpenConsole := func(vmi *v1.VirtualMachineInstance) (expect.Expecter, <-chan error) {
		By("Expecting the VirtualMachineInstance console")
		expecter, errChan, err := tests.NewConsoleExpecter(virtClient, vmi, 30*time.Second)
		Expect(err).ToNot(HaveOccurred())
		return expecter, errChan
	}

	deleteDataVolume := func(dv *cdiv1.DataVolume) {
		if dv != nil {
			By("Deleting the DataVolume")
			ExpectWithOffset(1, virtClient.CdiClient().CdiV1alpha1().DataVolumes(dv.Namespace).Delete(dv.Name, &metav1.DeleteOptions{})).To(Succeed())
		}
	}

	Describe("[rfe_id:127][posneg:negative][crit:medium][vendor:cnv-qe@redhat.com][level:component]A new VirtualMachineInstance", func() {
		Context("with a serial console", func() {
			Context("with a cirros image", func() {

				It("[test_id:1588]should return that we are running cirros", func() {
					vmi := tests.NewRandomVMIWithEphemeralDiskAndUserdata(cd.ContainerDiskFor(cd.ContainerDiskCirros), "#!/bin/bash\necho 'hello'\n")
					RunVMIAndWaitForStart(vmi)
					ExpectConsoleOutput(
						vmi,
						"login as 'cirros' user",
					)
				})
			})

			Context("[Serial]with a fedora image", func() {
				It("[test_id:1589]should return that we are running fedora", func() {
					vmi := tests.NewRandomVMIWithEphemeralDiskHighMemory(cd.ContainerDiskFor(cd.ContainerDiskFedora))
					RunVMIAndWaitForStart(vmi)
					ExpectConsoleOutput(
						vmi,
						"Welcome to",
					)
				})
			})

			Context("with an alpine image", func() {
				type vmiBuilder func() (*v1.VirtualMachineInstance, *cdiv1.DataVolume)

				newVirtualMachineInstanceWithAlpineContainerDisk := func() (*v1.VirtualMachineInstance, *cdiv1.DataVolume) {
					return tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine)), nil
				}

				newVirtualMachineInstanceWithAlpineOCSFileDisk := func() (*v1.VirtualMachineInstance, *cdiv1.DataVolume) {
					return tests.NewRandomVirtualMachineInstanceWithOCSDisk(tests.GetUrl(tests.AlpineHttpUrl), tests.NamespaceTestDefault, k8sv1.ReadWriteOnce, k8sv1.PersistentVolumeFilesystem)
				}

				newVirtualMachineInstanceWithAlpineOCSBlockDisk := func() (*v1.VirtualMachineInstance, *cdiv1.DataVolume) {
					return tests.NewRandomVirtualMachineInstanceWithOCSDisk(tests.GetUrl(tests.AlpineHttpUrl), tests.NamespaceTestDefault, k8sv1.ReadWriteOnce, k8sv1.PersistentVolumeBlock)
				}

				table.DescribeTable("should return that we are running alpine", func(createVMI vmiBuilder) {
					vmi, dv := createVMI()
					defer deleteDataVolume(dv)
					RunVMIAndWaitForStart(vmi)
					ExpectConsoleOutput(vmi, "login")
				},
					table.Entry("[test_id:4636]with ContainerDisk", newVirtualMachineInstanceWithAlpineContainerDisk),
					table.Entry("[test_id:4637]with OCS Filesystem Disk", newVirtualMachineInstanceWithAlpineOCSFileDisk),
					table.Entry("[test_id:4638]with OCS Block Disk", newVirtualMachineInstanceWithAlpineOCSBlockDisk),
				)
			})

			It("[test_id:1590]should be able to reconnect to console multiple times", func() {
				vmi := tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine))

				RunVMIAndWaitForStart(vmi)

				for i := 0; i < 5; i++ {
					ExpectConsoleOutput(vmi, "login")
				}
			})

			It("[test_id:1591]should close console connection when new console connection is opened", func(done Done) {
				vmi := tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine))

				RunVMIAndWaitForStart(vmi)

				By("opening 1st console connection")
				expecter, errChan := OpenConsole(vmi)
				defer expecter.Close()

				By("expecting error on 1st console connection")
				go func() {
					defer GinkgoRecover()
					select {
					case receivedErr := <-errChan:
						Expect(receivedErr.Error()).To(ContainSubstring("close"))
						close(done)
					case <-time.After(60 * time.Second):
						Fail("timed out waiting for closed 1st connection")
					}
				}()

				By("opening 2nd console connection")
				ExpectConsoleOutput(vmi, "login")
			}, 220)

			It("[test_id:1592]should wait until the virtual machine is in running state and return a stream interface", func() {
				vmi := tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine))
				By("Creating a new VirtualMachineInstance")
				_, err := virtClient.VirtualMachineInstance(tests.NamespaceTestDefault).Create(vmi)
				Expect(err).ToNot(HaveOccurred())

				_, err = virtClient.VirtualMachineInstance(vmi.Namespace).SerialConsole(vmi.Name, &kubecli.SerialConsoleOptions{ConnectionTimeout: 30 * time.Second})
				Expect(err).ToNot(HaveOccurred())
			})

			It("[test_id:1593]should fail waiting for the virtual machine instance to be running", func() {
				vmi := tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine))
				vmi.Spec.Affinity = &k8sv1.Affinity{
					NodeAffinity: &k8sv1.NodeAffinity{
						RequiredDuringSchedulingIgnoredDuringExecution: &k8sv1.NodeSelector{
							NodeSelectorTerms: []k8sv1.NodeSelectorTerm{
								{
									MatchExpressions: []k8sv1.NodeSelectorRequirement{
										{Key: "kubernetes.io/hostname", Operator: k8sv1.NodeSelectorOpIn, Values: []string{"notexist"}},
									},
								},
							},
						},
					},
				}

				By("Creating a new VirtualMachineInstance")
				Expect(virtClient.RestClient().Post().Resource("virtualmachineinstances").Namespace(tests.NamespaceTestDefault).Body(vmi).Do().Error()).To(Succeed())

				_, err := virtClient.VirtualMachineInstance(vmi.Namespace).SerialConsole(vmi.Name, &kubecli.SerialConsoleOptions{ConnectionTimeout: 30 * time.Second})
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(Equal("Timeout trying to connect to the virtual machine instance"))
			})

			It("[test_id:1594]should fail waiting for the expecter", func() {
				vmi := tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine))
				vmi.Spec.Affinity = &k8sv1.Affinity{
					NodeAffinity: &k8sv1.NodeAffinity{
						RequiredDuringSchedulingIgnoredDuringExecution: &k8sv1.NodeSelector{
							NodeSelectorTerms: []k8sv1.NodeSelectorTerm{
								{
									MatchExpressions: []k8sv1.NodeSelectorRequirement{
										{Key: "kubernetes.io/hostname", Operator: k8sv1.NodeSelectorOpIn, Values: []string{"notexist"}},
									},
								},
							},
						},
					},
				}

				By("Creating a new VirtualMachineInstance")
				Expect(virtClient.RestClient().Post().Resource("virtualmachineinstances").Namespace(tests.NamespaceTestDefault).Body(vmi).Do().Error()).To(Succeed())

				By("Expecting the VirtualMachineInstance console")
				_, _, err := tests.NewConsoleExpecter(virtClient, vmi, 30*time.Second)
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(Equal("Timeout trying to connect to the virtual machine instance"))
			})
		})

		Context("without a serial console", func() {
			var vmi *v1.VirtualMachineInstance

			BeforeEach(func() {
				vmi = tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine))
				f := false
				vmi.Spec.Domain.Devices.AutoattachSerialConsole = &f
			})

			It("[test_id:4116]should create the vmi without any issue", func() {
				tests.RunVMIAndExpectLaunch(vmi, 30)
			})

			It("[test_id:4117]should not have the  serial console in xml", func() {
				tests.RunVMIAndExpectLaunch(vmi, 30)

				runningVMISpec, err := tests.GetRunningVMIDomainSpec(vmi)
				Expect(err).ToNot(HaveOccurred(), "should get vmi spec without problem")

				Expect(len(runningVMISpec.Devices.Serials)).To(Equal(0), "should not have any serial consoles present")
				Expect(len(runningVMISpec.Devices.Consoles)).To(Equal(0), "should not have any virtio console for serial consoles")
			})

			It("[test_id:4118]should not connect to the serial console", func() {
				vmi = tests.RunVMIAndExpectLaunch(vmi, 30)

				_, err := virtClient.VirtualMachineInstance(vmi.ObjectMeta.Namespace).SerialConsole(vmi.ObjectMeta.Name, &kubecli.SerialConsoleOptions{})

				Expect(err.Error()).To(Equal("No serial consoles are present."), "serial console should not connect if there are no serial consoles present")
			})
		})
	})
})
<|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 (
	"context"
	"time"

	expect "github.com/google/goexpect"
	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/extensions/table"
	. "github.com/onsi/gomega"
	k8sv1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	"kubevirt.io/kubevirt/tests/util"

	v1 "kubevirt.io/api/core/v1"
	"kubevirt.io/client-go/kubecli"
	cdiv1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1"
	"kubevirt.io/kubevirt/tests"
	"kubevirt.io/kubevirt/tests/console"
	cd "kubevirt.io/kubevirt/tests/containerdisk"
	"kubevirt.io/kubevirt/tests/libvmi"
)

var _ = Describe("[rfe_id:127][posneg:negative][crit:medium][vendor:cnv-qe@redhat.com][level:component][sig-compute]Console", func() {

	var virtClient kubecli.KubevirtClient

	BeforeEach(func() {
		var err error

		virtClient, err = kubecli.GetKubevirtClient()
		util.PanicOnError(err)

		tests.BeforeTestCleanup()
	})

	ExpectConsoleOutput := func(vmi *v1.VirtualMachineInstance, expected string) {
		By("Checking that the console output equals to expected one")
		Expect(console.SafeExpectBatch(vmi, []expect.Batcher{
			&expect.BSnd{S: "\n"},
			&expect.BExp{R: expected},
		}, 120)).To(Succeed())
	}

	OpenConsole := func(vmi *v1.VirtualMachineInstance) (expect.Expecter, <-chan error) {
		By("Expecting the VirtualMachineInstance console")
		expecter, errChan, err := console.NewExpecter(virtClient, vmi, 30*time.Second)
		Expect(err).ToNot(HaveOccurred())
		return expecter, errChan
	}

	deleteDataVolume := func(dv *cdiv1.DataVolume) {
		By("Deleting the DataVolume")
		ExpectWithOffset(1, virtClient.CdiClient().CdiV1beta1().DataVolumes(dv.Namespace).Delete(context.Background(), dv.Name, metav1.DeleteOptions{})).To(Succeed(), metav1.DeleteOptions{})
	}

	Describe("[rfe_id:127][posneg:negative][crit:medium][vendor:cnv-qe@redhat.com][level:component]A new VirtualMachineInstance", func() {
		Context("with a serial console", func() {
			Context("with a cirros image", func() {

				It("[test_id:1588]should return that we are running cirros", func() {
					vmi := libvmi.NewCirros()
					vmi = tests.RunVMIAndExpectLaunch(vmi, 30)
					ExpectConsoleOutput(
						vmi,
						"login as 'cirros' user",
					)
				})
			})

			Context("with a fedora image", func() {
				It("[sig-compute][test_id:1589]should return that we are running fedora", func() {
					vmi := libvmi.NewFedora()
					vmi = tests.RunVMIAndExpectLaunch(vmi, 30)
					ExpectConsoleOutput(
						vmi,
						"Welcome to",
					)
				})
			})

			Context("with an alpine image", func() {
				type vmiBuilder func() (*v1.VirtualMachineInstance, *cdiv1.DataVolume)

				newVirtualMachineInstanceWithAlpineFileDisk := func() (*v1.VirtualMachineInstance, *cdiv1.DataVolume) {
					return tests.NewRandomVirtualMachineInstanceWithFileDisk(cd.DataVolumeImportUrlForContainerDisk(cd.ContainerDiskAlpine), util.NamespaceTestDefault, k8sv1.ReadWriteOnce)
				}

				newVirtualMachineInstanceWithAlpineBlockDisk := func() (*v1.VirtualMachineInstance, *cdiv1.DataVolume) {
					return tests.NewRandomVirtualMachineInstanceWithBlockDisk(cd.DataVolumeImportUrlForContainerDisk(cd.ContainerDiskAlpine), util.NamespaceTestDefault, k8sv1.ReadWriteOnce)
				}

				table.DescribeTable("should return that we are running alpine", func(createVMI vmiBuilder) {
					vmi, dv := createVMI()
					defer deleteDataVolume(dv)
					vmi = tests.RunVMIAndExpectLaunch(vmi, 30)
					ExpectConsoleOutput(vmi, "login")
				},
					table.Entry("[test_id:4637][storage-req]with Filesystem Disk", newVirtualMachineInstanceWithAlpineFileDisk),
					table.Entry("[test_id:4638][storage-req]with Block Disk", newVirtualMachineInstanceWithAlpineBlockDisk),
				)
			})

			It("[test_id:1590]should be able to reconnect to console multiple times", func() {
				vmi := libvmi.NewAlpine()
				vmi = tests.RunVMIAndExpectLaunch(vmi, 30)

				for i := 0; i < 5; i++ {
					ExpectConsoleOutput(vmi, "login")
				}
			})

			It("[test_id:1591]should close console connection when new console connection is opened", func(done Done) {
				vmi := libvmi.NewAlpine()
				vmi = tests.RunVMIAndExpectLaunch(vmi, 30)

				By("opening 1st console connection")
				expecter, errChan := OpenConsole(vmi)
				defer expecter.Close()

				By("expecting error on 1st console connection")
				go func() {
					defer GinkgoRecover()
					select {
					case receivedErr := <-errChan:
						Expect(receivedErr.Error()).To(ContainSubstring("close"))
						close(done)
					case <-time.After(60 * time.Second):
						Fail("timed out waiting for closed 1st connection")
					}
				}()

				By("opening 2nd console connection")
				ExpectConsoleOutput(vmi, "login")
			}, 220)

			It("[test_id:1592]should wait until the virtual machine is in running state and return a stream interface", func() {
				vmi := libvmi.NewAlpine()
				By("Creating a new VirtualMachineInstance")
				vmi, err := virtClient.VirtualMachineInstance(util.NamespaceTestDefault).Create(vmi)
				Expect(err).ToNot(HaveOccurred())

				_, err = virtClient.VirtualMachineInstance(vmi.Namespace).SerialConsole(vmi.Name, &kubecli.SerialConsoleOptions{ConnectionTimeout: 30 * time.Second})
				Expect(err).ToNot(HaveOccurred())
			})

			It("[test_id:1593]should fail waiting for the virtual machine instance to be running", func() {
				vmi := libvmi.NewAlpine()
				vmi.Spec.Affinity = &k8sv1.Affinity{
					NodeAffinity: &k8sv1.NodeAffinity{
						RequiredDuringSchedulingIgnoredDuringExecution: &k8sv1.NodeSelector{
							NodeSelectorTerms: []k8sv1.NodeSelectorTerm{
								{
									MatchExpressions: []k8sv1.NodeSelectorRequirement{
										{Key: "kubernetes.io/hostname", Operator: k8sv1.NodeSelectorOpIn, Values: []string{"notexist"}},
									},
								},
							},
						},
					},
				}

				By("Creating a new VirtualMachineInstance")
				vmi, err := virtClient.VirtualMachineInstance(util.NamespaceTestDefault).Create(vmi)
				Expect(err).ToNot(HaveOccurred())

				_, err = virtClient.VirtualMachineInstance(vmi.Namespace).SerialConsole(vmi.Name, &kubecli.SerialConsoleOptions{ConnectionTimeout: 30 * time.Second})
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(Equal("Timeout trying to connect to the virtual machine instance"))
			})

			It("[test_id:1594]should fail waiting for the expecter", func() {
				vmi := libvmi.NewAlpine()
				vmi.Spec.Affinity = &k8sv1.Affinity{
					NodeAffinity: &k8sv1.NodeAffinity{
						RequiredDuringSchedulingIgnoredDuringExecution: &k8sv1.NodeSelector{
							NodeSelectorTerms: []k8sv1.NodeSelectorTerm{
								{
									MatchExpressions: []k8sv1.NodeSelectorRequirement{
										{Key: "kubernetes.io/hostname", Operator: k8sv1.NodeSelectorOpIn, Values: []string{"notexist"}},
									},
								},
							},
						},
					},
				}

				By("Creating a new VirtualMachineInstance")
				vmi, err := virtClient.VirtualMachineInstance(util.NamespaceTestDefault).Create(vmi)
				Expect(err).ToNot(HaveOccurred())

				By("Expecting the VirtualMachineInstance console")
				_, _, err = console.NewExpecter(virtClient, vmi, 30*time.Second)
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(Equal("Timeout trying to connect to the virtual machine instance"))
			})
		})

		Context("without a serial console", func() {
			var vmi *v1.VirtualMachineInstance

			BeforeEach(func() {
				vmi = tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine))
				f := false
				vmi.Spec.Domain.Devices.AutoattachSerialConsole = &f
			})

			It("[test_id:4116]should create the vmi without any issue", func() {
				tests.RunVMIAndExpectLaunch(vmi, 30)
			})

			It("[test_id:4117]should not have the  serial console in xml", func() {
				tests.RunVMIAndExpectLaunch(vmi, 30)

				runningVMISpec, err := tests.GetRunningVMIDomainSpec(vmi)
				Expect(err).ToNot(HaveOccurred(), "should get vmi spec without problem")

				Expect(len(runningVMISpec.Devices.Serials)).To(Equal(0), "should not have any serial consoles present")
				Expect(len(runningVMISpec.Devices.Consoles)).To(Equal(0), "should not have any virtio console for serial consoles")
			})

			It("[test_id:4118]should not connect to the serial console", func() {
				vmi = tests.RunVMIAndExpectLaunch(vmi, 30)

				_, err := virtClient.VirtualMachineInstance(vmi.ObjectMeta.Namespace).SerialConsole(vmi.ObjectMeta.Name, &kubecli.SerialConsoleOptions{})

				Expect(err.Error()).To(Equal("No serial consoles are present."), "serial console should not connect if there are no serial consoles present")
			})
		})
	})
})
<commit_msg>Remove custom DataVolume cleanup and increase timeout<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 (
	"time"

	expect "github.com/google/goexpect"
	. "github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/extensions/table"
	. "github.com/onsi/gomega"
	k8sv1 "k8s.io/api/core/v1"

	"kubevirt.io/kubevirt/tests/util"

	v1 "kubevirt.io/api/core/v1"
	"kubevirt.io/client-go/kubecli"
	"kubevirt.io/kubevirt/tests"
	"kubevirt.io/kubevirt/tests/console"
	cd "kubevirt.io/kubevirt/tests/containerdisk"
	"kubevirt.io/kubevirt/tests/libvmi"
)

var _ = Describe("[rfe_id:127][posneg:negative][crit:medium][vendor:cnv-qe@redhat.com][level:component][sig-compute]Console", func() {

	var virtClient kubecli.KubevirtClient

	BeforeEach(func() {
		var err error

		virtClient, err = kubecli.GetKubevirtClient()
		util.PanicOnError(err)

		tests.BeforeTestCleanup()
	})

	ExpectConsoleOutput := func(vmi *v1.VirtualMachineInstance, expected string) {
		By("Checking that the console output equals to expected one")
		Expect(console.SafeExpectBatch(vmi, []expect.Batcher{
			&expect.BSnd{S: "\n"},
			&expect.BExp{R: expected},
		}, 120)).To(Succeed())
	}

	OpenConsole := func(vmi *v1.VirtualMachineInstance) (expect.Expecter, <-chan error) {
		By("Expecting the VirtualMachineInstance console")
		expecter, errChan, err := console.NewExpecter(virtClient, vmi, 30*time.Second)
		Expect(err).ToNot(HaveOccurred())
		return expecter, errChan
	}

	Describe("[rfe_id:127][posneg:negative][crit:medium][vendor:cnv-qe@redhat.com][level:component]A new VirtualMachineInstance", func() {
		Context("with a serial console", func() {
			Context("with a cirros image", func() {

				It("[test_id:1588]should return that we are running cirros", func() {
					vmi := libvmi.NewCirros()
					vmi = tests.RunVMIAndExpectLaunch(vmi, 30)
					ExpectConsoleOutput(
						vmi,
						"login as 'cirros' user",
					)
				})
			})

			Context("with a fedora image", func() {
				It("[sig-compute][test_id:1589]should return that we are running fedora", func() {
					vmi := libvmi.NewFedora()
					vmi = tests.RunVMIAndExpectLaunch(vmi, 30)
					ExpectConsoleOutput(
						vmi,
						"Welcome to",
					)
				})
			})

			Context("with an alpine image", func() {
				type vmiBuilder func() *v1.VirtualMachineInstance

				newVirtualMachineInstanceWithAlpineFileDisk := func() *v1.VirtualMachineInstance {
					vmi, _ := tests.NewRandomVirtualMachineInstanceWithFileDisk(cd.DataVolumeImportUrlForContainerDisk(cd.ContainerDiskAlpine), util.NamespaceTestDefault, k8sv1.ReadWriteOnce)
					return vmi
				}

				newVirtualMachineInstanceWithAlpineBlockDisk := func() *v1.VirtualMachineInstance {
					vmi, _ := tests.NewRandomVirtualMachineInstanceWithBlockDisk(cd.DataVolumeImportUrlForContainerDisk(cd.ContainerDiskAlpine), util.NamespaceTestDefault, k8sv1.ReadWriteOnce)
					return vmi
				}

				table.DescribeTable("should return that we are running alpine", func(createVMI vmiBuilder) {
					vmi := createVMI()
					vmi = tests.RunVMIAndExpectLaunch(vmi, 120)
					ExpectConsoleOutput(vmi, "login")
				},
					table.Entry("[test_id:4637][storage-req]with Filesystem Disk", newVirtualMachineInstanceWithAlpineFileDisk),
					table.Entry("[test_id:4638][storage-req]with Block Disk", newVirtualMachineInstanceWithAlpineBlockDisk),
				)
			})

			It("[test_id:1590]should be able to reconnect to console multiple times", func() {
				vmi := libvmi.NewAlpine()
				vmi = tests.RunVMIAndExpectLaunch(vmi, 30)

				for i := 0; i < 5; i++ {
					ExpectConsoleOutput(vmi, "login")
				}
			})

			It("[test_id:1591]should close console connection when new console connection is opened", func(done Done) {
				vmi := libvmi.NewAlpine()
				vmi = tests.RunVMIAndExpectLaunch(vmi, 30)

				By("opening 1st console connection")
				expecter, errChan := OpenConsole(vmi)
				defer expecter.Close()

				By("expecting error on 1st console connection")
				go func() {
					defer GinkgoRecover()
					select {
					case receivedErr := <-errChan:
						Expect(receivedErr.Error()).To(ContainSubstring("close"))
						close(done)
					case <-time.After(60 * time.Second):
						Fail("timed out waiting for closed 1st connection")
					}
				}()

				By("opening 2nd console connection")
				ExpectConsoleOutput(vmi, "login")
			}, 220)

			It("[test_id:1592]should wait until the virtual machine is in running state and return a stream interface", func() {
				vmi := libvmi.NewAlpine()
				By("Creating a new VirtualMachineInstance")
				vmi, err := virtClient.VirtualMachineInstance(util.NamespaceTestDefault).Create(vmi)
				Expect(err).ToNot(HaveOccurred())

				_, err = virtClient.VirtualMachineInstance(vmi.Namespace).SerialConsole(vmi.Name, &kubecli.SerialConsoleOptions{ConnectionTimeout: 30 * time.Second})
				Expect(err).ToNot(HaveOccurred())
			})

			It("[test_id:1593]should fail waiting for the virtual machine instance to be running", func() {
				vmi := libvmi.NewAlpine()
				vmi.Spec.Affinity = &k8sv1.Affinity{
					NodeAffinity: &k8sv1.NodeAffinity{
						RequiredDuringSchedulingIgnoredDuringExecution: &k8sv1.NodeSelector{
							NodeSelectorTerms: []k8sv1.NodeSelectorTerm{
								{
									MatchExpressions: []k8sv1.NodeSelectorRequirement{
										{Key: "kubernetes.io/hostname", Operator: k8sv1.NodeSelectorOpIn, Values: []string{"notexist"}},
									},
								},
							},
						},
					},
				}

				By("Creating a new VirtualMachineInstance")
				vmi, err := virtClient.VirtualMachineInstance(util.NamespaceTestDefault).Create(vmi)
				Expect(err).ToNot(HaveOccurred())

				_, err = virtClient.VirtualMachineInstance(vmi.Namespace).SerialConsole(vmi.Name, &kubecli.SerialConsoleOptions{ConnectionTimeout: 30 * time.Second})
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(Equal("Timeout trying to connect to the virtual machine instance"))
			})

			It("[test_id:1594]should fail waiting for the expecter", func() {
				vmi := libvmi.NewAlpine()
				vmi.Spec.Affinity = &k8sv1.Affinity{
					NodeAffinity: &k8sv1.NodeAffinity{
						RequiredDuringSchedulingIgnoredDuringExecution: &k8sv1.NodeSelector{
							NodeSelectorTerms: []k8sv1.NodeSelectorTerm{
								{
									MatchExpressions: []k8sv1.NodeSelectorRequirement{
										{Key: "kubernetes.io/hostname", Operator: k8sv1.NodeSelectorOpIn, Values: []string{"notexist"}},
									},
								},
							},
						},
					},
				}

				By("Creating a new VirtualMachineInstance")
				vmi, err := virtClient.VirtualMachineInstance(util.NamespaceTestDefault).Create(vmi)
				Expect(err).ToNot(HaveOccurred())

				By("Expecting the VirtualMachineInstance console")
				_, _, err = console.NewExpecter(virtClient, vmi, 30*time.Second)
				Expect(err).To(HaveOccurred())
				Expect(err.Error()).To(Equal("Timeout trying to connect to the virtual machine instance"))
			})
		})

		Context("without a serial console", func() {
			var vmi *v1.VirtualMachineInstance

			BeforeEach(func() {
				vmi = tests.NewRandomVMIWithEphemeralDisk(cd.ContainerDiskFor(cd.ContainerDiskAlpine))
				f := false
				vmi.Spec.Domain.Devices.AutoattachSerialConsole = &f
			})

			It("[test_id:4116]should create the vmi without any issue", func() {
				tests.RunVMIAndExpectLaunch(vmi, 30)
			})

			It("[test_id:4117]should not have the  serial console in xml", func() {
				tests.RunVMIAndExpectLaunch(vmi, 30)

				runningVMISpec, err := tests.GetRunningVMIDomainSpec(vmi)
				Expect(err).ToNot(HaveOccurred(), "should get vmi spec without problem")

				Expect(len(runningVMISpec.Devices.Serials)).To(Equal(0), "should not have any serial consoles present")
				Expect(len(runningVMISpec.Devices.Consoles)).To(Equal(0), "should not have any virtio console for serial consoles")
			})

			It("[test_id:4118]should not connect to the serial console", func() {
				vmi = tests.RunVMIAndExpectLaunch(vmi, 30)

				_, err := virtClient.VirtualMachineInstance(vmi.ObjectMeta.Namespace).SerialConsole(vmi.ObjectMeta.Name, &kubecli.SerialConsoleOptions{})

				Expect(err.Error()).To(Equal("No serial consoles are present."), "serial console should not connect if there are no serial consoles present")
			})
		})
	})
})
<|endoftext|>


<commit_before>/*
Copyright 2015 The Kubernetes Authors 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 e2e

import (
	"fmt"
	"time"

	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/apis/experimental"
	client "k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/fields"
	"k8s.io/kubernetes/pkg/kubectl"
	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/util/wait"

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

var _ = Describe("Daemon set", func() {
	f := &Framework{BaseName: "daemonsets"}

	BeforeEach(func() {
		f.beforeEach()
		err := clearNodeLabels(f.Client)
		Expect(err).NotTo(HaveOccurred())
	})

	AfterEach(func() {
		err := clearNodeLabels(f.Client)
		Expect(err).NotTo(HaveOccurred())
		f.afterEach()
	})

	It("should launch a daemon pod on every node of the cluster", func() {
		testDaemonSets(f)
	})
})

func clearNodeLabels(c *client.Client) error {
	nodeClient := c.Nodes()
	nodeList, err := nodeClient.List(labels.Everything(), fields.Everything())
	if err != nil {
		return err
	}
	for _, node := range nodeList.Items {
		if len(node.Labels) != 0 {
			node.Labels = map[string]string{}
			newNode, err := nodeClient.Update(&node)
			if err != nil {
				return err
			} else if len(newNode.Labels) != 0 {
				return fmt.Errorf("Could not make node labels nil.")
			}
		}
	}
	return nil
}

func checkDaemonPodOnNodes(f *Framework, selector map[string]string, nodeNames []string) func() (bool, error) {
	return func() (bool, error) {
		podList, err := f.Client.Pods(f.Namespace.Name).List(labels.Set(selector).AsSelector(), fields.Everything())
		if err != nil {
			return false, nil
		}
		pods := podList.Items

		nodesToPodCount := make(map[string]int)
		for _, pod := range pods {
			nodesToPodCount[pod.Spec.NodeName] += 1
		}

		// Ensure that exactly 1 pod is running on all nodes in nodeNames.
		for _, nodeName := range nodeNames {
			if nodesToPodCount[nodeName] != 1 {
				return false, nil
			}
		}

		// Ensure that sizes of the lists are the same. We've verified that every element of nodeNames is in
		// nodesToPodCount, so verifying the lengths are equal ensures that there aren't pods running on any
		// other nodes.
		return len(nodesToPodCount) == len(nodeNames), nil
	}
}

func checkRunningOnAllNodes(f *Framework, selector map[string]string) func() (bool, error) {
	return func() (bool, error) {
		nodeList, err := f.Client.Nodes().List(labels.Everything(), fields.Everything())
		if err != nil {
			return false, nil
		}
		nodeNames := make([]string, 0)
		for _, node := range nodeList.Items {
			nodeNames = append(nodeNames, node.Name)
		}
		return checkDaemonPodOnNodes(f, selector, nodeNames)()
	}
}

func checkRunningOnNoNodes(f *Framework, selector map[string]string) func() (bool, error) {
	return checkDaemonPodOnNodes(f, selector, make([]string, 0))
}

func testDaemonSets(f *Framework) {
	ns := f.Namespace.Name
	c := f.Client
	simpleDSName := "simple-daemon-set"
	image := "gcr.io/google_containers/serve_hostname:1.1"
	label := map[string]string{"name": simpleDSName}
	retryTimeout := 1 * time.Minute
	retryInterval := 5 * time.Second

	Logf("Creating simple daemon set %s", simpleDSName)
	_, err := c.DaemonSets(ns).Create(&experimental.DaemonSet{
		ObjectMeta: api.ObjectMeta{
			Name: simpleDSName,
		},
		Spec: experimental.DaemonSetSpec{
			Template: &api.PodTemplateSpec{
				ObjectMeta: api.ObjectMeta{
					Labels: label,
				},
				Spec: api.PodSpec{
					Containers: []api.Container{
						{
							Name:  simpleDSName,
							Image: image,
							Ports: []api.ContainerPort{{ContainerPort: 9376}},
						},
					},
				},
			},
		},
	})
	Expect(err).NotTo(HaveOccurred())
	defer func() {
		Logf("Check that reaper kills all daemon pods for %s", simpleDSName)
		dsReaper, err := kubectl.ReaperFor("DaemonSet", c)
		Expect(err).NotTo(HaveOccurred())
		_, err = dsReaper.Stop(ns, simpleDSName, 0, nil)
		Expect(err).NotTo(HaveOccurred())
		err = wait.Poll(retryInterval, retryTimeout, checkRunningOnNoNodes(f, label))
		Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pod to be reaped")
	}()

	By("Check that daemon pods launch on every node of the cluster.")
	Expect(err).NotTo(HaveOccurred())
	err = wait.Poll(retryInterval, retryTimeout, checkRunningOnAllNodes(f, label))
	Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pod to start")

	By("Stop a daemon pod, check that the daemon pod is revived.")
	podClient := c.Pods(ns)

	podList, err := podClient.List(labels.Set(label).AsSelector(), fields.Everything())
	Expect(err).NotTo(HaveOccurred())
	Expect(len(podList.Items)).To(BeNumerically(">", 0))
	pod := podList.Items[0]
	err = podClient.Delete(pod.Name, nil)
	Expect(err).NotTo(HaveOccurred())
	err = wait.Poll(retryInterval, retryTimeout, checkRunningOnAllNodes(f, label))
	Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pod to revive")

	complexDSName := "complex-daemon-set"
	complexLabel := map[string]string{"name": complexDSName}
	nodeSelector := map[string]string{"color": "blue"}
	Logf("Creating daemon with a node selector %s", complexDSName)
	_, err = c.DaemonSets(ns).Create(&experimental.DaemonSet{
		ObjectMeta: api.ObjectMeta{
			Name: complexDSName,
		},
		Spec: experimental.DaemonSetSpec{
			Selector: complexLabel,
			Template: &api.PodTemplateSpec{
				ObjectMeta: api.ObjectMeta{
					Labels: complexLabel,
				},
				Spec: api.PodSpec{
					NodeSelector: nodeSelector,
					Containers: []api.Container{
						{
							Name:  complexDSName,
							Image: image,
							Ports: []api.ContainerPort{{ContainerPort: 9376}},
						},
					},
				},
			},
		},
	})
	Expect(err).NotTo(HaveOccurred())

	By("Initially, daemon pods should not be running on any nodes.")
	err = wait.Poll(retryInterval, retryTimeout, checkRunningOnNoNodes(f, complexLabel))
	Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pods to be running on no nodes")

	By("Change label of node, check that daemon pod is launched.")
	nodeClient := c.Nodes()
	nodeList, err := nodeClient.List(labels.Everything(), fields.Everything())
	Expect(len(nodeList.Items)).To(BeNumerically(">", 0))
	nodeList.Items[0].Labels = nodeSelector
	newNode, err := nodeClient.Update(&nodeList.Items[0])
	Expect(err).NotTo(HaveOccurred())
	Expect(len(newNode.Labels)).To(Equal(1))
	err = wait.Poll(retryInterval, retryTimeout, checkDaemonPodOnNodes(f, complexLabel, []string{newNode.Name}))
	Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pods to be running on new nodes")

	By("remove the node selector and wait for daemons to be unscheduled")
	newNode, err = nodeClient.Get(newNode.Name)
	Expect(err).NotTo(HaveOccurred(), "error getting node")
	newNode.Labels = map[string]string{}
	newNode, err = nodeClient.Update(newNode)
	Expect(err).NotTo(HaveOccurred())
	Expect(wait.Poll(retryInterval, retryTimeout, checkRunningOnNoNodes(f, complexLabel))).
		NotTo(HaveOccurred(), "error waiting for daemon pod to not be running on nodes")

	By("We should now be able to delete the daemon set.")
	Expect(c.DaemonSets(ns).Delete(complexDSName)).NotTo(HaveOccurred())
}
<commit_msg>retry updates of nodes in daemonset e2e<commit_after>/*
Copyright 2015 The Kubernetes Authors 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 e2e

import (
	"fmt"
	"time"

	"k8s.io/kubernetes/pkg/api"
	apierrs "k8s.io/kubernetes/pkg/api/errors"
	"k8s.io/kubernetes/pkg/api/unversioned"
	"k8s.io/kubernetes/pkg/apis/experimental"
	client "k8s.io/kubernetes/pkg/client/unversioned"
	"k8s.io/kubernetes/pkg/fields"
	"k8s.io/kubernetes/pkg/kubectl"
	"k8s.io/kubernetes/pkg/labels"
	"k8s.io/kubernetes/pkg/util/wait"

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

const (
	updateRetryPeriod  = 5 * time.Second
	updateRetryTimeout = 30 * time.Second
)

var _ = Describe("Daemon set", func() {
	f := &Framework{BaseName: "daemonsets"}

	BeforeEach(func() {
		f.beforeEach()
		err := clearNodeLabels(f.Client)
		Expect(err).NotTo(HaveOccurred())
	})

	AfterEach(func() {
		err := clearNodeLabels(f.Client)
		Expect(err).NotTo(HaveOccurred())
		f.afterEach()
	})

	It("should launch a daemon pod on every node of the cluster", func() {
		testDaemonSets(f)
	})
})

func clearNodeLabels(c *client.Client) error {
	nodeClient := c.Nodes()
	nodeList, err := nodeClient.List(labels.Everything(), fields.Everything())
	if err != nil {
		return err
	}
	for _, node := range nodeList.Items {
		if len(node.Labels) != 0 {
			node.Labels = map[string]string{}
			var newNode *api.Node
			err = wait.Poll(updateRetryPeriod, updateRetryTimeout, func() (bool, error) {
				newNode, err = nodeClient.Update(&node)
				if err == nil {
					return true, err
				}
				if se, ok := err.(*apierrs.StatusError); ok && se.ErrStatus.Reason == unversioned.StatusReasonConflict {
					Logf("failed to update node due to resource version conflict")
					return false, nil
				}
				return false, err
			})
			if err != nil {
				return err
			} else if len(newNode.Labels) != 0 {
				return fmt.Errorf("Could not make node labels nil.")
			}
		}
	}
	return nil
}

func checkDaemonPodOnNodes(f *Framework, selector map[string]string, nodeNames []string) func() (bool, error) {
	return func() (bool, error) {
		podList, err := f.Client.Pods(f.Namespace.Name).List(labels.Set(selector).AsSelector(), fields.Everything())
		if err != nil {
			return false, nil
		}
		pods := podList.Items

		nodesToPodCount := make(map[string]int)
		for _, pod := range pods {
			nodesToPodCount[pod.Spec.NodeName] += 1
		}

		// Ensure that exactly 1 pod is running on all nodes in nodeNames.
		for _, nodeName := range nodeNames {
			if nodesToPodCount[nodeName] != 1 {
				return false, nil
			}
		}

		// Ensure that sizes of the lists are the same. We've verified that every element of nodeNames is in
		// nodesToPodCount, so verifying the lengths are equal ensures that there aren't pods running on any
		// other nodes.
		return len(nodesToPodCount) == len(nodeNames), nil
	}
}

func checkRunningOnAllNodes(f *Framework, selector map[string]string) func() (bool, error) {
	return func() (bool, error) {
		nodeList, err := f.Client.Nodes().List(labels.Everything(), fields.Everything())
		if err != nil {
			return false, nil
		}
		nodeNames := make([]string, 0)
		for _, node := range nodeList.Items {
			nodeNames = append(nodeNames, node.Name)
		}
		return checkDaemonPodOnNodes(f, selector, nodeNames)()
	}
}

func checkRunningOnNoNodes(f *Framework, selector map[string]string) func() (bool, error) {
	return checkDaemonPodOnNodes(f, selector, make([]string, 0))
}

func testDaemonSets(f *Framework) {
	ns := f.Namespace.Name
	c := f.Client
	simpleDSName := "simple-daemon-set"
	image := "gcr.io/google_containers/serve_hostname:1.1"
	label := map[string]string{"name": simpleDSName}
	retryTimeout := 1 * time.Minute
	retryInterval := 5 * time.Second

	Logf("Creating simple daemon set %s", simpleDSName)
	_, err := c.DaemonSets(ns).Create(&experimental.DaemonSet{
		ObjectMeta: api.ObjectMeta{
			Name: simpleDSName,
		},
		Spec: experimental.DaemonSetSpec{
			Template: &api.PodTemplateSpec{
				ObjectMeta: api.ObjectMeta{
					Labels: label,
				},
				Spec: api.PodSpec{
					Containers: []api.Container{
						{
							Name:  simpleDSName,
							Image: image,
							Ports: []api.ContainerPort{{ContainerPort: 9376}},
						},
					},
				},
			},
		},
	})
	Expect(err).NotTo(HaveOccurred())
	defer func() {
		Logf("Check that reaper kills all daemon pods for %s", simpleDSName)
		dsReaper, err := kubectl.ReaperFor("DaemonSet", c)
		Expect(err).NotTo(HaveOccurred())
		_, err = dsReaper.Stop(ns, simpleDSName, 0, nil)
		Expect(err).NotTo(HaveOccurred())
		err = wait.Poll(retryInterval, retryTimeout, checkRunningOnNoNodes(f, label))
		Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pod to be reaped")
	}()

	By("Check that daemon pods launch on every node of the cluster.")
	Expect(err).NotTo(HaveOccurred())
	err = wait.Poll(retryInterval, retryTimeout, checkRunningOnAllNodes(f, label))
	Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pod to start")

	By("Stop a daemon pod, check that the daemon pod is revived.")
	podClient := c.Pods(ns)

	podList, err := podClient.List(labels.Set(label).AsSelector(), fields.Everything())
	Expect(err).NotTo(HaveOccurred())
	Expect(len(podList.Items)).To(BeNumerically(">", 0))
	pod := podList.Items[0]
	err = podClient.Delete(pod.Name, nil)
	Expect(err).NotTo(HaveOccurred())
	err = wait.Poll(retryInterval, retryTimeout, checkRunningOnAllNodes(f, label))
	Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pod to revive")

	complexDSName := "complex-daemon-set"
	complexLabel := map[string]string{"name": complexDSName}
	nodeSelector := map[string]string{"color": "blue"}
	Logf("Creating daemon with a node selector %s", complexDSName)
	_, err = c.DaemonSets(ns).Create(&experimental.DaemonSet{
		ObjectMeta: api.ObjectMeta{
			Name: complexDSName,
		},
		Spec: experimental.DaemonSetSpec{
			Selector: complexLabel,
			Template: &api.PodTemplateSpec{
				ObjectMeta: api.ObjectMeta{
					Labels: complexLabel,
				},
				Spec: api.PodSpec{
					NodeSelector: nodeSelector,
					Containers: []api.Container{
						{
							Name:  complexDSName,
							Image: image,
							Ports: []api.ContainerPort{{ContainerPort: 9376}},
						},
					},
				},
			},
		},
	})
	Expect(err).NotTo(HaveOccurred())

	By("Initially, daemon pods should not be running on any nodes.")
	err = wait.Poll(retryInterval, retryTimeout, checkRunningOnNoNodes(f, complexLabel))
	Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pods to be running on no nodes")

	By("Change label of node, check that daemon pod is launched.")
	nodeClient := c.Nodes()
	nodeList, err := nodeClient.List(labels.Everything(), fields.Everything())
	Expect(len(nodeList.Items)).To(BeNumerically(">", 0))
	nodeList.Items[0].Labels = nodeSelector
	var newNode *api.Node
	err = wait.Poll(updateRetryPeriod, updateRetryTimeout, func() (bool, error) {
		newNode, err = nodeClient.Update(&nodeList.Items[0])
		if err == nil {
			return true, err
		}
		if se, ok := err.(*apierrs.StatusError); ok && se.ErrStatus.Reason == unversioned.StatusReasonConflict {
			Logf("failed to update node due to resource version conflict")
			return false, nil
		}
		return false, err
	})
	Expect(err).NotTo(HaveOccurred())
	Expect(len(newNode.Labels)).To(Equal(1))
	err = wait.Poll(retryInterval, retryTimeout, checkDaemonPodOnNodes(f, complexLabel, []string{newNode.Name}))
	Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pods to be running on new nodes")

	By("remove the node selector and wait for daemons to be unscheduled")
	newNode, err = nodeClient.Get(newNode.Name)
	Expect(err).NotTo(HaveOccurred(), "error getting node")
	newNode.Labels = map[string]string{}
	err = wait.Poll(updateRetryPeriod, updateRetryTimeout, func() (bool, error) {
		newNode, err = nodeClient.Update(newNode)
		if err == nil {
			return true, err
		}
		if se, ok := err.(*apierrs.StatusError); ok && se.ErrStatus.Reason == unversioned.StatusReasonConflict {
			Logf("failed to update node due to resource version conflict")
			return false, nil
		}
		return false, err
	})
	Expect(err).NotTo(HaveOccurred())
	Expect(wait.Poll(retryInterval, retryTimeout, checkRunningOnNoNodes(f, complexLabel))).
		NotTo(HaveOccurred(), "error waiting for daemon pod to not be running on nodes")

	By("We should now be able to delete the daemon set.")
	Expect(c.DaemonSets(ns).Delete(complexDSName)).NotTo(HaveOccurred())
}
<|endoftext|>


<commit_before>// +build mock

package tera

import (
	"errors"
	"fmt"
)

type Table struct {
	Name string
	Data map[string]string
}

func (t *Table) Close() {
	fmt.Println("close mock table: " + t.Name)
}

// discard ttl in mock table
func (t *Table) PutKV(key, value string, ttl int) (err error) {
	t.Data[key] = value
	return nil
}

func (t *Table) GetKV(key string) (value string, err error) {
	var found bool
	value, found = t.Data[key]
	if !found {
		err = errors.New("NotExist")
	}
	return
}

func (t *Table) DeleteKV(key string) (err error) {
	delete(t.Data, key)
	return nil
}
<commit_msg>update table_mock<commit_after>// +build mock

package tera

import (
	"errors"
	"fmt"
)

type Table struct {
	Name string
	Data map[string]string
}

func (t *Table) Close() {
	fmt.Println("close mock table: " + t.Name)
}

// discard ttl in mock table
func (t *Table) PutKV(key, value string, ttl int) (err error) {
	t.Data[key] = value
	return nil
}

func (t *Table) PutKVAsync(key, value string, ttl int) (err error) {
	t.Data[key] = value
	return nil
}

func (t *Table) GetKV(key string) (value string, err error) {
	var found bool
	value, found = t.Data[key]
	if !found {
		err = errors.New("NotExist")
	}
	return
}

func (t *Table) DeleteKV(key string) (err error) {
	delete(t.Data, key)
	return nil
}
<|endoftext|>