<commit_before>package http_response

import (
	"errors"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/url"
	"regexp"
	"strings"
	"time"

	"github.com/influxdata/telegraf"
	"github.com/influxdata/telegraf/internal"
	"github.com/influxdata/telegraf/plugins/inputs"
)

// HTTPResponse struct
type HTTPResponse struct {
	Address             string
	Body                string
	Method              string
	ResponseTimeout     internal.Duration
	Headers             map[string]string
	FollowRedirects     bool
	ResponseStringMatch string

	// Path to CA file
	SSLCA string `toml:"ssl_ca"`
	// Path to host cert file
	SSLCert string `toml:"ssl_cert"`
	// Path to cert key file
	SSLKey string `toml:"ssl_key"`
	// Use SSL but skip chain & host verification
	InsecureSkipVerify bool

	compiledStringMatch *regexp.Regexp
	client              *http.Client
}

// Description returns the plugin Description
func (h *HTTPResponse) Description() string {
	return "HTTP/HTTPS request given an address a method and a timeout"
}

var sampleConfig = `
  ## Server address (default http://localhost)
  # address = "http://localhost"

  ## Set response_timeout (default 5 seconds)
  # response_timeout = "5s"

  ## HTTP Request Method
  # method = "GET"

  ## Whether to follow redirects from the server (defaults to false)
  # follow_redirects = false

  ## Optional HTTP Request Body
  # body = '''
  # {'fake':'data'}
  # '''

  ## Optional substring or regex match in body of the response
  # response_string_match = "\"service_status\": \"up\""
  # response_string_match = "ok"
  # response_string_match = "\".*_status\".?:.?\"up\""

  ## Optional SSL Config
  # ssl_ca = "/etc/telegraf/ca.pem"
  # ssl_cert = "/etc/telegraf/cert.pem"
  # ssl_key = "/etc/telegraf/key.pem"
  ## Use SSL but skip chain & host verification
  # insecure_skip_verify = false

  ## HTTP Request Headers (all values must be strings)
  # [inputs.http_response.headers]
  #   Host = "github.com"
`

// SampleConfig returns the plugin SampleConfig
func (h *HTTPResponse) SampleConfig() string {
	return sampleConfig
}

// ErrRedirectAttempted indicates that a redirect occurred
var ErrRedirectAttempted = errors.New("redirect")

// CreateHttpClient creates an http client which will timeout at the specified
// timeout period and can follow redirects if specified
func (h *HTTPResponse) createHttpClient() (*http.Client, error) {
	tlsCfg, err := internal.GetTLSConfig(
		h.SSLCert, h.SSLKey, h.SSLCA, h.InsecureSkipVerify)
	if err != nil {
		return nil, err
	}
	client := &http.Client{
		Transport: &http.Transport{
			DisableKeepAlives: true,
			TLSClientConfig:   tlsCfg,
		},
		Timeout: h.ResponseTimeout.Duration,
	}

	if h.FollowRedirects == false {
		client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
			return ErrRedirectAttempted
		}
	}
	return client, nil
}

// HTTPGather gathers all fields and returns any errors it encounters
func (h *HTTPResponse) httpGather() (map[string]interface{}, error) {
	// Prepare fields
	fields := make(map[string]interface{})

	var body io.Reader
	if h.Body != "" {
		body = strings.NewReader(h.Body)
	}
	request, err := http.NewRequest(h.Method, h.Address, body)
	if err != nil {
		return nil, err
	}

	for key, val := range h.Headers {
		request.Header.Add(key, val)
		if key == "Host" {
			request.Host = val
		}
	}

	// Start Timer
	start := time.Now()
	resp, err := h.client.Do(request)

	if err != nil {
		if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
			fields["result_type"] = "timeout"
			return fields, nil
		}
		fields["result_type"] = "connection_failed"
		if h.FollowRedirects {
			return fields, nil
		}
		if urlError, ok := err.(*url.Error); ok &&
			urlError.Err == ErrRedirectAttempted {
			err = nil
		} else {
			return fields, nil
		}
	}
	defer func() {
		io.Copy(ioutil.Discard, resp.Body)
		resp.Body.Close()
	}()

	fields["response_time"] = time.Since(start).Seconds()
	fields["http_response_code"] = resp.StatusCode

	// Check the response for a regex match.
	if h.ResponseStringMatch != "" {

		// Compile once and reuse
		if h.compiledStringMatch == nil {
			h.compiledStringMatch = regexp.MustCompile(h.ResponseStringMatch)
			if err != nil {
				log.Printf("E! Failed to compile regular expression %s : %s", h.ResponseStringMatch, err)
				fields["result_type"] = "response_string_mismatch"
				return fields, nil
			}
		}

		bodyBytes, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			log.Printf("E! Failed to read body of HTTP Response : %s", err)
			fields["result_type"] = "response_string_mismatch"
			fields["response_string_match"] = 0
			return fields, nil
		}

		if h.compiledStringMatch.Match(bodyBytes) {
			fields["result_type"] = "success"
			fields["response_string_match"] = 1
		} else {
			fields["result_type"] = "response_string_mismatch"
			fields["response_string_match"] = 0
		}
	} else {
		fields["result_type"] = "success"
	}

	return fields, nil
}

// Gather gets all metric fields and tags and returns any errors it encounters
func (h *HTTPResponse) Gather(acc telegraf.Accumulator) error {
	// Set default values
	if h.ResponseTimeout.Duration < time.Second {
		h.ResponseTimeout.Duration = time.Second * 5
	}
	// Check send and expected string
	if h.Method == "" {
		h.Method = "GET"
	}
	if h.Address == "" {
		h.Address = "http://localhost"
	}
	addr, err := url.Parse(h.Address)
	if err != nil {
		return err
	}
	if addr.Scheme != "http" && addr.Scheme != "https" {
		return errors.New("Only http and https are supported")
	}
	// Prepare data
	tags := map[string]string{"server": h.Address, "method": h.Method}
	var fields map[string]interface{}

	if h.client == nil {
		client, err := h.createHttpClient()
		if err != nil {
			return err
		}
		h.client = client
	}

	// Gather data
	fields, err = h.httpGather()
	if err != nil {
		return err
	}
	// Add metrics
	acc.AddFields("http_response", fields, tags)
	return nil
}

func init() {
	inputs.Add("http_response", func() telegraf.Input {
		return &HTTPResponse{}
	})
}
<commit_msg>Add support for proxy environment variables to http_response (#3302)<commit_after>package http_response

import (
	"errors"
	"io"
	"io/ioutil"
	"log"
	"net"
	"net/http"
	"net/url"
	"regexp"
	"strings"
	"time"

	"github.com/influxdata/telegraf"
	"github.com/influxdata/telegraf/internal"
	"github.com/influxdata/telegraf/plugins/inputs"
)

// HTTPResponse struct
type HTTPResponse struct {
	Address             string
	Body                string
	Method              string
	ResponseTimeout     internal.Duration
	Headers             map[string]string
	FollowRedirects     bool
	ResponseStringMatch string

	// Path to CA file
	SSLCA string `toml:"ssl_ca"`
	// Path to host cert file
	SSLCert string `toml:"ssl_cert"`
	// Path to cert key file
	SSLKey string `toml:"ssl_key"`
	// Use SSL but skip chain & host verification
	InsecureSkipVerify bool

	compiledStringMatch *regexp.Regexp
	client              *http.Client
}

// Description returns the plugin Description
func (h *HTTPResponse) Description() string {
	return "HTTP/HTTPS request given an address a method and a timeout"
}

var sampleConfig = `
  ## Server address (default http://localhost)
  # address = "http://localhost"

  ## Set response_timeout (default 5 seconds)
  # response_timeout = "5s"

  ## HTTP Request Method
  # method = "GET"

  ## Whether to follow redirects from the server (defaults to false)
  # follow_redirects = false

  ## Optional HTTP Request Body
  # body = '''
  # {'fake':'data'}
  # '''

  ## Optional substring or regex match in body of the response
  # response_string_match = "\"service_status\": \"up\""
  # response_string_match = "ok"
  # response_string_match = "\".*_status\".?:.?\"up\""

  ## Optional SSL Config
  # ssl_ca = "/etc/telegraf/ca.pem"
  # ssl_cert = "/etc/telegraf/cert.pem"
  # ssl_key = "/etc/telegraf/key.pem"
  ## Use SSL but skip chain & host verification
  # insecure_skip_verify = false

  ## HTTP Request Headers (all values must be strings)
  # [inputs.http_response.headers]
  #   Host = "github.com"
`

// SampleConfig returns the plugin SampleConfig
func (h *HTTPResponse) SampleConfig() string {
	return sampleConfig
}

// ErrRedirectAttempted indicates that a redirect occurred
var ErrRedirectAttempted = errors.New("redirect")

// CreateHttpClient creates an http client which will timeout at the specified
// timeout period and can follow redirects if specified
func (h *HTTPResponse) createHttpClient() (*http.Client, error) {
	tlsCfg, err := internal.GetTLSConfig(
		h.SSLCert, h.SSLKey, h.SSLCA, h.InsecureSkipVerify)
	if err != nil {
		return nil, err
	}
	client := &http.Client{
		Transport: &http.Transport{
			Proxy:             http.ProxyFromEnvironment,
			DisableKeepAlives: true,
			TLSClientConfig:   tlsCfg,
		},
		Timeout: h.ResponseTimeout.Duration,
	}

	if h.FollowRedirects == false {
		client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
			return ErrRedirectAttempted
		}
	}
	return client, nil
}

// HTTPGather gathers all fields and returns any errors it encounters
func (h *HTTPResponse) httpGather() (map[string]interface{}, error) {
	// Prepare fields
	fields := make(map[string]interface{})

	var body io.Reader
	if h.Body != "" {
		body = strings.NewReader(h.Body)
	}
	request, err := http.NewRequest(h.Method, h.Address, body)
	if err != nil {
		return nil, err
	}

	for key, val := range h.Headers {
		request.Header.Add(key, val)
		if key == "Host" {
			request.Host = val
		}
	}

	// Start Timer
	start := time.Now()
	resp, err := h.client.Do(request)

	if err != nil {
		if netErr, ok := err.(net.Error); ok && netErr.Timeout() {
			fields["result_type"] = "timeout"
			return fields, nil
		}
		fields["result_type"] = "connection_failed"
		if h.FollowRedirects {
			return fields, nil
		}
		if urlError, ok := err.(*url.Error); ok &&
			urlError.Err == ErrRedirectAttempted {
			err = nil
		} else {
			return fields, nil
		}
	}
	defer func() {
		io.Copy(ioutil.Discard, resp.Body)
		resp.Body.Close()
	}()

	fields["response_time"] = time.Since(start).Seconds()
	fields["http_response_code"] = resp.StatusCode

	// Check the response for a regex match.
	if h.ResponseStringMatch != "" {

		// Compile once and reuse
		if h.compiledStringMatch == nil {
			h.compiledStringMatch = regexp.MustCompile(h.ResponseStringMatch)
			if err != nil {
				log.Printf("E! Failed to compile regular expression %s : %s", h.ResponseStringMatch, err)
				fields["result_type"] = "response_string_mismatch"
				return fields, nil
			}
		}

		bodyBytes, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			log.Printf("E! Failed to read body of HTTP Response : %s", err)
			fields["result_type"] = "response_string_mismatch"
			fields["response_string_match"] = 0
			return fields, nil
		}

		if h.compiledStringMatch.Match(bodyBytes) {
			fields["result_type"] = "success"
			fields["response_string_match"] = 1
		} else {
			fields["result_type"] = "response_string_mismatch"
			fields["response_string_match"] = 0
		}
	} else {
		fields["result_type"] = "success"
	}

	return fields, nil
}

// Gather gets all metric fields and tags and returns any errors it encounters
func (h *HTTPResponse) Gather(acc telegraf.Accumulator) error {
	// Set default values
	if h.ResponseTimeout.Duration < time.Second {
		h.ResponseTimeout.Duration = time.Second * 5
	}
	// Check send and expected string
	if h.Method == "" {
		h.Method = "GET"
	}
	if h.Address == "" {
		h.Address = "http://localhost"
	}
	addr, err := url.Parse(h.Address)
	if err != nil {
		return err
	}
	if addr.Scheme != "http" && addr.Scheme != "https" {
		return errors.New("Only http and https are supported")
	}
	// Prepare data
	tags := map[string]string{"server": h.Address, "method": h.Method}
	var fields map[string]interface{}

	if h.client == nil {
		client, err := h.createHttpClient()
		if err != nil {
			return err
		}
		h.client = client
	}

	// Gather data
	fields, err = h.httpGather()
	if err != nil {
		return err
	}
	// Add metrics
	acc.AddFields("http_response", fields, tags)
	return nil
}

func init() {
	inputs.Add("http_response", func() telegraf.Input {
		return &HTTPResponse{}
	})
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"sync"
)

type PrintResetter interface {
	Print(string) (int, error)
	Reset()
}

func NewPrinter(target io.Writer, maxCol, maxRow int) *Printer {
	return &Printer{
		target:  target,
		maxCol:  maxCol,
		maxRow:  maxRow,
		printed: 0,
		mutex:   &sync.Mutex{},
	}
}

type Printer struct {
	target  io.Writer
	maxCol  int
	maxRow  int
	printed int
	mutex   *sync.Mutex
}

func (p *Printer) Print(line string) (n int, err error) {
	p.mutex.Lock()
	if p.printed == p.maxRow {
		p.mutex.Unlock()
		return 0, nil
	}

	if p.printed == 0 {
		fmt.Fprintf(p.target, "\n")
	}

	// If we're on the last line, cut the newline character off
	if p.printed == p.maxRow-1 && line[len(line)-1] == '\n' {
		n, err = p.printLine(line[:len(line)-1])
	} else {
		n, err = p.printLine(line)
	}

	if err == nil {
		p.printed++
	}

	p.mutex.Unlock()
	return
}

func (p *Printer) printLine(line string) (n int, err error) {
	if len(line) > p.maxCol {
		n, err = fmt.Fprintf(p.target, "%s\n", line[:p.maxCol])
	} else {
		n, err = fmt.Fprintf(p.target, "%s", line)
	}
	return
}

func (p *Printer) Reset() {
	p.mutex.Lock()
	p.printed = 0
	p.mutex.Unlock()
}
<commit_msg>Remove mutex from Printer<commit_after>package main

import (
	"fmt"
	"io"
)

type PrintResetter interface {
	Print(string) (int, error)
	Reset()
}

func NewPrinter(target io.Writer, maxCol, maxRow int) *Printer {
	return &Printer{
		target:  target,
		maxCol:  maxCol,
		maxRow:  maxRow,
		printed: 0,
	}
}

type Printer struct {
	target  io.Writer
	maxCol  int
	maxRow  int
	printed int
}

func (p *Printer) Print(line string) (n int, err error) {
	if p.printed == p.maxRow {
		return 0, nil
	}

	if p.printed == 0 {
		fmt.Fprintf(p.target, "\n")
	}

	// If we're on the last line, cut the newline character off
	if p.printed == p.maxRow-1 && line[len(line)-1] == '\n' {
		n, err = p.printLine(line[:len(line)-1])
	} else {
		n, err = p.printLine(line)
	}

	if err == nil {
		p.printed++
	}

	return
}

func (p *Printer) printLine(line string) (n int, err error) {
	if len(line) > p.maxCol {
		n, err = fmt.Fprintf(p.target, "%s\n", line[:p.maxCol])
	} else {
		n, err = fmt.Fprintf(p.target, "%s", line)
	}
	return
}

func (p *Printer) Reset() {
	p.printed = 0
}
<|endoftext|>


<commit_before>package GistJSON

type Response struct {
	Url         string                 `json:"url"`
	ForksUrl    string                 `json:"forks_url"`
	CommitsUrl  string                 `json:"commits_url"`
	Id          string                 `json:"id"`
	GitPullUrl  string                 `json:"git_pull_url"`
	GitPushUrl  string                 `json:"git_push_url"`
	HtmlUrl     string                 `json:"html_url"`
	Files       map[string]FileDetails `json:"files"`
	Public      bool                   `json:"public"`
	CreatedAt   string                 `json:"created_at"`
	UpdatedAt   string                 `json:"updated_at"`
	Description string                 `json:"description"`
	Comments    int                    `json:"comments"`
	User        User                   `json:"user"`
	CommentsUrl string                 `json:"comments_url"`
}

type User struct {
	Login             string `json:"login"`
	Id                int64  `json:"id"`
	AvatarUrl         string `json:"avatar_url"`
	GravatarId        string `json:"gravatar_id"`
	Url               string `json:"url"`
	HtmlUrl           string `json:"html_url"`
	FollowersUrl      string `json:"followers_url"`
	FollowingUrl      string `json:"followings_url"`
	GistsUrl          string `json:"gists_url"`
	StarredUrl        string `json:"starred_url"`
	SubscriptionsUrl  string `json:"subscriptions_url"`
	OrganizationsUrl  string `json:"organizations_url"`
	ReposUrl          string `json:"repos_url"`
	EventsUrl         string `json:"events_url"`
	ReceivedEventsUrl string `json:"received_events_url"`
	TypeUrl           string `json:"type_url"`
}

type Post struct {
	Desc   string          `json:"description"`
	Public bool            `json:"public"`
	Files  map[string]File `json:"files"`
}

type File struct {
	Content string `json:"content"`
}

type FileDetails struct {
	FileName string `json:"file_name"`
	Type     string `json:"type"`
	Language string `json:"language"`
	RawUrl   string `json:"raw_url"`
	Size     int    `json:"size"`
	Content  string `json:"content"`
}

type MessageResponse struct {
	Message          string `json:"message"`
	DocumentationUrl string `json:"documentation_url"`
}
<commit_msg>FIX filename json key<commit_after>package GistJSON

type Response struct {
	Url         string                 `json:"url"`
	ForksUrl    string                 `json:"forks_url"`
	CommitsUrl  string                 `json:"commits_url"`
	Id          string                 `json:"id"`
	GitPullUrl  string                 `json:"git_pull_url"`
	GitPushUrl  string                 `json:"git_push_url"`
	HtmlUrl     string                 `json:"html_url"`
	Files       map[string]FileDetails `json:"files"`
	Public      bool                   `json:"public"`
	CreatedAt   string                 `json:"created_at"`
	UpdatedAt   string                 `json:"updated_at"`
	Description string                 `json:"description"`
	Comments    int                    `json:"comments"`
	User        User                   `json:"user"`
	CommentsUrl string                 `json:"comments_url"`
}

type User struct {
	Login             string `json:"login"`
	Id                int64  `json:"id"`
	AvatarUrl         string `json:"avatar_url"`
	GravatarId        string `json:"gravatar_id"`
	Url               string `json:"url"`
	HtmlUrl           string `json:"html_url"`
	FollowersUrl      string `json:"followers_url"`
	FollowingUrl      string `json:"followings_url"`
	GistsUrl          string `json:"gists_url"`
	StarredUrl        string `json:"starred_url"`
	SubscriptionsUrl  string `json:"subscriptions_url"`
	OrganizationsUrl  string `json:"organizations_url"`
	ReposUrl          string `json:"repos_url"`
	EventsUrl         string `json:"events_url"`
	ReceivedEventsUrl string `json:"received_events_url"`
	TypeUrl           string `json:"type_url"`
}

type Post struct {
	Desc   string          `json:"description"`
	Public bool            `json:"public"`
	Files  map[string]File `json:"files"`
}

type File struct {
	Content string `json:"content"`
}

type FileDetails struct {
	FileName string `json:"filename"`
	Type     string `json:"type"`
	Language string `json:"language"`
	RawUrl   string `json:"raw_url"`
	Size     int    `json:"size"`
	Content  string `json:"content"`
}

type MessageResponse struct {
	Message          string `json:"message"`
	DocumentationUrl string `json:"documentation_url"`
}
<|endoftext|>


<commit_before>package jsonrpc

import (
	"encoding/json"
	"errors"

	"github.com/nbusy/neptulon"
)

// Client is a client implementation for JSON-RPC 2.0 protocol for Neptulon framework.
// Client implementations in other programming languages might be provided in separate repositories so check the documentation.
type Client struct {
	conn *neptulon.Conn
}

// Dial creates a new client connection to a given network address with optional CA and/or a client certificate (PEM encoded X.509 cert/key).
// Debug mode logs all raw TCP communication.
func Dial(addr string, ca []byte, clientCert []byte, clientCertKey []byte, debug bool) (*Client, error) {
	c, err := neptulon.Dial(addr, ca, clientCert, clientCertKey, debug)
	if err != nil {
		return nil, err
	}

	return &Client{conn: c}, nil
}

// SetReadDeadline set the read deadline for the connection in seconds.
func (c *Client) SetReadDeadline(seconds int) {
	c.conn.SetReadDeadline(seconds)
}

// ReadMsg reads a message off of a client connection and returns a request, response, or notification message depending on what server sent.
// Optionally, you can pass in a data structure that the returned JSON-RPC response result data will be serialized into. Otherwise the response result data will be a map.
func (c *Client) ReadMsg(resultData interface{}) (req *Request, res *Response, not *Notification, err error) {
	_, data, err := c.conn.Read()
	if err != nil {
		return
	}

	msg := message{Result: resultData}
	if err = json.Unmarshal(data, &msg); err != nil {
		return
	}

	// if incoming message is a request or response
	if msg.ID != "" {
		// if incoming message is a request
		if msg.Method != "" {
			req = &Request{ID: msg.ID, Method: msg.Method, Params: msg.Params}
			return
		}

		// if incoming message is a response
		res = &Response{ID: msg.ID, Result: msg.Result, Error: msg.Error}
		return
	}

	// if incoming message is a notification
	if msg.Method != "" {
		not = &Notification{Method: msg.Method, Params: msg.Params}
	}

	err = errors.New("Received a malformed message.")
	return
}

// WriteRequest writes a JSON-RPC request to a client connection with structured params object and auto generated request ID.
func (c *Client) WriteRequest(method string, params interface{}) (reqID string, err error) {
	id, err := neptulon.GenUID()
	if err != nil {
		return "", err
	}

	return id, c.WriteMsg(Request{ID: id, Method: method, Params: params})
}

// WriteRequestArr writes a JSON-RPC request to a client connection with array params and auto generated request ID.
func (c *Client) WriteRequestArr(method string, params ...interface{}) (reqID string, err error) {
	id, err := neptulon.GenUID()
	if err != nil {
		return "", err
	}

	return id, c.WriteMsg(Request{ID: id, Method: method, Params: params})
}

// WriteMsg writes any JSON-RPC message to a client connection.
func (c *Client) WriteMsg(msg interface{}) error {
	data, err := json.Marshal(msg)
	if err != nil {
		return err
	}

	if _, err := c.conn.Write(data); err != nil {
		return err
	}

	return nil
}

// Close closes a client connection.
func (c *Client) Close() error {
	return c.conn.Close()
}
<commit_msg>add Client.WriteNotification and array variant functions<commit_after>package jsonrpc

import (
	"encoding/json"
	"errors"

	"github.com/nbusy/neptulon"
)

// Client is a client implementation for JSON-RPC 2.0 protocol for Neptulon framework.
// Client implementations in other programming languages might be provided in separate repositories so check the documentation.
type Client struct {
	conn *neptulon.Conn
}

// Dial creates a new client connection to a given network address with optional CA and/or a client certificate (PEM encoded X.509 cert/key).
// Debug mode logs all raw TCP communication.
func Dial(addr string, ca []byte, clientCert []byte, clientCertKey []byte, debug bool) (*Client, error) {
	c, err := neptulon.Dial(addr, ca, clientCert, clientCertKey, debug)
	if err != nil {
		return nil, err
	}

	return &Client{conn: c}, nil
}

// SetReadDeadline set the read deadline for the connection in seconds.
func (c *Client) SetReadDeadline(seconds int) {
	c.conn.SetReadDeadline(seconds)
}

// ReadMsg reads a message off of a client connection and returns a request, response, or notification message depending on what server sent.
// Optionally, you can pass in a data structure that the returned JSON-RPC response result data will be serialized into. Otherwise the response result data will be a map.
func (c *Client) ReadMsg(resultData interface{}) (req *Request, res *Response, not *Notification, err error) {
	_, data, err := c.conn.Read()
	if err != nil {
		return
	}

	msg := message{Result: resultData}
	if err = json.Unmarshal(data, &msg); err != nil {
		return
	}

	// if incoming message is a request or response
	if msg.ID != "" {
		// if incoming message is a request
		if msg.Method != "" {
			req = &Request{ID: msg.ID, Method: msg.Method, Params: msg.Params}
			return
		}

		// if incoming message is a response
		res = &Response{ID: msg.ID, Result: msg.Result, Error: msg.Error}
		return
	}

	// if incoming message is a notification
	if msg.Method != "" {
		not = &Notification{Method: msg.Method, Params: msg.Params}
	}

	err = errors.New("Received a malformed message.")
	return
}

// WriteRequest writes a JSON-RPC request message to a client connection with structured params object and auto generated request ID.
func (c *Client) WriteRequest(method string, params interface{}) (reqID string, err error) {
	id, err := neptulon.GenUID()
	if err != nil {
		return "", err
	}

	return id, c.WriteMsg(Request{ID: id, Method: method, Params: params})
}

// WriteRequestArr writes a JSON-RPC request message to a client connection with array params and auto generated request ID.
func (c *Client) WriteRequestArr(method string, params ...interface{}) (reqID string, err error) {
	return c.WriteRequest(method, params)
}

// WriteNotification writes a JSON-RPC notification message to a client connection with structured params object.
func (c *Client) WriteNotification(method string, params interface{}) error {
	return c.WriteMsg(Notification{Method: method, Params: params})
}

// WriteNotificationArr writes a JSON-RPC notification message to a client connection with array params.
func (c *Client) WriteNotificationArr(method string, params ...interface{}) error {
	return c.WriteNotification(method, params)
}

// WriteMsg writes any JSON-RPC message to a client connection.
func (c *Client) WriteMsg(msg interface{}) error {
	data, err := json.Marshal(msg)
	if err != nil {
		return err
	}

	if _, err := c.conn.Write(data); err != nil {
		return err
	}

	return nil
}

// Close closes a client connection.
func (c *Client) Close() error {
	return c.conn.Close()
}
<|endoftext|>


<commit_before>package fileproxy

import (
	"bytes"
	"fmt"
	"github.com/disintegration/gift"
	"image"
	"image/gif"
	"path"

	"image/jpeg"
	"image/png"
	"io"
)

const (
	JPG  = ".jpg"
	JPEG = ".jpeg"
	GIF  = ".gif"
	PNG  = ".png"
)

func process(params *Params, filePath string, file *bytes.Buffer) (*bytes.Buffer, error) {
	if params.raw {
		return file, nil
	}

	ext := path.Ext(filePath)
	img, err := decode(ext, file)
	if err != nil {
		return nil, err
	}

	var dst image.Image

	if params.CropMode != "" {
		switch params.CropMode {
		case CropModeExact:
			dst = crop(img, params.Width, params.Height, params.CropPos)
		case CropModeScale:
			imgBound := img.Bounds()
			ratioX := float64(imgBound.Dx()) / float64(imgBound.Dy())
			ratioY := float64(imgBound.Dy()) / float64(imgBound.Dx())
			//wide
			if ratioX > ratioY {
				dst = resize(img, 0, params.Height)
			} else {
				dst = resize(img, params.Width, 0)
			}

			dst = crop(dst, params.Width, params.Height, params.CropPos)
		}
	} else {
		if params.Width > 1 || params.Height > 1 {
			dst = resize(img, params.Width, params.Height)
		} else {
			dst = img
		}
	}

	file.Reset()
	err = encode(file, ext, dst, params)
	return file, err
}

func resize(img image.Image, width, height int) image.Image {
	imgBound := img.Bounds()

	g := gift.New()

	g.Add(gift.Resize(width, height, gift.LanczosResampling))

	dst := image.NewRGBA(g.Bounds(imgBound))
	g.Draw(dst, img)

	return dst
}

func crop(img image.Image, width, height int, pos string) image.Image {
	imgBound := img.Bounds()
	if width < 1 {
		width = imgBound.Dx()
	}
	if height < 1 {
		height = imgBound.Dy()
	}

	x0, y0, x1, y1 := getCropPos(pos, width, height, imgBound.Dx(), imgBound.Dy())

	g := gift.New()
	g.Add(gift.Crop(image.Rect(x0, y0, x1, y1)))

	dst := image.NewRGBA(g.Bounds(imgBound))
	g.Draw(dst, img)

	return dst
}

func getCropPos(pos string, width, height, bx, by int) (int, int, int, int) {
	switch pos {
	case CropTopLeft:
		return 0, 0, width, height
	case CropTopCenter:
		x0 := getTopLeft(bx, width)
		return x0, 0, x0 + width, height
	case CropTopRight:
		return bx - width, 0, bx, height
	case CropMiddleLeft:
		y0 := getTopLeft(by, height)
		return 0, y0, width, y0 + height
	case CropMiddleCenter:
		x0 := getTopLeft(bx, width)
		y0 := getTopLeft(by, height)
		return x0, y0, x0 + width, y0 + height
	case CropMiddleRight:
		y0 := getTopLeft(by, height)
		return bx - width, y0, bx, y0 + height
	case CropBottomLeft:
		return 0, by, width, by - height
	case CropBottomCenter:
		x0 := getTopLeft(bx, width)
		return x0, by - height, x0 + width, by
	case CropBottomRight:
		return bx - width, by - height, bx, by
	}

	return 0, 0, bx, by
}

func getTopLeft(bound, dis int) int {
	return (bound - dis) / 2
}

func encode(bf io.Writer, ext string, img image.Image, params *Params) error {
	switch ext {
	case JPG, JPEG:
		return jpeg.Encode(bf, img, &jpeg.Options{Quality: params.Quality})
	case PNG:
		return png.Encode(bf, img)
	case GIF:
		return gif.Encode(bf, img, nil)
	default:
		return fmt.Errorf(`unsupported image format: "%s"`, ext)
	}
}

func decode(ext string, r io.Reader) (image.Image, error) {
	switch ext {
	case JPG, JPEG:
		return jpeg.Decode(r)
	case PNG:
		return png.Decode(r)
	case GIF:
		return gif.Decode(r)
	default:
		return nil, fmt.Errorf(`unsupported image format: "%s"`, ext)
	}
}
<commit_msg>change filter<commit_after>package fileproxy

import (
	"bytes"
	"fmt"
	"github.com/disintegration/gift"
	"image"
	"image/gif"
	"path"

	"image/jpeg"
	"image/png"
	"io"
)

const (
	JPG  = ".jpg"
	JPEG = ".jpeg"
	GIF  = ".gif"
	PNG  = ".png"
)

func process(params *Params, filePath string, file *bytes.Buffer) (*bytes.Buffer, error) {
	if params.raw {
		return file, nil
	}

	ext := path.Ext(filePath)
	img, err := decode(ext, file)
	if err != nil {
		return nil, err
	}

	var dst image.Image

	if params.CropMode != "" {
		switch params.CropMode {
		case CropModeExact:
			dst = crop(img, params.Width, params.Height, params.CropPos)
		case CropModeScale:
			imgBound := img.Bounds()
			ratioX := float64(imgBound.Dx()) / float64(imgBound.Dy())
			ratioY := float64(imgBound.Dy()) / float64(imgBound.Dx())
			//wide
			if ratioX > ratioY {
				dst = resize(img, 0, params.Height)
			} else {
				dst = resize(img, params.Width, 0)
			}

			dst = crop(dst, params.Width, params.Height, params.CropPos)
		}
	} else {
		if params.Width > 1 || params.Height > 1 {
			dst = resize(img, params.Width, params.Height)
		} else {
			dst = img
		}
	}

	file.Reset()
	err = encode(file, ext, dst, params)
	return file, err
}

func resize(img image.Image, width, height int) image.Image {
	imgBound := img.Bounds()

	g := gift.New()

	g.Add(gift.Resize(width, height, gift.LinearResampling))

	dst := image.NewRGBA(g.Bounds(imgBound))
	g.Draw(dst, img)

	return dst
}

func crop(img image.Image, width, height int, pos string) image.Image {
	imgBound := img.Bounds()
	if width < 1 {
		width = imgBound.Dx()
	}
	if height < 1 {
		height = imgBound.Dy()
	}

	x0, y0, x1, y1 := getCropPos(pos, width, height, imgBound.Dx(), imgBound.Dy())

	g := gift.New()
	g.Add(gift.Crop(image.Rect(x0, y0, x1, y1)))

	dst := image.NewRGBA(g.Bounds(imgBound))
	g.Draw(dst, img)

	return dst
}

func getCropPos(pos string, width, height, bx, by int) (int, int, int, int) {
	switch pos {
	case CropTopLeft:
		return 0, 0, width, height
	case CropTopCenter:
		x0 := getTopLeft(bx, width)
		return x0, 0, x0 + width, height
	case CropTopRight:
		return bx - width, 0, bx, height
	case CropMiddleLeft:
		y0 := getTopLeft(by, height)
		return 0, y0, width, y0 + height
	case CropMiddleCenter:
		x0 := getTopLeft(bx, width)
		y0 := getTopLeft(by, height)
		return x0, y0, x0 + width, y0 + height
	case CropMiddleRight:
		y0 := getTopLeft(by, height)
		return bx - width, y0, bx, y0 + height
	case CropBottomLeft:
		return 0, by, width, by - height
	case CropBottomCenter:
		x0 := getTopLeft(bx, width)
		return x0, by - height, x0 + width, by
	case CropBottomRight:
		return bx - width, by - height, bx, by
	}

	return 0, 0, bx, by
}

func getTopLeft(bound, dis int) int {
	return (bound - dis) / 2
}

func encode(bf io.Writer, ext string, img image.Image, params *Params) error {
	switch ext {
	case JPG, JPEG:
		return jpeg.Encode(bf, img, &jpeg.Options{Quality: params.Quality})
	case PNG:
		return png.Encode(bf, img)
	case GIF:
		return gif.Encode(bf, img, nil)
	default:
		return fmt.Errorf(`unsupported image format: "%s"`, ext)
	}
}

func decode(ext string, r io.Reader) (image.Image, error) {
	switch ext {
	case JPG, JPEG:
		return jpeg.Decode(r)
	case PNG:
		return png.Decode(r)
	case GIF:
		return gif.Decode(r)
	default:
		return nil, fmt.Errorf(`unsupported image format: "%s"`, ext)
	}
}
<|endoftext|>


<commit_before>// Package profile provides a simple way to manage runtime/pprof
// profiling of your Go application.
package profile

import (
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"path/filepath"
	"runtime"
	"runtime/pprof"
	"time"
)

// Config controls the operation of the profile package.
type Config struct {
	// Quiet suppresses informational messages during profiling.
	Quiet bool

	// CPUProfile controls if cpu profiling will be enabled.
	// It defaults to false.
	CPUProfile bool

	// MemProfile controls if memory profiling will be enabled.
	// It defaults to false.
	MemProfile bool

	// BlockProfile controls if block (contention) profiling will
	// be enabled.
	// It defaults to false.
	BlockProfile bool

	// ProfilePath controls the base path where various profiling
	// files are written. If blank, the base path will be generated
	// by ioutil.TempDir.
	ProfilePath string

	// NoShutdownHook controls whether the profiling package should
	// hook SIGINT to write profiles cleanly.
	// Programs with more sophisticated signal handling should set
	// this to true and ensure the Stop() function returned from Start()
	// is called during shutdown.
	NoShutdownHook bool
}

var zeroConfig Config

const memProfileRate = 4096

func defaultConfig() *Config { return &zeroConfig }

var (
	CPUProfile = &Config{
		CPUProfile: true,
	}

	MemProfile = &Config{
		MemProfile: true,
	}

	BlockProfile = &Config{
		BlockProfile: true,
	}
)

type profile struct {
	path string
	*Config
	closers []func()
}

func (p *profile) Stop() {
	for _, c := range p.closers {
		c()
	}
}

// Start starts a new profiling session configured using *Config.
// The caller should call the Stop method on the value returned
// to cleanly stop profiling.
// Passing a nil *Config is the same as passing a *Config with
// defaults chosen.
func Start(cfg *Config) interface {
	Stop()
} {
	if cfg == nil {
		cfg = defaultConfig()
	}
	path := cfg.ProfilePath
	var err error
	if path == "" {
		path, err = ioutil.TempDir("", "profile")
	} else {
		err = os.MkdirAll(path, 0777)
	}
	if err != nil {
		log.Fatalf("profile: could not create initial output directory: %v", err)
	}
	prof := &profile{
		path:   path,
		Config: cfg,
	}

	if prof.CPUProfile {
		fn := filepath.Join(prof.path, "cpu.pprof")
		f, err := os.Create(fn)
		if err != nil {
			log.Fatalf("profile: could not create cpu profile %q: %v", fn, err)
		}
		if !prof.Quiet {
			log.Printf("profile: cpu profiling enabled, %s", fn)
			snapshot := time.Now()
		}
		pprof.StartCPUProfile(f)
		prof.closers = append(prof.closers, func() {
			pprof.StopCPUProfile()
			if !prof.Quiet {
				log.Println(time.Since(snapshot))
			}
			f.Close()
		})
	}

	if prof.MemProfile {
		fn := filepath.Join(prof.path, "mem.pprof")
		f, err := os.Create(fn)
		if err != nil {
			log.Fatalf("profile: could not create memory profile %q: %v", fn, err)
		}
		old := runtime.MemProfileRate
		runtime.MemProfileRate = memProfileRate
		if !prof.Quiet {
			log.Printf("profile: memory profiling enabled, %s", fn)
		}
		prof.closers = append(prof.closers, func() {
			pprof.Lookup("heap").WriteTo(f, 0)
			f.Close()
			runtime.MemProfileRate = old
		})
	}

	if prof.BlockProfile {
		fn := filepath.Join(prof.path, "block.pprof")
		f, err := os.Create(fn)
		if err != nil {
			log.Fatalf("profile: could not create block profile %q: %v", fn, err)
		}
		runtime.SetBlockProfileRate(1)
		if !prof.Quiet {
			log.Printf("profile: block profiling enabled, %s", fn)
		}
		prof.closers = append(prof.closers, func() {
			pprof.Lookup("block").WriteTo(f, 0)
			f.Close()
			runtime.SetBlockProfileRate(0)
		})
	}

	if !prof.NoShutdownHook {
		go func() {
			c := make(chan os.Signal, 1)
			signal.Notify(c, os.Interrupt)
			<-c

			log.Println("profile: caught interrupt, stopping profiles")
			prof.Stop()

			os.Exit(0)
		}()
	}

	return prof
}
<commit_msg>add timestamp<commit_after>// Package profile provides a simple way to manage runtime/pprof
// profiling of your Go application.
package profile

import (
	"io/ioutil"
	"log"
	"os"
	"os/signal"
	"path/filepath"
	"runtime"
	"runtime/pprof"
	"time"
)

// Config controls the operation of the profile package.
type Config struct {
	// Quiet suppresses informational messages during profiling.
	Quiet bool

	// CPUProfile controls if cpu profiling will be enabled.
	// It defaults to false.
	CPUProfile bool

	// MemProfile controls if memory profiling will be enabled.
	// It defaults to false.
	MemProfile bool

	// BlockProfile controls if block (contention) profiling will
	// be enabled.
	// It defaults to false.
	BlockProfile bool

	// ProfilePath controls the base path where various profiling
	// files are written. If blank, the base path will be generated
	// by ioutil.TempDir.
	ProfilePath string

	// NoShutdownHook controls whether the profiling package should
	// hook SIGINT to write profiles cleanly.
	// Programs with more sophisticated signal handling should set
	// this to true and ensure the Stop() function returned from Start()
	// is called during shutdown.
	NoShutdownHook bool
}

var zeroConfig Config

const memProfileRate = 4096

func defaultConfig() *Config { return &zeroConfig }

var (
	CPUProfile = &Config{
		CPUProfile: true,
	}

	MemProfile = &Config{
		MemProfile: true,
	}

	BlockProfile = &Config{
		BlockProfile: true,
	}
)

type profile struct {
	path string
	*Config
	closers []func()
}

func (p *profile) Stop() {
	for _, c := range p.closers {
		c()
	}
}

// Start starts a new profiling session configured using *Config.
// The caller should call the Stop method on the value returned
// to cleanly stop profiling.
// Passing a nil *Config is the same as passing a *Config with
// defaults chosen.
func Start(cfg *Config) interface {
	Stop()
} {
	if cfg == nil {
		cfg = defaultConfig()
	}
	path := cfg.ProfilePath
	var err error
	if path == "" {
		path, err = ioutil.TempDir("", "profile")
	} else {
		err = os.MkdirAll(path, 0777)
	}
	if err != nil {
		log.Fatalf("profile: could not create initial output directory: %v", err)
	}
	prof := &profile{
		path:   path,
		Config: cfg,
	}

	if prof.CPUProfile {
		fn := filepath.Join(prof.path, "cpu.pprof")
		f, err := os.Create(fn)
		if err != nil {
			log.Fatalf("profile: could not create cpu profile %q: %v", fn, err)
		}
		var snapshot time.Time
		if !prof.Quiet {
			log.Printf("profile: cpu profiling enabled, %s", fn)
			snapshot = time.Now()
		}
		pprof.StartCPUProfile(f)
		prof.closers = append(prof.closers, func() {
			pprof.StopCPUProfile()
			if !prof.Quiet {
				log.Println(time.Since(snapshot))
			}
			f.Close()
		})
	}

	if prof.MemProfile {
		fn := filepath.Join(prof.path, "mem.pprof")
		f, err := os.Create(fn)
		if err != nil {
			log.Fatalf("profile: could not create memory profile %q: %v", fn, err)
		}
		old := runtime.MemProfileRate
		runtime.MemProfileRate = memProfileRate
		if !prof.Quiet {
			log.Printf("profile: memory profiling enabled, %s", fn)
		}
		prof.closers = append(prof.closers, func() {
			pprof.Lookup("heap").WriteTo(f, 0)
			f.Close()
			runtime.MemProfileRate = old
		})
	}

	if prof.BlockProfile {
		fn := filepath.Join(prof.path, "block.pprof")
		f, err := os.Create(fn)
		if err != nil {
			log.Fatalf("profile: could not create block profile %q: %v", fn, err)
		}
		runtime.SetBlockProfileRate(1)
		if !prof.Quiet {
			log.Printf("profile: block profiling enabled, %s", fn)
		}
		prof.closers = append(prof.closers, func() {
			pprof.Lookup("block").WriteTo(f, 0)
			f.Close()
			runtime.SetBlockProfileRate(0)
		})
	}

	if !prof.NoShutdownHook {
		go func() {
			c := make(chan os.Signal, 1)
			signal.Notify(c, os.Interrupt)
			<-c

			log.Println("profile: caught interrupt, stopping profiles")
			prof.Stop()

			os.Exit(0)
		}()
	}

	return prof
}
<|endoftext|>


<commit_before>/*
Copyright 2015 The Kubernetes Authors.

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

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

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

package common

import (
	"fmt"
	"time"

	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/util/intstr"
	"k8s.io/kubernetes/pkg/util/uuid"
	"k8s.io/kubernetes/test/e2e/framework"

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

const (
	probTestContainerName       = "test-webserver"
	probTestInitialDelaySeconds = 15

	defaultObservationTimeout = time.Minute * 2
)

var _ = framework.KubeDescribe("Probing container", func() {
	f := framework.NewDefaultFramework("container-probe")
	var podClient *framework.PodClient
	probe := webserverProbeBuilder{}

	BeforeEach(func() {
		podClient = f.PodClient()
	})

	It("with readiness probe should not be ready before initial delay and never restart [Conformance]", func() {
		p := podClient.Create(makePodSpec(probe.withInitialDelay().build(), nil))
		f.WaitForPodReady(p.Name)

		p, err := podClient.Get(p.Name)
		framework.ExpectNoError(err)
		isReady, err := framework.PodRunningReady(p)
		framework.ExpectNoError(err)
		Expect(isReady).To(BeTrue(), "pod should be ready")

		// We assume the pod became ready when the container became ready. This
		// is true for a single container pod.
		readyTime, err := getTransitionTimeForReadyCondition(p)
		framework.ExpectNoError(err)
		startedTime, err := getContainerStartedTime(p, probTestContainerName)
		framework.ExpectNoError(err)

		framework.Logf("Container started at %v, pod became ready at %v", startedTime, readyTime)
		initialDelay := probTestInitialDelaySeconds * time.Second
		if readyTime.Sub(startedTime) < initialDelay {
			framework.Failf("Pod became ready before it's %v initial delay", initialDelay)
		}

		restartCount := getRestartCount(p)
		Expect(restartCount == 0).To(BeTrue(), "pod should have a restart count of 0 but got %v", restartCount)
	})

	It("with readiness probe that fails should never be ready and never restart [Conformance]", func() {
		p := podClient.Create(makePodSpec(probe.withFailing().build(), nil))
		Consistently(func() (bool, error) {
			p, err := podClient.Get(p.Name)
			if err != nil {
				return false, err
			}
			return api.IsPodReady(p), nil
		}, 1*time.Minute, 1*time.Second).ShouldNot(BeTrue(), "pod should not be ready")

		p, err := podClient.Get(p.Name)
		framework.ExpectNoError(err)

		isReady, err := framework.PodRunningReady(p)
		Expect(isReady).NotTo(BeTrue(), "pod should be not ready")

		restartCount := getRestartCount(p)
		Expect(restartCount == 0).To(BeTrue(), "pod should have a restart count of 0 but got %v", restartCount)
	})

	It("should be restarted with a exec \"cat /tmp/health\" liveness probe [Conformance]", func() {
		runLivenessTest(f, &api.Pod{
			ObjectMeta: api.ObjectMeta{
				Name:   "liveness-exec",
				Labels: map[string]string{"test": "liveness"},
			},
			Spec: api.PodSpec{
				Containers: []api.Container{
					{
						Name:    "liveness",
						Image:   "gcr.io/google_containers/busybox:1.24",
						Command: []string{"/bin/sh", "-c", "echo ok >/tmp/health; sleep 10; rm -rf /tmp/health; sleep 600"},
						LivenessProbe: &api.Probe{
							Handler: api.Handler{
								Exec: &api.ExecAction{
									Command: []string{"cat", "/tmp/health"},
								},
							},
							InitialDelaySeconds: 15,
							FailureThreshold:    1,
						},
					},
				},
			},
		}, 1, defaultObservationTimeout)
	})

	It("should *not* be restarted with a exec \"cat /tmp/health\" liveness probe [Conformance]", func() {
		runLivenessTest(f, &api.Pod{
			ObjectMeta: api.ObjectMeta{
				Name:   "liveness-exec",
				Labels: map[string]string{"test": "liveness"},
			},
			Spec: api.PodSpec{
				Containers: []api.Container{
					{
						Name:    "liveness",
						Image:   "gcr.io/google_containers/busybox:1.24",
						Command: []string{"/bin/sh", "-c", "echo ok >/tmp/health; sleep 600"},
						LivenessProbe: &api.Probe{
							Handler: api.Handler{
								Exec: &api.ExecAction{
									Command: []string{"cat", "/tmp/health"},
								},
							},
							InitialDelaySeconds: 15,
							FailureThreshold:    1,
						},
					},
				},
			},
		}, 0, defaultObservationTimeout)
	})

	It("should be restarted with a /healthz http liveness probe [Conformance]", func() {
		runLivenessTest(f, &api.Pod{
			ObjectMeta: api.ObjectMeta{
				Name:   "liveness-http",
				Labels: map[string]string{"test": "liveness"},
			},
			Spec: api.PodSpec{
				Containers: []api.Container{
					{
						Name:    "liveness",
						Image:   "gcr.io/google_containers/liveness:e2e",
						Command: []string{"/server"},
						LivenessProbe: &api.Probe{
							Handler: api.Handler{
								HTTPGet: &api.HTTPGetAction{
									Path: "/healthz",
									Port: intstr.FromInt(8080),
								},
							},
							InitialDelaySeconds: 15,
							FailureThreshold:    1,
						},
					},
				},
			},
		}, 1, defaultObservationTimeout)
	})

	// Slow by design (5 min)
	It("should have monotonically increasing restart count [Conformance] [Slow]", func() {
		runLivenessTest(f, &api.Pod{
			ObjectMeta: api.ObjectMeta{
				Name:   "liveness-http",
				Labels: map[string]string{"test": "liveness"},
			},
			Spec: api.PodSpec{
				Containers: []api.Container{
					{
						Name:    "liveness",
						Image:   "gcr.io/google_containers/liveness:e2e",
						Command: []string{"/server"},
						LivenessProbe: &api.Probe{
							Handler: api.Handler{
								HTTPGet: &api.HTTPGetAction{
									Path: "/healthz",
									Port: intstr.FromInt(8080),
								},
							},
							InitialDelaySeconds: 5,
							FailureThreshold:    1,
						},
					},
				},
			},
		}, 5, time.Minute*5)
	})

	It("should *not* be restarted with a /healthz http liveness probe [Conformance]", func() {
		runLivenessTest(f, &api.Pod{
			ObjectMeta: api.ObjectMeta{
				Name:   "liveness-http",
				Labels: map[string]string{"test": "liveness"},
			},
			Spec: api.PodSpec{
				Containers: []api.Container{
					{
						Name:  "liveness",
						Image: "gcr.io/google_containers/nginx-slim:0.7",
						Ports: []api.ContainerPort{{ContainerPort: 80}},
						LivenessProbe: &api.Probe{
							Handler: api.Handler{
								HTTPGet: &api.HTTPGetAction{
									Path: "/",
									Port: intstr.FromInt(80),
								},
							},
							InitialDelaySeconds: 15,
							FailureThreshold:    1,
						},
					},
				},
			},
		}, 0, defaultObservationTimeout)
	})

})

func getContainerStartedTime(p *api.Pod, containerName string) (time.Time, error) {
	for _, status := range p.Status.ContainerStatuses {
		if status.Name != containerName {
			continue
		}
		if status.State.Running == nil {
			return time.Time{}, fmt.Errorf("Container is not running")
		}
		return status.State.Running.StartedAt.Time, nil
	}
	return time.Time{}, fmt.Errorf("cannot find container named %q", containerName)
}

func getTransitionTimeForReadyCondition(p *api.Pod) (time.Time, error) {
	for _, cond := range p.Status.Conditions {
		if cond.Type == api.PodReady {
			return cond.LastTransitionTime.Time, nil
		}
	}
	return time.Time{}, fmt.Errorf("No ready condition can be found for pod")
}

func getRestartCount(p *api.Pod) int {
	count := 0
	for _, containerStatus := range p.Status.ContainerStatuses {
		count += int(containerStatus.RestartCount)
	}
	return count
}

func makePodSpec(readinessProbe, livenessProbe *api.Probe) *api.Pod {
	pod := &api.Pod{
		ObjectMeta: api.ObjectMeta{Name: "test-webserver-" + string(uuid.NewUUID())},
		Spec: api.PodSpec{
			Containers: []api.Container{
				{
					Name:           probTestContainerName,
					Image:          "gcr.io/google_containers/test-webserver:e2e",
					LivenessProbe:  livenessProbe,
					ReadinessProbe: readinessProbe,
				},
			},
		},
	}
	return pod
}

type webserverProbeBuilder struct {
	failing      bool
	initialDelay bool
}

func (b webserverProbeBuilder) withFailing() webserverProbeBuilder {
	b.failing = true
	return b
}

func (b webserverProbeBuilder) withInitialDelay() webserverProbeBuilder {
	b.initialDelay = true
	return b
}

func (b webserverProbeBuilder) build() *api.Probe {
	probe := &api.Probe{
		Handler: api.Handler{
			HTTPGet: &api.HTTPGetAction{
				Port: intstr.FromInt(80),
				Path: "/",
			},
		},
	}
	if b.initialDelay {
		probe.InitialDelaySeconds = probTestInitialDelaySeconds
	}
	if b.failing {
		probe.HTTPGet.Port = intstr.FromInt(81)
	}
	return probe
}

func runLivenessTest(f *framework.Framework, pod *api.Pod, expectNumRestarts int, timeout time.Duration) {
	podClient := f.PodClient()
	ns := f.Namespace.Name
	Expect(pod.Spec.Containers).NotTo(BeEmpty())
	containerName := pod.Spec.Containers[0].Name
	// At the end of the test, clean up by removing the pod.
	defer func() {
		By("deleting the pod")
		podClient.Delete(pod.Name, api.NewDeleteOptions(0))
	}()
	By(fmt.Sprintf("Creating pod %s in namespace %s", pod.Name, ns))
	podClient.Create(pod)

	// Wait until the pod is not pending. (Here we need to check for something other than
	// 'Pending' other than checking for 'Running', since when failures occur, we go to
	// 'Terminated' which can cause indefinite blocking.)
	framework.ExpectNoError(framework.WaitForPodNotPending(f.Client, ns, pod.Name, pod.ResourceVersion),
		fmt.Sprintf("starting pod %s in namespace %s", pod.Name, ns))
	framework.Logf("Started pod %s in namespace %s", pod.Name, ns)

	// Check the pod's current state and verify that restartCount is present.
	By("checking the pod's current state and verifying that restartCount is present")
	pod, err := podClient.Get(pod.Name)
	framework.ExpectNoError(err, fmt.Sprintf("getting pod %s in namespace %s", pod.Name, ns))
	initialRestartCount := api.GetExistingContainerStatus(pod.Status.ContainerStatuses, containerName).RestartCount
	framework.Logf("Initial restart count of pod %s is %d", pod.Name, initialRestartCount)

	// Wait for the restart state to be as desired.
	deadline := time.Now().Add(timeout)
	lastRestartCount := initialRestartCount
	observedRestarts := int32(0)
	for start := time.Now(); time.Now().Before(deadline); time.Sleep(2 * time.Second) {
		pod, err = podClient.Get(pod.Name)
		framework.ExpectNoError(err, fmt.Sprintf("getting pod %s", pod.Name))
		restartCount := api.GetExistingContainerStatus(pod.Status.ContainerStatuses, containerName).RestartCount
		if restartCount != lastRestartCount {
			framework.Logf("Restart count of pod %s/%s is now %d (%v elapsed)",
				ns, pod.Name, restartCount, time.Since(start))
			if restartCount < lastRestartCount {
				framework.Failf("Restart count should increment monotonically: restart cont of pod %s/%s changed from %d to %d",
					ns, pod.Name, lastRestartCount, restartCount)
			}
		}
		observedRestarts = restartCount - initialRestartCount
		if expectNumRestarts > 0 && int(observedRestarts) >= expectNumRestarts {
			// Stop if we have observed more than expectNumRestarts restarts.
			break
		}
		lastRestartCount = restartCount
	}

	// If we expected 0 restarts, fail if observed any restart.
	// If we expected n restarts (n > 0), fail if we observed < n restarts.
	if (expectNumRestarts == 0 && observedRestarts > 0) || (expectNumRestarts > 0 &&
		int(observedRestarts) < expectNumRestarts) {
		framework.Failf("pod %s/%s - expected number of restarts: %d, found restarts: %d",
			ns, pod.Name, expectNumRestarts, observedRestarts)
	}
}
<commit_msg>Add back the original liveness check timeout.<commit_after>/*
Copyright 2015 The Kubernetes Authors.

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

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

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

package common

import (
	"fmt"
	"time"

	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/util/intstr"
	"k8s.io/kubernetes/pkg/util/uuid"
	"k8s.io/kubernetes/test/e2e/framework"

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

const (
	probTestContainerName       = "test-webserver"
	probTestInitialDelaySeconds = 15

	defaultObservationTimeout = time.Minute * 2
)

var _ = framework.KubeDescribe("Probing container", func() {
	f := framework.NewDefaultFramework("container-probe")
	var podClient *framework.PodClient
	probe := webserverProbeBuilder{}

	BeforeEach(func() {
		podClient = f.PodClient()
	})

	It("with readiness probe should not be ready before initial delay and never restart [Conformance]", func() {
		p := podClient.Create(makePodSpec(probe.withInitialDelay().build(), nil))
		f.WaitForPodReady(p.Name)

		p, err := podClient.Get(p.Name)
		framework.ExpectNoError(err)
		isReady, err := framework.PodRunningReady(p)
		framework.ExpectNoError(err)
		Expect(isReady).To(BeTrue(), "pod should be ready")

		// We assume the pod became ready when the container became ready. This
		// is true for a single container pod.
		readyTime, err := getTransitionTimeForReadyCondition(p)
		framework.ExpectNoError(err)
		startedTime, err := getContainerStartedTime(p, probTestContainerName)
		framework.ExpectNoError(err)

		framework.Logf("Container started at %v, pod became ready at %v", startedTime, readyTime)
		initialDelay := probTestInitialDelaySeconds * time.Second
		if readyTime.Sub(startedTime) < initialDelay {
			framework.Failf("Pod became ready before it's %v initial delay", initialDelay)
		}

		restartCount := getRestartCount(p)
		Expect(restartCount == 0).To(BeTrue(), "pod should have a restart count of 0 but got %v", restartCount)
	})

	It("with readiness probe that fails should never be ready and never restart [Conformance]", func() {
		p := podClient.Create(makePodSpec(probe.withFailing().build(), nil))
		Consistently(func() (bool, error) {
			p, err := podClient.Get(p.Name)
			if err != nil {
				return false, err
			}
			return api.IsPodReady(p), nil
		}, 1*time.Minute, 1*time.Second).ShouldNot(BeTrue(), "pod should not be ready")

		p, err := podClient.Get(p.Name)
		framework.ExpectNoError(err)

		isReady, err := framework.PodRunningReady(p)
		Expect(isReady).NotTo(BeTrue(), "pod should be not ready")

		restartCount := getRestartCount(p)
		Expect(restartCount == 0).To(BeTrue(), "pod should have a restart count of 0 but got %v", restartCount)
	})

	It("should be restarted with a exec \"cat /tmp/health\" liveness probe [Conformance]", func() {
		runLivenessTest(f, &api.Pod{
			ObjectMeta: api.ObjectMeta{
				Name:   "liveness-exec",
				Labels: map[string]string{"test": "liveness"},
			},
			Spec: api.PodSpec{
				Containers: []api.Container{
					{
						Name:    "liveness",
						Image:   "gcr.io/google_containers/busybox:1.24",
						Command: []string{"/bin/sh", "-c", "echo ok >/tmp/health; sleep 10; rm -rf /tmp/health; sleep 600"},
						LivenessProbe: &api.Probe{
							Handler: api.Handler{
								Exec: &api.ExecAction{
									Command: []string{"cat", "/tmp/health"},
								},
							},
							InitialDelaySeconds: 15,
							FailureThreshold:    1,
						},
					},
				},
			},
		}, 1, defaultObservationTimeout)
	})

	It("should *not* be restarted with a exec \"cat /tmp/health\" liveness probe [Conformance]", func() {
		runLivenessTest(f, &api.Pod{
			ObjectMeta: api.ObjectMeta{
				Name:   "liveness-exec",
				Labels: map[string]string{"test": "liveness"},
			},
			Spec: api.PodSpec{
				Containers: []api.Container{
					{
						Name:    "liveness",
						Image:   "gcr.io/google_containers/busybox:1.24",
						Command: []string{"/bin/sh", "-c", "echo ok >/tmp/health; sleep 600"},
						LivenessProbe: &api.Probe{
							Handler: api.Handler{
								Exec: &api.ExecAction{
									Command: []string{"cat", "/tmp/health"},
								},
							},
							InitialDelaySeconds: 15,
							FailureThreshold:    1,
						},
					},
				},
			},
		}, 0, defaultObservationTimeout)
	})

	It("should be restarted with a /healthz http liveness probe [Conformance]", func() {
		runLivenessTest(f, &api.Pod{
			ObjectMeta: api.ObjectMeta{
				Name:   "liveness-http",
				Labels: map[string]string{"test": "liveness"},
			},
			Spec: api.PodSpec{
				Containers: []api.Container{
					{
						Name:    "liveness",
						Image:   "gcr.io/google_containers/liveness:e2e",
						Command: []string{"/server"},
						LivenessProbe: &api.Probe{
							Handler: api.Handler{
								HTTPGet: &api.HTTPGetAction{
									Path: "/healthz",
									Port: intstr.FromInt(8080),
								},
							},
							InitialDelaySeconds: 15,
							FailureThreshold:    1,
						},
					},
				},
			},
		}, 1, defaultObservationTimeout)
	})

	// Slow by design (5 min)
	It("should have monotonically increasing restart count [Conformance] [Slow]", func() {
		runLivenessTest(f, &api.Pod{
			ObjectMeta: api.ObjectMeta{
				Name:   "liveness-http",
				Labels: map[string]string{"test": "liveness"},
			},
			Spec: api.PodSpec{
				Containers: []api.Container{
					{
						Name:    "liveness",
						Image:   "gcr.io/google_containers/liveness:e2e",
						Command: []string{"/server"},
						LivenessProbe: &api.Probe{
							Handler: api.Handler{
								HTTPGet: &api.HTTPGetAction{
									Path: "/healthz",
									Port: intstr.FromInt(8080),
								},
							},
							InitialDelaySeconds: 5,
							FailureThreshold:    1,
						},
					},
				},
			},
		}, 5, time.Minute*5)
	})

	It("should *not* be restarted with a /healthz http liveness probe [Conformance]", func() {
		runLivenessTest(f, &api.Pod{
			ObjectMeta: api.ObjectMeta{
				Name:   "liveness-http",
				Labels: map[string]string{"test": "liveness"},
			},
			Spec: api.PodSpec{
				Containers: []api.Container{
					{
						Name:  "liveness",
						Image: "gcr.io/google_containers/nginx-slim:0.7",
						Ports: []api.ContainerPort{{ContainerPort: 80}},
						LivenessProbe: &api.Probe{
							Handler: api.Handler{
								HTTPGet: &api.HTTPGetAction{
									Path: "/",
									Port: intstr.FromInt(80),
								},
							},
							InitialDelaySeconds: 15,
							TimeoutSeconds:      5,
							FailureThreshold:    1,
						},
					},
				},
			},
		}, 0, defaultObservationTimeout)
	})

})

func getContainerStartedTime(p *api.Pod, containerName string) (time.Time, error) {
	for _, status := range p.Status.ContainerStatuses {
		if status.Name != containerName {
			continue
		}
		if status.State.Running == nil {
			return time.Time{}, fmt.Errorf("Container is not running")
		}
		return status.State.Running.StartedAt.Time, nil
	}
	return time.Time{}, fmt.Errorf("cannot find container named %q", containerName)
}

func getTransitionTimeForReadyCondition(p *api.Pod) (time.Time, error) {
	for _, cond := range p.Status.Conditions {
		if cond.Type == api.PodReady {
			return cond.LastTransitionTime.Time, nil
		}
	}
	return time.Time{}, fmt.Errorf("No ready condition can be found for pod")
}

func getRestartCount(p *api.Pod) int {
	count := 0
	for _, containerStatus := range p.Status.ContainerStatuses {
		count += int(containerStatus.RestartCount)
	}
	return count
}

func makePodSpec(readinessProbe, livenessProbe *api.Probe) *api.Pod {
	pod := &api.Pod{
		ObjectMeta: api.ObjectMeta{Name: "test-webserver-" + string(uuid.NewUUID())},
		Spec: api.PodSpec{
			Containers: []api.Container{
				{
					Name:           probTestContainerName,
					Image:          "gcr.io/google_containers/test-webserver:e2e",
					LivenessProbe:  livenessProbe,
					ReadinessProbe: readinessProbe,
				},
			},
		},
	}
	return pod
}

type webserverProbeBuilder struct {
	failing      bool
	initialDelay bool
}

func (b webserverProbeBuilder) withFailing() webserverProbeBuilder {
	b.failing = true
	return b
}

func (b webserverProbeBuilder) withInitialDelay() webserverProbeBuilder {
	b.initialDelay = true
	return b
}

func (b webserverProbeBuilder) build() *api.Probe {
	probe := &api.Probe{
		Handler: api.Handler{
			HTTPGet: &api.HTTPGetAction{
				Port: intstr.FromInt(80),
				Path: "/",
			},
		},
	}
	if b.initialDelay {
		probe.InitialDelaySeconds = probTestInitialDelaySeconds
	}
	if b.failing {
		probe.HTTPGet.Port = intstr.FromInt(81)
	}
	return probe
}

func runLivenessTest(f *framework.Framework, pod *api.Pod, expectNumRestarts int, timeout time.Duration) {
	podClient := f.PodClient()
	ns := f.Namespace.Name
	Expect(pod.Spec.Containers).NotTo(BeEmpty())
	containerName := pod.Spec.Containers[0].Name
	// At the end of the test, clean up by removing the pod.
	defer func() {
		By("deleting the pod")
		podClient.Delete(pod.Name, api.NewDeleteOptions(0))
	}()
	By(fmt.Sprintf("Creating pod %s in namespace %s", pod.Name, ns))
	podClient.Create(pod)

	// Wait until the pod is not pending. (Here we need to check for something other than
	// 'Pending' other than checking for 'Running', since when failures occur, we go to
	// 'Terminated' which can cause indefinite blocking.)
	framework.ExpectNoError(framework.WaitForPodNotPending(f.Client, ns, pod.Name, pod.ResourceVersion),
		fmt.Sprintf("starting pod %s in namespace %s", pod.Name, ns))
	framework.Logf("Started pod %s in namespace %s", pod.Name, ns)

	// Check the pod's current state and verify that restartCount is present.
	By("checking the pod's current state and verifying that restartCount is present")
	pod, err := podClient.Get(pod.Name)
	framework.ExpectNoError(err, fmt.Sprintf("getting pod %s in namespace %s", pod.Name, ns))
	initialRestartCount := api.GetExistingContainerStatus(pod.Status.ContainerStatuses, containerName).RestartCount
	framework.Logf("Initial restart count of pod %s is %d", pod.Name, initialRestartCount)

	// Wait for the restart state to be as desired.
	deadline := time.Now().Add(timeout)
	lastRestartCount := initialRestartCount
	observedRestarts := int32(0)
	for start := time.Now(); time.Now().Before(deadline); time.Sleep(2 * time.Second) {
		pod, err = podClient.Get(pod.Name)
		framework.ExpectNoError(err, fmt.Sprintf("getting pod %s", pod.Name))
		restartCount := api.GetExistingContainerStatus(pod.Status.ContainerStatuses, containerName).RestartCount
		if restartCount != lastRestartCount {
			framework.Logf("Restart count of pod %s/%s is now %d (%v elapsed)",
				ns, pod.Name, restartCount, time.Since(start))
			if restartCount < lastRestartCount {
				framework.Failf("Restart count should increment monotonically: restart cont of pod %s/%s changed from %d to %d",
					ns, pod.Name, lastRestartCount, restartCount)
			}
		}
		observedRestarts = restartCount - initialRestartCount
		if expectNumRestarts > 0 && int(observedRestarts) >= expectNumRestarts {
			// Stop if we have observed more than expectNumRestarts restarts.
			break
		}
		lastRestartCount = restartCount
	}

	// If we expected 0 restarts, fail if observed any restart.
	// If we expected n restarts (n > 0), fail if we observed < n restarts.
	if (expectNumRestarts == 0 && observedRestarts > 0) || (expectNumRestarts > 0 &&
		int(observedRestarts) < expectNumRestarts) {
		framework.Failf("pod %s/%s - expected number of restarts: %d, found restarts: %d",
			ns, pod.Name, expectNumRestarts, observedRestarts)
	}
}
<|endoftext|>


<commit_before>package authorization

import (
	"context"
	"fmt"
	"strings"

	g "github.com/onsi/ginkgo"
	o "github.com/onsi/gomega"
	exutil "github.com/openshift/origin/test/extended/util"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ = g.Describe("[sig-auth][Feature:SCC][Early]", func() {
	defer g.GinkgoRecover()

	oc := exutil.NewCLIWithoutNamespace("working-scc-during-install")

	g.It("should not have pod creation failures during install", func() {
		kubeClient := oc.AdminKubeClient()

		isFIPS, err := exutil.IsFIPS(kubeClient.CoreV1())
		o.Expect(err).NotTo(o.HaveOccurred())
		// deads2k chose five as a number that passes nearly all the time on 4.6.  If this gets worse, we should double check against 4.6.
		// if I was wrong about 4.6, then adjust this up.  If I am right about 4.6, then fix whatever regressed this.
		// Because the CVO starts a static pod that races with the cluster-policy-controller, it is impractical to get this value to 0.
		numFailuresForFail := 5
		if isFIPS {
			// for whatever reason, fips fails more frequently.  this isn't good and it's bad practice to have platform
			// dependent tests, but we need to start the ratchet somewhere to prevent regressions.
			numFailuresForFail = 10
		}

		events, err := kubeClient.CoreV1().Events("").List(context.TODO(), metav1.ListOptions{})
		o.Expect(err).NotTo(o.HaveOccurred())

		denialStrings := []string{}
		for _, event := range events.Items {
			if !strings.Contains(event.Message, "unable to validate against any security context constraint") {
				continue
			}
			// TODO if we need more details, this is a good guess.
			//eventBytes, err := json.Marshal(event)
			//if err != nil {
			//	e2e.Logf("%v", spew.Sdump(event))
			//} else {
			//	e2e.Logf("%v", string(eventBytes))
			//}
			// try with a short summary we can actually read first
			denialString := fmt.Sprintf("%v for %v.%v/%v -n %v happened %d times", event.Message, event.InvolvedObject.Kind, event.InvolvedObject.APIVersion, event.InvolvedObject.Name, event.InvolvedObject.Namespace, event.Count)
			denialStrings = append(denialStrings, denialString)
		}

		numFailingPods := len(denialStrings)
		failMessage := fmt.Sprintf("%d pods failed on SCC errors\n%s\n", numFailingPods, strings.Join(denialStrings, "\n"))
		if numFailingPods > numFailuresForFail {
			g.Fail(failMessage)
			return
		}

		// given a low threshold, there isn't much space left to mark a flake over a fail.
		//result.Flakef(failMessage)
	})
})
<commit_msg>refine SCC check to take into account the pod delay before failure<commit_after>package authorization

import (
	"context"
	"fmt"
	"strings"
	"time"

	g "github.com/onsi/ginkgo"
	o "github.com/onsi/gomega"
	exutil "github.com/openshift/origin/test/extended/util"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

var _ = g.Describe("[sig-auth][Feature:SCC][Early]", func() {
	defer g.GinkgoRecover()

	oc := exutil.NewCLIWithoutNamespace("working-scc-during-install")

	g.It("should not have pod creation failures during install", func() {
		kubeClient := oc.AdminKubeClient()

		isFIPS, err := exutil.IsFIPS(kubeClient.CoreV1())
		o.Expect(err).NotTo(o.HaveOccurred())
		// deads2k chose five as a number that passes nearly all the time on 4.6.  If this gets worse, we should double check against 4.6.
		// if I was wrong about 4.6, then adjust this up.  If I am right about 4.6, then fix whatever regressed this.
		// Because the CVO starts a static pod that races with the cluster-policy-controller, it is impractical to get this value to 0.
		numFailuresForFail := 5
		if isFIPS {
			// for whatever reason, fips fails more frequently.  this isn't good and it's bad practice to have platform
			// dependent tests, but we need to start the ratchet somewhere to prevent regressions.
			numFailuresForFail = 10
		}

		events, err := kubeClient.CoreV1().Events("").List(context.TODO(), metav1.ListOptions{})
		o.Expect(err).NotTo(o.HaveOccurred())

		denialStrings := []string{}
		for _, event := range events.Items {
			if !strings.Contains(event.Message, "unable to validate against any security context constraint") {
				continue
			}
			// SCCs become accessible to serviceaccounts based on RBAC resources.  We could require that every operator
			// apply their RBAC in order with respect to their operands by checking SARs against every kube-apiserver endpoint
			// and ensuring that the "use" for an SCC comes back correctly, but that isn't very useful.
			// We don't want to delay pods for an excessive period of time, so we will catch those pods that take more
			// than five seconds to make it through SCC
			durationPodFailed := event.LastTimestamp.Sub(event.FirstTimestamp.Time)
			if durationPodFailed < 5*time.Second {
				continue
			}
			// TODO if we need more details, this is a good guess.
			//eventBytes, err := json.Marshal(event)
			//if err != nil {
			//	e2e.Logf("%v", spew.Sdump(event))
			//} else {
			//	e2e.Logf("%v", string(eventBytes))
			//}
			// try with a short summary we can actually read first
			denialString := fmt.Sprintf("%v for %v.%v/%v -n %v happened %d times", event.Message, event.InvolvedObject.Kind, event.InvolvedObject.APIVersion, event.InvolvedObject.Name, event.InvolvedObject.Namespace, event.Count)
			denialStrings = append(denialStrings, denialString)
		}

		numFailingPods := len(denialStrings)
		failMessage := fmt.Sprintf("%d pods failed on SCC errors\n%s\n", numFailingPods, strings.Join(denialStrings, "\n"))
		if numFailingPods > numFailuresForFail {
			g.Fail(failMessage)
			return
		}

		// given a low threshold, there isn't much space left to mark a flake over a fail.
		//result.Flakef(failMessage)
	})
})
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
)

type Program struct {
	Name        string
	CommandPath string
}

const BUFFER_SIZE = 1000

const (
	Success   = 0
	Retryable = 1
	Failed    = 2
)

func (p *Program) Execute() (chan string, error) {
	log.Println("executing", p.CommandPath)
	cmd := exec.Command(p.CommandPath)

	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}

	err = cmd.Start()
	if err != nil {
		return nil, err
	}

	// go func() {
	//	log.Println("waiting to finish", p.Name)
	//	cmd.Wait()
	//	log.Println("finished", p.Name)
	// }()

	messages := make(chan string, BUFFER_SIZE)

	go func() {
		scanner := bufio.NewScanner(stdout)

		for scanner.Scan() {
			s := scanner.Text()
			log.Println(p.Name, s)
			messages <- s
		}

		if err := scanner.Err(); err != nil {
			log.Println("scanner error", err)
		}
	}()

	return messages, nil
}

func readDir(dir string) ([]*Program, error) {
	log.Println("looking for programs in", dir)
	infos, err := ioutil.ReadDir(dir)
	if err != nil {
		return nil, err
	}

	programs := []*Program{}

	for _, info := range infos {
		commandPath := filepath.Join(dir, info.Name(), "main")
		_, err := os.Stat(commandPath)

		if err == nil {
			log.Println("program executable:", commandPath)

			programs = append(programs, &Program{info.Name(), commandPath})
		}
	}

	return programs, nil
}
<commit_msg>add goroutine to check for command exit status. sends messages to subscribers.<commit_after>package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"syscall"
)

type Program struct {
	Name        string
	CommandPath string
}

const BUFFER_SIZE = 1000

const (
	Success   = 0
	Retryable = 1
	Failed    = 2
)

func (p *Program) Execute() (chan string, error) {
	log.Println("executing", p.CommandPath)
	cmd := exec.Command(p.CommandPath)

	stdout, err := cmd.StdoutPipe()
	if err != nil {
		return nil, err
	}

	err = cmd.Start()
	if err != nil {
		return nil, err
	}

	messages := make(chan string, BUFFER_SIZE)

	go func() {
		log.Println(p.Name, "waiting to complete")
		err := cmd.Wait()
		if err == nil {
			log.Println(p.Name, "successfully completed")
			messages<-fmt.Sprintln("successfully completed")
			return
		}

		exitError := err.(*exec.ExitError)
		waitStatus := exitError.Sys().(syscall.WaitStatus)
		exitCode := waitStatus.ExitStatus()
		log.Println(p.Name, "exited with status", exitCode)

		messages<-fmt.Sprintln("exited with status", exitCode)
	}()

	go func() {
		scanner := bufio.NewScanner(stdout)

		for scanner.Scan() {
			s := scanner.Text()
			log.Println(p.Name, s)
			messages <- s
		}

		if err := scanner.Err(); err != nil {
			log.Println(p.Name, "scanner error", err)
		}
	}()

	return messages, nil
}

func readDir(dir string) ([]*Program, error) {
	log.Println("looking for programs in", dir)
	infos, err := ioutil.ReadDir(dir)
	if err != nil {
		return nil, err
	}

	programs := []*Program{}

	for _, info := range infos {
		commandPath := filepath.Join(dir, info.Name(), "main")
		_, err := os.Stat(commandPath)

		if err == nil {
			log.Println("program executable:", commandPath)

			programs = append(programs, &Program{info.Name(), commandPath})
		}
	}

	return programs, nil
}
<|endoftext|>


<commit_before>package helpers

import (
	"encoding/json"
	"fmt"
	"reflect"
	"strings"

	schema "github.com/lestrrat/go-jsschema"
)

func ToLiteralForGo(input interface{}) string {
	switch t := input.(type) {
	case string:
		return fmt.Sprintf("\"%s\"", t)
	case int, int32, int64:
		return fmt.Sprintf("%d", t)
	case float32, float64:
		return fmt.Sprintf("%f", t)
	}
	switch reflect.TypeOf(input).Kind() {
	case reflect.Slice:
		t := reflect.ValueOf(input)
		l := t.Len()
		es := make([]string, l)
		for i := 0; i < l; i++ {
			e := t.Index(i)
			es[i] = ToLiteralForGo(e.Interface())
		}
		return fmt.Sprintf("[]%s{%s}", reflect.TypeOf(input).Elem().Kind().String(), strings.Join(es, ", "))
	}
	b, err := json.Marshal(input)
	if err != nil {
		fmt.Println(err)
	}
	return string(b)
}

func ConvertTypeForGo(s string) string {
	v, ok := map[string]string{
		"integer": "int64",
		"boolean": "bool",
		"number":  "float64",
	}[s]
	if !ok {
		return s
	}
	return v
}

func ConvertTypeInJSONForGo(s string) string {
	v, ok := map[string]string{
		"integer": "float64",
		"boolean": "bool",
		"number":  "float64",
	}[s]
	if !ok {
		return s
	}
	return v
}

func ConvertArrayForGo(m []string) string {
	s := "[]string{"
	for i, v := range m {
		if i != len(m)-1 {
			s += fmt.Sprintf("\"%s\",", UpperCamelCase(v))
		} else {
			s += fmt.Sprintf("\"%s\"", UpperCamelCase(v))
		}
	}
	s += "}"
	return s
}

func ConvertJSONTagForGo(tag string) string {
	if tag == "" || tag == "-" {
		return "json:\"-\""
	}
	return fmt.Sprintf("json:\"%s,omitempty\"", tag)
}

func ConvertXORMTagForGo(tag string) string {
	if tag == "" || tag == "-" {
		return "xorm:\"-\""
	}
	return fmt.Sprintf("xorm:\"%s\"", tag)
}

func GetTable(ts *schema.Schema) (tn string, err error) {
	if ts.Extras["table"] == nil {
		return
	}

	s, ok := ts.Extras["table"].(map[string]interface{})
	if !ok {
		err = fmt.Errorf("table %v is invalid type", ts.Extras["table"])
	}

	t, ok := s["name"].(string)
	if !ok {
		err = fmt.Errorf("table[name] %v is invalid type", s["name"])
	}

	tn = t
	return
}

func GetPrivate(ts *schema.Schema) (bool, error) {
	if ts.Extras["private"] == nil {
		return false, nil
	}

	c, ok := ts.Extras["private"].(bool)
	if !ok {
		return false, fmt.Errorf("private %v is invalid type", ts.Extras["private"])
	}
	return c, nil
}

func GetColumn(ts *schema.Schema) (cn, ct string, err error) {
	if ts.Extras["column"] == nil {
		return
	}

	c, ok := ts.Extras["column"].(map[string]interface{})
	if !ok {
		err = fmt.Errorf("column %v is invalid type", ts.Extras["column"])
	}

	n, ok := c["name"].(string)
	if !ok {
		err = fmt.Errorf("column[name] %v is invalid type", c["name"])
	}
	cn = n

	t, ok := c["db_type"].(string)
	if !ok {
		err = fmt.Errorf("column[db_type] %v is invalid type", c["db_type"])
	}
	ct = t
	return
}
<commit_msg>Support some types likes int<commit_after>package helpers

import (
	"encoding/json"
	"fmt"
	"reflect"
	"strings"

	schema "github.com/lestrrat/go-jsschema"
)

func ToLiteralForGo(input interface{}) string {
	switch t := input.(type) {
	case bool:
		return fmt.Sprintf("%b", t)
	case int, int8, int16, int32, int64:
		return fmt.Sprintf("%d", t)
	case float32, float64:
		return fmt.Sprintf("%f", t)
	case string:
		return fmt.Sprintf("\"%s\"", t)
	}
	switch reflect.TypeOf(input).Kind() {
	case reflect.Slice:
		t := reflect.ValueOf(input)
		l := t.Len()
		es := make([]string, l)
		for i := 0; i < l; i++ {
			e := t.Index(i)
			es[i] = ToLiteralForGo(e.Interface())
		}
		return fmt.Sprintf("[]%s{%s}", reflect.TypeOf(input).Elem().Kind().String(), strings.Join(es, ", "))
	}
	b, err := json.Marshal(input)
	if err != nil {
		fmt.Println(err)
	}
	return string(b)
}

func ConvertTypeForGo(s string) string {
	v, ok := map[string]string{
		"integer": "int64",
		"boolean": "bool",
		"number":  "float64",
	}[s]
	if !ok {
		return s
	}
	return v
}

func ConvertTypeInJSONForGo(s string) string {
	v, ok := map[string]string{
		"integer": "float64",
		"boolean": "bool",
		"number":  "float64",
	}[s]
	if !ok {
		return s
	}
	return v
}

func ConvertArrayForGo(m []string) string {
	s := "[]string{"
	for i, v := range m {
		if i != len(m)-1 {
			s += fmt.Sprintf("\"%s\",", UpperCamelCase(v))
		} else {
			s += fmt.Sprintf("\"%s\"", UpperCamelCase(v))
		}
	}
	s += "}"
	return s
}

func ConvertJSONTagForGo(tag string) string {
	if tag == "" || tag == "-" {
		return "json:\"-\""
	}
	return fmt.Sprintf("json:\"%s,omitempty\"", tag)
}

func ConvertXORMTagForGo(tag string) string {
	if tag == "" || tag == "-" {
		return "xorm:\"-\""
	}
	return fmt.Sprintf("xorm:\"%s\"", tag)
}

func GetTable(ts *schema.Schema) (tn string, err error) {
	if ts.Extras["table"] == nil {
		return
	}

	s, ok := ts.Extras["table"].(map[string]interface{})
	if !ok {
		err = fmt.Errorf("table %v is invalid type", ts.Extras["table"])
	}

	t, ok := s["name"].(string)
	if !ok {
		err = fmt.Errorf("table[name] %v is invalid type", s["name"])
	}

	tn = t
	return
}

func GetPrivate(ts *schema.Schema) (bool, error) {
	if ts.Extras["private"] == nil {
		return false, nil
	}

	c, ok := ts.Extras["private"].(bool)
	if !ok {
		return false, fmt.Errorf("private %v is invalid type", ts.Extras["private"])
	}
	return c, nil
}

func GetColumn(ts *schema.Schema) (cn, ct string, err error) {
	if ts.Extras["column"] == nil {
		return
	}

	c, ok := ts.Extras["column"].(map[string]interface{})
	if !ok {
		err = fmt.Errorf("column %v is invalid type", ts.Extras["column"])
	}

	n, ok := c["name"].(string)
	if !ok {
		err = fmt.Errorf("column[name] %v is invalid type", c["name"])
	}
	cn = n

	t, ok := c["db_type"].(string)
	if !ok {
		err = fmt.Errorf("column[db_type] %v is invalid type", c["db_type"])
	}
	ct = t
	return
}
<|endoftext|>


<commit_before>package aceproject

import (
	"net/http"
	"strconv"

	sling "gopkg.in/dghubble/sling.v1"
)

// GetProjectsParam represents getprojects request parameter
type GetProjectsParam struct {
	FilterCompletedProject *bool  `url:"Filtercompletedproject,omitempty"`
	ProjectID              string `url:"Projectid,omitempty"`
}

// ProjectResponse represents porject listing response
type ProjectResponse struct {
	Status  string    `json:"status"`
	Results []Project `json:"results"`
}

// Project is representing project in ACEProject
type Project struct {
	ID                int64   `json:"PROJECT_ID"`
	Name              string  `json:"PROJECT_NAME"`
	ProjectNumber     string  `json:"PROJECT_NUMBER"`
	TypeID            int64   `json:"PROJECT_TYPE"`
	Type              string  `json:"PROJECT_TYPE_NAME"`
	ProjectStatusName string  `json:"PROJECT_STATUS_NAME"`
	PriorityName      string  `json:"PROJECT_PRIORITY_NAME"`
	ClientName        string  `json:"CLIENT_NAME"`
	ContactName       string  `json:"CONTACT_NAME"`
	ContactPhone      string  `json:"CONTACT_PHONE"`
	ErrorDesc         *string `json:"ERRORDESCRIPTION,omitempty"`
}

// ProjectService provides methods to interact with project specific action
type ProjectService struct {
	sling *sling.Sling
}

// NewProjectService return a new ProjectService
func NewProjectService(httpClient *http.Client, guidInfo *GUIDInfo) *ProjectService {
	return &ProjectService{
		sling: sling.New().Client(httpClient).Base(baseURL).QueryStruct(guidInfo),
	}
}

// List returns the project list
func (s *ProjectService) List() ([]Project, *http.Response, error) {
	projRes := new(ProjectResponse)
	resp, err := s.sling.New().
		QueryStruct(CreateFunctionParam("getprojects")).
		ReceiveSuccess(projRes)
	if projRes != nil && len(projRes.Results) > 0 {
		if projRes.Results[0].ErrorDesc != nil {
			return nil, resp, Error{*projRes.Results[0].ErrorDesc}
		}
		return *(&projRes.Results), resp, err
	}
	return make([]Project, 0), resp, err
}

// ListWithCompleteness returns the list of complete / incomplete projects
func (s *ProjectService) ListWithCompleteness(complete bool) ([]Project, *http.Response, error) {
	projRes := new(ProjectResponse)
	resp, err := s.sling.New().
		QueryStruct(CreateFunctionParam("getprojects")).
		QueryStruct(&GetProjectsParam{FilterCompletedProject: &complete}).
		ReceiveSuccess(projRes)
	if projRes != nil && len(projRes.Results) > 0 {
		if projRes.Results[0].ErrorDesc != nil {
			return nil, resp, Error{*projRes.Results[0].ErrorDesc}
		}
		return *(&projRes.Results), resp, err
	}
	return make([]Project, 0), resp, err
}

// Get returns the project of given ID
func (s *ProjectService) Get(projectID int64) (*Project, *http.Response, error) {
	//
	projRes := new(ProjectResponse)
	resp, err := s.sling.New().
		QueryStruct(CreateFunctionParam("getprojects")).
		QueryStruct(&GetProjectsParam{ProjectID: strconv.FormatInt(projectID, 10)}).
		ReceiveSuccess(projRes)
	if projRes != nil && len(projRes.Results) > 0 {
		if projRes.Results[0].ErrorDesc != nil {
			return nil, resp, Error{*projRes.Results[0].ErrorDesc}
		}
		return &projRes.Results[0], resp, err
	}
	return nil, resp, err
}
<commit_msg>Add more fields to project (#17)<commit_after>package aceproject

import (
	"net/http"
	"strconv"

	sling "gopkg.in/dghubble/sling.v1"
)

// GetProjectsParam represents getprojects request parameter
type GetProjectsParam struct {
	FilterCompletedProject *bool  `url:"Filtercompletedproject,omitempty"`
	ProjectID              string `url:"Projectid,omitempty"`
}

// ProjectResponse represents porject listing response
type ProjectResponse struct {
	Status  string    `json:"status"`
	Results []Project `json:"results"`
}

// Project is representing project in ACEProject
type Project struct {
	ID                 int64   `json:"PROJECT_ID"`
	Name               string  `json:"PROJECT_NAME"`
	ProjectNumber      string  `json:"PROJECT_NUMBER"`
	TypeID             int64   `json:"PROJECT_TYPE"`
	Type               string  `json:"PROJECT_TYPE_NAME"`
	ProjectStatusName  string  `json:"PROJECT_STATUS_NAME"`
	PriorityName       string  `json:"PROJECT_PRIORITY_NAME"`
	ClientName         string  `json:"CLIENT_NAME"`
	ContactName        string  `json:"CONTACT_NAME"`
	ContactPhone       string  `json:"CONTACT_PHONE"`
	DateCreated        string  `json:"DATE_CREATED"`
	DateModified       string  `json:"DATE_MODIFIED"`
	ProjectCreatorID   int64   `json:"PROJECT_CREATOR_ID"`
	Username           string  `json:"USERNAME"`
	UserUpdateID       int64   `json:"USER_UPDATE_ID"`
	UserUpdateUsername string  `json:"USER_UPDATE_USERNAME"`
	AssignedUsers      string  `json:"ASSIGNED_USERS"`
	ErrorDesc          *string `json:"ERRORDESCRIPTION,omitempty"`
}

// ProjectService provides methods to interact with project specific action
type ProjectService struct {
	sling *sling.Sling
}

// NewProjectService return a new ProjectService
func NewProjectService(httpClient *http.Client, guidInfo *GUIDInfo) *ProjectService {
	return &ProjectService{
		sling: sling.New().Client(httpClient).Base(baseURL).QueryStruct(guidInfo),
	}
}

// List returns the project list
func (s *ProjectService) List() ([]Project, *http.Response, error) {
	projRes := new(ProjectResponse)
	resp, err := s.sling.New().
		QueryStruct(CreateFunctionParam("getprojects")).
		ReceiveSuccess(projRes)
	if projRes != nil && len(projRes.Results) > 0 {
		if projRes.Results[0].ErrorDesc != nil {
			return nil, resp, Error{*projRes.Results[0].ErrorDesc}
		}
		return *(&projRes.Results), resp, err
	}
	return make([]Project, 0), resp, err
}

// ListWithCompleteness returns the list of complete / incomplete projects
func (s *ProjectService) ListWithCompleteness(complete bool) ([]Project, *http.Response, error) {
	projRes := new(ProjectResponse)
	resp, err := s.sling.New().
		QueryStruct(CreateFunctionParam("getprojects")).
		QueryStruct(&GetProjectsParam{FilterCompletedProject: &complete}).
		ReceiveSuccess(projRes)
	if projRes != nil && len(projRes.Results) > 0 {
		if projRes.Results[0].ErrorDesc != nil {
			return nil, resp, Error{*projRes.Results[0].ErrorDesc}
		}
		return *(&projRes.Results), resp, err
	}
	return make([]Project, 0), resp, err
}

// Get returns the project of given ID
func (s *ProjectService) Get(projectID int64) (*Project, *http.Response, error) {
	//
	projRes := new(ProjectResponse)
	resp, err := s.sling.New().
		QueryStruct(CreateFunctionParam("getprojects")).
		QueryStruct(&GetProjectsParam{ProjectID: strconv.FormatInt(projectID, 10)}).
		ReceiveSuccess(projRes)
	if projRes != nil && len(projRes.Results) > 0 {
		if projRes.Results[0].ErrorDesc != nil {
			return nil, resp, Error{*projRes.Results[0].ErrorDesc}
		}
		return &projRes.Results[0], resp, err
	}
	return nil, resp, err
}
<|endoftext|>