<commit_before>package main

// The Cgo directives must immediately preceed 'import "C"' below.
// Example:
//   $ wget http://.../web100_userland-1.8.tar.gz
//   $ tar -xvf web100_userland-1.8.tar.gz
//   $ pushd web100_userland
//   $ ./configure --prefix=$PWD/build
//   $ make && make install
//   $ popd
//   $ go build

/*
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <web100.h>
#include <web100-int.h>

web100_log *get_null_log() {
	return NULL;
}
*/
import "C"

import (
	"flag"
	"fmt"
	"unsafe"
)

var (
	filename = flag.String("filename", "", "Trace filename.")
)

// Necessary web100 functions:
//  + web100_log_open_read(filename)
//  + web100_log_close_read(log_)
//
//   ConvertWeb100VarToNameValue(snap_, var, &var_name, &var_value)
//   for (web100_var *var = web100_var_head(group_);
//        var != NULL;
//        var = web100_var_next(var)) {
//
//   web100_get_log_agent(log_)
//   web100_get_log_time(log_);
//   web100_get_log_group(log_);
//
//   connection_ = web100_get_log_connection(log_);
//   snap_ = web100_snapshot_alloc_from_log(log_);
//   web100_snap_from_log(snap_, log_)
//

// Go structs cannot embed fields with C types.
// https://golang.org/cmd/cgo/#hdr-Go_references_to_C
// Discovered:
//  - 'NULL' is usually equivalent to 'nil'

type Web100 struct {
	log unsafe.Pointer
}

func Open(filename string) (*Web100, error) {
	w := &Web100{}
	var log *C.web100_log

	c_filename := C.CString(filename)
	defer C.free(unsafe.Pointer(c_filename))

	log = C.web100_log_open_read(c_filename)
	fmt.Println("errno", C.web100_errno)
	if log == nil {
		return nil, fmt.Errorf(C.GoString(C.web100_strerror(C.web100_errno)))
	}
	w.log = unsafe.Pointer(log)
	fmt.Println(log)
	snap := C.web100_snapshot_alloc_from_log(log)
	defer C.web100_snapshot_free(snap)
	return w, nil
}

func (w *Web100) Read() error {
	var log *C.web100_log
	var snap *C.web100_snapshot

	log = (*C.web100_log)(w.log)
	fmt.Println("test")
	fmt.Println(log)
	snap = C.web100_snapshot_alloc_from_log(log)
	defer C.web100_snapshot_free(snap)

	err := C.web100_snap_from_log(snap, log)
	if err != C.WEB100_ERR_SUCCESS {
		return fmt.Errorf(C.GoString(C.web100_strerror(C.int(err))))
	}

	group := C.web100_get_log_group(log)
	for v := C.web100_var_head(group); v != nil; v = C.web100_var_next(v) {
		//name := C.web100_get_var_name(v)
		var_size := C.web100_get_var_size(v)
		var_type := C.web100_get_var_type(v)

		var_value := C.malloc(var_size)
		var_text := C.malloc(2 * C.WEB100_VALUE_LEN_MAX) // Use a better size.

		err := C.web100_snap_read(v, snap, var_value)
		if err != C.WEB100_ERR_SUCCESS {
			return fmt.Errorf(C.GoString(C.web100_strerror(C.int(err))))
		}
		C.web100_value_to_textn((*C.char)(var_text), var_size, (C.WEB100_TYPE)(var_type), var_value)
		//fmt.Println(
		//	C.GoString(name),
		//	var_size,
		//	var_type,
		//	C.GoString((*C.char)(var_value)),
		//	C.GoString((*C.char)(var_text)))
	}

	return nil
}

func (w *Web100) Close() error {
	var log *C.web100_log

	log = (*C.web100_log)(w.log)
	err := C.web100_log_close_read(log)
	if err != C.WEB100_ERR_SUCCESS {
		return fmt.Errorf(C.GoString(C.web100_strerror(C.int(err))))
	}

	// Clear pointer after free.
	w.log = nil
	return nil
}

func LookupError(errnum int) string {
	return C.GoString(C.web100_strerror(C.int(errnum)))
}

func main() {
	flag.Parse()

	fmt.Println(LookupError(0))
	// fmt.Println(LookupError(1))
	// fmt.Println(LookupError(2))
	// fmt.Println(LookupError(3))
	// w, err := Open("logs/20170413T01:05:24.133980000Z_c-68-80-50-142.hsd1.pa.comcast.net:53301.s2c_snaplog")
	w, err := Open(*filename)
	if err != nil {
		panic(err)
	}
	err = w.Read()
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v\n", w)
	w.Close()
	fmt.Printf("%#v\n", w)
}
<commit_msg>Return a map from Web100.Next()<commit_after>package main

// The Cgo directives must immediately preceed 'import "C"' below.
// Example:
//   $ wget http://.../web100_userland-1.8.tar.gz
//   $ tar -xvf web100_userland-1.8.tar.gz
//   $ pushd web100_userland
//   $ ./configure --prefix=$PWD/build
//   $ make && make install
//   $ popd
//   $ go build

/*
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <web100.h>
#include <web100-int.h>

web100_log *get_null_log() {
	return NULL;
}
*/
import "C"

import (
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"unsafe"
	//"github.com/kr/pretty"
)

var (
	filename = flag.String("filename", "", "Trace filename.")
)

// Necessary web100 functions:
//  + web100_log_open_read(filename)
//  + web100_log_close_read(log_)
//  + snap_ = web100_snapshot_alloc_from_log(log_);
//  + web100_snap_from_log(snap_, log_)
//
//  + for (web100_var *var = web100_var_head(group_);
//  +      var != NULL;
//  +      var = web100_var_next(var)) {
//
//   web100_get_log_agent(log_)
//   web100_get_log_time(log_);
//   + web100_get_log_group(log_);
//
//   connection_ = web100_get_log_connection(log_);

// Notes:
//  - See: https://golang.org/cmd/cgo/#hdr-Go_references_to_C
//
// Discoveries:
//  - Not all C macros exist in the "C" namespace.
//  - 'NULL' is usually equivalent to 'nil'

// Web100 maintains state associated with a web100 log file.
type Web100 struct {
	// Do not export unsafe pointers.
	log  unsafe.Pointer
	snap unsafe.Pointer
}

// Open prepares a web100 log file for reading. The caller must call Close on
// the returned Web100 instance to release resources.
func Open(filename string) (*Web100, error) {
	c_filename := C.CString(filename)
	defer C.free(unsafe.Pointer(c_filename))

	log := C.web100_log_open_read(c_filename)
	if log == nil {
		return nil, fmt.Errorf(C.GoString(C.web100_strerror(C.web100_errno)))
	}

	// Pre-allocate a snapshot record.
	snap := C.web100_snapshot_alloc_from_log(log)

	w := &Web100{
		log:  unsafe.Pointer(log),
		snap: unsafe.Pointer(snap),
	}
	return w, nil
}

// Next iterates through the web100 log file and returns the next snapshot
// record in the form of a map.
func (w *Web100) Next() (map[string]string, error) {
	results := make(map[string]string)

	log := (*C.web100_log)(w.log)
	snap := (*C.web100_snapshot)(w.snap)

	// Read the next web100_snaplog data from underlying file.
	err := C.web100_snap_from_log(snap, log)
	if err == C.EOF {
		return nil, io.EOF
	}
	if err != C.WEB100_ERR_SUCCESS {
		return nil, fmt.Errorf(C.GoString(C.web100_strerror(err)))
	}

	// Parses variables from most recent web100_snapshot data.
	group := C.web100_get_log_group(log)
	for v := C.web100_var_head(group); v != nil; v = C.web100_var_next(v) {

		name := C.web100_get_var_name(v)
		var_size := C.web100_get_var_size(v)
		var_type := C.web100_get_var_type(v)

		var_data := C.malloc(var_size)
		defer C.free(var_data)

		var_text := C.malloc(2 * C.WEB100_VALUE_LEN_MAX) // Use a better size.
		defer C.free(var_text)

		// Read the raw variable data from the snapshot data.
		err := C.web100_snap_read(v, snap, var_data)
		if err != C.WEB100_ERR_SUCCESS {
			return nil, fmt.Errorf(C.GoString(C.web100_strerror(err)))
		}

		// Convert raw var_data into a string based on var_type.
		C.web100_value_to_textn((*C.char)(var_text), var_size, (C.WEB100_TYPE)(var_type), var_data)
		results[C.GoString(name)] = C.GoString((*C.char)(var_text))
	}

	return results, nil
}

// Close releases resources created by Open.
func (w *Web100) Close() error {
	snap := (*C.web100_snapshot)(w.snap)
	C.web100_snapshot_free(snap)

	log := (*C.web100_log)(w.log)
	err := C.web100_log_close_read(log)
	if err != C.WEB100_ERR_SUCCESS {
		return fmt.Errorf(C.GoString(C.web100_strerror(err)))
	}

	// Clear pointer after free.
	w.log = nil
	w.snap = nil
	return nil
}

func LookupError(errnum int) string {
	return C.GoString(C.web100_strerror(C.int(errnum)))
}

func Pprint(results map[string]string) {
	b, err := json.MarshalIndent(results, "", "  ")
	if err != nil {
		fmt.Println("error:", err)
	}
	fmt.Print(string(b))
}

func main() {
	flag.Parse()

	fmt.Println(LookupError(0))
	w, err := Open(*filename)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%#v\n", w)

	// Find and print the last web100 snapshot record.
	var results map[string]string
	var current map[string]string
	for {
		current, err = w.Next()
		if err != nil {
			break
		}
		results = current
	}
	if err != io.EOF {
		panic(err)
	}
	Pprint(results)
	w.Close()
	fmt.Printf("%#v\n", w)
}
<|endoftext|>


<commit_before>package api

import (
	"encoding/json"
	"errors"
	"fmt"
	"koding/db/mongodb/modelhelper"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/workers/common/response"
	"strings"

	"github.com/nlopes/slack"

	"golang.org/x/oauth2"
	"gopkg.in/mgo.v2"
)

const slackAway = "away"

// Slack holds runtime config for slack OAuth system
type Slack struct {
	Hostname          string
	Protocol          string
	VerificationToken string
	OAuthConf         *oauth2.Config
}

// SlackMessageRequest carries message creation request from client side
type SlackMessageRequest struct {
	Channel string
	Text    string
	Params  slack.PostMessageParameters
}

// Send initiates Slack OAuth
func (s *Slack) Send(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	session, err := models.Cache.Session.ById(context.Client.SessionID)
	if err != nil {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	url := s.OAuthConf.AuthCodeURL(session.Id.Hex(), oauth2.AccessTypeOffline)
	h.Set("Location", url)
	return http.StatusTemporaryRedirect, h, nil, nil

}

// Callback handler is used for handling redirection requests from Slack API
//
// If we can get the token successfully, then we store user's token in mongo in
// Callback handler
func (s *Slack) Callback(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	state := u.Query().Get("state")
	if state == "" {
		return response.NewBadRequest(errors.New("state is not set"))
	}

	session, err := modelhelper.GetSessionById(state)
	if err != nil {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	redirectURL, err := url.Parse(s.OAuthConf.RedirectURL)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// we want to redirect slacks redirection into our success handler with team
	// name included in the redirection url, this is required because user does
	// not need to be logged in plain koding.com doamin
	// eg: dev.koding.com:8090/api/social/slack/oauth/callback?<query params>
	// 			should be redirected to
	// 		teamname.dev.koding.com:8090/api/social/slack/oauth/success?<query params>

	// set incoming request's query params into redirected url
	redirectURL.RawQuery = u.Query().Encode()

	// change subdomain if not only it is koding
	if session.GroupName != models.Channel_KODING_NAME {
		// set team's subdomain
		redirectURL.Host = fmt.Sprintf("%s.%s", session.GroupName, redirectURL.Host)
	}

	// replace 'callback' with 'success'
	redirectURL.Path = strings.Replace(redirectURL.Path, "callback", "success", -1)

	h.Set("Location", redirectURL.String())
	return http.StatusTemporaryRedirect, h, nil, nil
}

// Success handler is used for handling redirection requests from Callback handler
//
// We need this for handling the internal redirection of team requests
func (s *Slack) Success(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	// get session data from state
	state := u.Query().Get("state")
	if state == "" {
		return response.NewBadRequest(errors.New("state is not set"))
	}

	session, err := modelhelper.GetSessionById(state)
	if err != nil {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	// get user info
	user, err := modelhelper.GetUser(session.Username)
	if err != nil && err != mgo.ErrNotFound {
		return response.NewBadRequest(err)
	}

	if err == mgo.ErrNotFound {
		return response.NewBadRequest(err)
	}

	// start exchanging code for a token
	code := u.Query().Get("code")
	if code == "" {
		return response.NewBadRequest(errors.New("code is not set"))
	}

	token, err := s.OAuthConf.Exchange(oauth2.NoContext, code)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// update the slack data
	if err := updateUserSlackToken(user, session.GroupName, token.AccessToken); err != nil {
		return response.NewBadRequest(err)
	}

	h.Set("Location", "/Admin/Invitations/Slack")
	return http.StatusTemporaryRedirect, h, nil, nil
}

// ListUsers lists users of a slack team
func (s *Slack) ListUsers(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackTokenWithContext(context)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(getUsers(token))
}

// ListChannels lists the channels of a slack team
func (s *Slack) ListChannels(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	var groupToken string

	userToken, err := getSlackToken(context)
	if err != nil || userToken == "" {
		groupToken, err = getAnySlackTokenWithGroup(context)
		if err != nil {
			return response.NewBadRequest(err)
		}
	}

	if userToken != "" {
		return response.HandleResultAndError(getChannels(userToken))
	} else {
		return response.HandleResultAndError(getOnlyChannels(groupToken))
	}
}

// TeamInfo shows basic info regarding a slack team
func (s *Slack) TeamInfo(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(getTeamInfo(token))
}

// PostMessage posts a message to a slack channel/group
func (s *Slack) PostMessage(u *url.URL, h http.Header, req *SlackMessageRequest, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context)
	if err != nil {
		return response.NewBadRequest(err)
	}
	return response.HandleResultAndError(postMessage(token, req))
}

// SlashCommand handles slash commands coming from slack
//
// Note: this is experimental, on prod instances this will just say hi,
// otherwise will output incoming request
func (s *Slack) SlashCommand(w http.ResponseWriter, req *http.Request) {
	if err := req.ParseForm(); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	command, err := newSlashCommandFromURLValues(req.PostForm)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if command.Token != s.VerificationToken {
		errMessage := fmt.Sprintf("request from unidentified source: %s - %s", command.Token, req.Host)
		http.Error(w, errMessage, http.StatusBadRequest)
		return
	}

	fmt.Fprintln(w, "hi from koding bot!")

	if command.Robot != "koding" {
		fmt.Fprintln(w, "here is some debug log for non-prod requests")
		fmt.Fprintln(w)

		if err := json.NewEncoder(w).Encode(command); err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
	}
}
<commit_msg>fixed problem on the backend<commit_after>package api

import (
	"encoding/json"
	"errors"
	"fmt"
	"koding/db/mongodb/modelhelper"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/workers/common/response"
	"strings"

	"github.com/nlopes/slack"

	"golang.org/x/oauth2"
	"gopkg.in/mgo.v2"
)

const slackAway = "away"

// Slack holds runtime config for slack OAuth system
type Slack struct {
	Hostname          string
	Protocol          string
	VerificationToken string
	OAuthConf         *oauth2.Config
}

// SlackMessageRequest carries message creation request from client side
type SlackMessageRequest struct {
	Channel string
	Text    string
	Params  slack.PostMessageParameters
}

// Send initiates Slack OAuth
func (s *Slack) Send(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	session, err := models.Cache.Session.ById(context.Client.SessionID)
	if err != nil {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	url := s.OAuthConf.AuthCodeURL(session.Id.Hex(), oauth2.AccessTypeOffline)
	h.Set("Location", url)
	return http.StatusTemporaryRedirect, h, nil, nil

}

// Callback handler is used for handling redirection requests from Slack API
//
// If we can get the token successfully, then we store user's token in mongo in
// Callback handler
func (s *Slack) Callback(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	state := u.Query().Get("state")
	if state == "" {
		return response.NewBadRequest(errors.New("state is not set"))
	}

	session, err := modelhelper.GetSessionById(state)
	if err != nil {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	redirectURL, err := url.Parse(s.OAuthConf.RedirectURL)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// we want to redirect slacks redirection into our success handler with team
	// name included in the redirection url, this is required because user does
	// not need to be logged in plain koding.com doamin
	// eg: dev.koding.com:8090/api/social/slack/oauth/callback?<query params>
	// 			should be redirected to
	// 		teamname.dev.koding.com:8090/api/social/slack/oauth/success?<query params>

	// set incoming request's query params into redirected url
	redirectURL.RawQuery = u.Query().Encode()

	// change subdomain if not only it is koding
	if session.GroupName != models.Channel_KODING_NAME {
		// set team's subdomain
		redirectURL.Host = fmt.Sprintf("%s.%s", session.GroupName, redirectURL.Host)
	}

	// replace 'callback' with 'success'
	redirectURL.Path = strings.Replace(redirectURL.Path, "callback", "success", -1)

	h.Set("Location", redirectURL.String())
	return http.StatusTemporaryRedirect, h, nil, nil
}

// Success handler is used for handling redirection requests from Callback handler
//
// We need this for handling the internal redirection of team requests
func (s *Slack) Success(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	errMessage := u.Query().Get("error")
	if len(errMessage) > 0 {
		h.Set("Location", "/Admin/Invitations/Slack?error="+url.QueryEscape(errMessage))
		return http.StatusTemporaryRedirect, h, nil, nil
	}

	// get session data from state
	state := u.Query().Get("state")
	if state == "" {
		return response.NewBadRequest(errors.New("state is not set"))
	}

	session, err := modelhelper.GetSessionById(state)
	if err != nil {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	// get user info
	user, err := modelhelper.GetUser(session.Username)
	if err != nil && err != mgo.ErrNotFound {
		return response.NewBadRequest(err)
	}

	if err == mgo.ErrNotFound {
		return response.NewBadRequest(err)
	}

	// start exchanging code for a token
	code := u.Query().Get("code")
	if code == "" {
		return response.NewBadRequest(errors.New("code is not set"))
	}

	token, err := s.OAuthConf.Exchange(oauth2.NoContext, code)
	if err != nil {
		return response.NewBadRequest(err)
	}

	// update the slack data
	if err := updateUserSlackToken(user, session.GroupName, token.AccessToken); err != nil {
		return response.NewBadRequest(err)
	}

	h.Set("Location", "/Admin/Invitations/Slack")
	return http.StatusTemporaryRedirect, h, nil, nil
}

// ListUsers lists users of a slack team
func (s *Slack) ListUsers(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackTokenWithContext(context)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(getUsers(token))
}

// ListChannels lists the channels of a slack team
func (s *Slack) ListChannels(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	var groupToken string

	userToken, err := getSlackToken(context)
	if err != nil || userToken == "" {
		groupToken, err = getAnySlackTokenWithGroup(context)
		if err != nil {
			return response.NewBadRequest(err)
		}
	}

	if userToken != "" {
		return response.HandleResultAndError(getChannels(userToken))
	} else {
		return response.HandleResultAndError(getOnlyChannels(groupToken))
	}
}

// TeamInfo shows basic info regarding a slack team
func (s *Slack) TeamInfo(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context)
	if err != nil {
		return response.NewBadRequest(err)
	}

	return response.HandleResultAndError(getTeamInfo(token))
}

// PostMessage posts a message to a slack channel/group
func (s *Slack) PostMessage(u *url.URL, h http.Header, req *SlackMessageRequest, context *models.Context) (int, http.Header, interface{}, error) {
	if !context.IsLoggedIn() {
		return response.NewBadRequest(models.ErrNotLoggedIn)
	}

	token, err := getSlackToken(context)
	if err != nil {
		return response.NewBadRequest(err)
	}
	return response.HandleResultAndError(postMessage(token, req))
}

// SlashCommand handles slash commands coming from slack
//
// Note: this is experimental, on prod instances this will just say hi,
// otherwise will output incoming request
func (s *Slack) SlashCommand(w http.ResponseWriter, req *http.Request) {
	if err := req.ParseForm(); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	command, err := newSlashCommandFromURLValues(req.PostForm)
	if err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	if command.Token != s.VerificationToken {
		errMessage := fmt.Sprintf("request from unidentified source: %s - %s", command.Token, req.Host)
		http.Error(w, errMessage, http.StatusBadRequest)
		return
	}

	fmt.Fprintln(w, "hi from koding bot!")

	if command.Robot != "koding" {
		fmt.Fprintln(w, "here is some debug log for non-prod requests")
		fmt.Fprintln(w)

		if err := json.NewEncoder(w).Encode(command); err != nil {
			http.Error(w, err.Error(), http.StatusBadRequest)
			return
		}
	}
}
<|endoftext|>


<commit_before>// Package redistest privides temporary redis-server for testing.
//
// This is basic usage of redistest.
//
//	s, err := redistest.NewServer(true, nil)
//	if err != nil {
//		panic(err)
//	}
//	defer s.Stop()
//	conn, err := redis.Dial("unix", s.Config["unixsocket"])
//	if err != nil {
//		panic(err)
//	}
//	_, err = conn.Do("PING")
//	if err != nil {
//		panic(err)
//	}
package redistest

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"sort"
	"time"
)

// Server is main struct of redistest.
type Server struct {
	Config  Config
	cmd     *exec.Cmd
	TempDir string
	TimeOut time.Duration
	reader  io.ReadCloser
	writer  io.WriteCloser
}

// Config is configuration of redis-server.
type Config map[string]string

func (config Config) write(wc io.Writer) error {
	keys := make([]string, 0, len(config))
	for key := range config {
		keys = append(keys, key)
	}
	sort.Strings(keys)
	for _, key := range keys {
		value := config[key]
		if _, err := fmt.Fprintf(wc, "%s %s\n", key, value); err != nil {
			return err
		}
	}
	return nil
}

// Error is error while starting redis
type Error struct {
	Err error
	Log string
}

func (err *Error) Error() string {
	return err.Err.Error() + "\n" + err.Log
}

// Cause returns the underlying cause of the error.
// The error can be inspected by errors.Cause https://github.com/pkg/errors
func (err *Error) Cause() error {
	return err.Err
}

// NewServer create a new Server.
// If config is nil, redistest use default value. It means use unixsocket, dir is random.
func NewServer(autostart bool, config Config) (*Server, error) {
	server := new(Server)

	if config == nil {
		config = Config{}
	}

	dir, err := ioutil.TempDir("", "redistest")
	if err != nil {
		return nil, err
	}
	server.TempDir = dir

	server.TimeOut = time.Second * 3

	if _, ok := config["dir"]; !ok {
		config["dir"] = server.TempDir
	}

	if config["loglevel"] == "warning" {
		fmt.Println(`redistest does not support "loglevel warning", using "notice" instead.`)
		config["loglevel"] = "notice"
	}

	_, hasPort := config["port"]
	_, hasUnixSocket := config["unixsocket"]

	if !hasPort && !hasUnixSocket {
		config["port"] = "0"
		config["unixsocket"] = filepath.Join(server.TempDir, "redis.sock")
	}

	server.Config = config

	if autostart {
		if err := server.Start(); err != nil {
			return nil, err
		}
	}

	return server, nil
}

// Start start redis-server.
func (server *Server) Start() error {

	conffile, err := server.createConfigFile()
	if err != nil {
		return err
	}

	path, err := exec.LookPath("redis-server")
	if err != nil {
		return err
	}

	buf := new(bytes.Buffer)
	server.reader, server.writer = io.Pipe()
	log := io.MultiWriter(buf, server.writer)
	cmd := exec.Command(path, conffile.Name())
	cmd.Stderr = log
	cmd.Stdout = log
	server.cmd = cmd

	// start
	if err := cmd.Start(); err != nil {
		return err
	}

	// check server is launced ?
	if err := server.checkLaunch(server.reader); err != nil {
		return &Error{Err: err, Log: buf.String()}
	}
	return nil
}

// Stop stop redis-server
func (server *Server) Stop() error {
	defer os.RemoveAll(server.TempDir)
	// kill process
	if err := server.killAndWait(); err != nil {
		return err
	}
	if server.writer != nil {
		if err := server.writer.Close(); err != nil {
			return err
		}
	}
	if server.reader != nil {
		if err := server.reader.Close(); err != nil {
			return err
		}
	}
	return nil
}

func (server *Server) killAndWait() error {
	if err := server.cmd.Process.Kill(); err != nil {
		return err
	}
	if err := server.cmd.Wait(); err != nil {
		if _, ok := err.(*exec.ExitError); ok {
			// err may be "signal: killed". ignore it.
			return nil
		}
		return err
	}
	return nil
}

func (server *Server) createConfigFile() (*os.File, error) {
	conffile, err := os.OpenFile(
		filepath.Join(server.TempDir, "redis.conf"),
		os.O_RDWR|os.O_CREATE|os.O_EXCL,
		0755,
	)
	defer conffile.Close()

	if err != nil {
		return nil, err
	}

	if err := server.Config.write(conffile); err != nil {
		return nil, err
	}

	return conffile, nil
}

func (server *Server) checkLaunch(r io.Reader) error {
	done := make(chan struct{})
	reg := regexp.MustCompile("The server is now ready to accept connections")

	go func() {
		// wait until the server is ready
		s := bufio.NewScanner(r)
		for s.Scan() {
			if reg.Match(s.Bytes()) {
				close(done)
				break
			}
		}

		// ignore other logs
		for s.Scan() {
		}

		type closer interface {
			CloseWithError(err error) error
		}
		if r, ok := r.(closer); ok {
			r.CloseWithError(s.Err())
		}
	}()

	select {
	case <-done:
		// The server is now ready to accept connections
	case <-time.After(server.TimeOut):
		// timeout
		if err := server.Stop(); err != nil {
			return err
		}
		return errors.New("*** failed to launch redis-server ***")
	}

	return nil
}
<commit_msg>Support both Redis >= 4 and < 4<commit_after>// Package redistest privides temporary redis-server for testing.
//
// This is basic usage of redistest.
//
//	s, err := redistest.NewServer(true, nil)
//	if err != nil {
//		panic(err)
//	}
//	defer s.Stop()
//	conn, err := redis.Dial("unix", s.Config["unixsocket"])
//	if err != nil {
//		panic(err)
//	}
//	_, err = conn.Do("PING")
//	if err != nil {
//		panic(err)
//	}
package redistest

import (
	"bufio"
	"bytes"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"sort"
	"time"
)

// Server is main struct of redistest.
type Server struct {
	Config  Config
	cmd     *exec.Cmd
	TempDir string
	TimeOut time.Duration
	reader  io.ReadCloser
	writer  io.WriteCloser
}

// Config is configuration of redis-server.
type Config map[string]string

func (config Config) write(wc io.Writer) error {
	keys := make([]string, 0, len(config))
	for key := range config {
		keys = append(keys, key)
	}
	sort.Strings(keys)
	for _, key := range keys {
		value := config[key]
		if _, err := fmt.Fprintf(wc, "%s %s\n", key, value); err != nil {
			return err
		}
	}
	return nil
}

// Error is error while starting redis
type Error struct {
	Err error
	Log string
}

func (err *Error) Error() string {
	return err.Err.Error() + "\n" + err.Log
}

// Cause returns the underlying cause of the error.
// The error can be inspected by errors.Cause https://github.com/pkg/errors
func (err *Error) Cause() error {
	return err.Err
}

// NewServer create a new Server.
// If config is nil, redistest use default value. It means use unixsocket, dir is random.
func NewServer(autostart bool, config Config) (*Server, error) {
	server := new(Server)

	if config == nil {
		config = Config{}
	}

	dir, err := ioutil.TempDir("", "redistest")
	if err != nil {
		return nil, err
	}
	server.TempDir = dir

	server.TimeOut = time.Second * 3

	if _, ok := config["dir"]; !ok {
		config["dir"] = server.TempDir
	}

	if config["loglevel"] == "warning" {
		fmt.Println(`redistest does not support "loglevel warning", using "notice" instead.`)
		config["loglevel"] = "notice"
	}

	_, hasPort := config["port"]
	_, hasUnixSocket := config["unixsocket"]

	if !hasPort && !hasUnixSocket {
		config["port"] = "0"
		config["unixsocket"] = filepath.Join(server.TempDir, "redis.sock")
	}

	server.Config = config

	if autostart {
		if err := server.Start(); err != nil {
			return nil, err
		}
	}

	return server, nil
}

// Start start redis-server.
func (server *Server) Start() error {

	conffile, err := server.createConfigFile()
	if err != nil {
		return err
	}

	path, err := exec.LookPath("redis-server")
	if err != nil {
		return err
	}

	buf := new(bytes.Buffer)
	server.reader, server.writer = io.Pipe()
	log := io.MultiWriter(buf, server.writer)
	cmd := exec.Command(path, conffile.Name())
	cmd.Stderr = log
	cmd.Stdout = log
	server.cmd = cmd

	// start
	if err := cmd.Start(); err != nil {
		return err
	}

	// check server is launced ?
	if err := server.checkLaunch(server.reader); err != nil {
		return &Error{Err: err, Log: buf.String()}
	}
	return nil
}

// Stop stop redis-server
func (server *Server) Stop() error {
	defer os.RemoveAll(server.TempDir)
	// kill process
	if err := server.killAndWait(); err != nil {
		return err
	}
	if server.writer != nil {
		if err := server.writer.Close(); err != nil {
			return err
		}
	}
	if server.reader != nil {
		if err := server.reader.Close(); err != nil {
			return err
		}
	}
	return nil
}

func (server *Server) killAndWait() error {
	if err := server.cmd.Process.Kill(); err != nil {
		return err
	}
	if err := server.cmd.Wait(); err != nil {
		if _, ok := err.(*exec.ExitError); ok {
			// err may be "signal: killed". ignore it.
			return nil
		}
		return err
	}
	return nil
}

func (server *Server) createConfigFile() (*os.File, error) {
	conffile, err := os.OpenFile(
		filepath.Join(server.TempDir, "redis.conf"),
		os.O_RDWR|os.O_CREATE|os.O_EXCL,
		0755,
	)
	defer conffile.Close()

	if err != nil {
		return nil, err
	}

	if err := server.Config.write(conffile); err != nil {
		return nil, err
	}

	return conffile, nil
}

func (server *Server) checkLaunch(r io.Reader) error {
	done := make(chan struct{})
	reg := regexp.MustCompile("[Rr]eady to accept connections")

	go func() {
		// wait until the server is ready
		s := bufio.NewScanner(r)
		for s.Scan() {
			if reg.Match(s.Bytes()) {
				close(done)
				break
			}
		}

		// ignore other logs
		for s.Scan() {
		}

		type closer interface {
			CloseWithError(err error) error
		}
		if r, ok := r.(closer); ok {
			r.CloseWithError(s.Err())
		}
	}()

	select {
	case <-done:
		// The server is now ready to accept connections
	case <-time.After(server.TimeOut):
		// timeout
		if err := server.Stop(); err != nil {
			return err
		}
		return errors.New("*** failed to launch redis-server ***")
	}

	return nil
}
<|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 kubeproxyconfig

import (
	"fmt"
	"sort"
	"strings"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// ClientConnectionConfiguration contains details for constructing a client.
type ClientConnectionConfiguration struct {
	// kubeConfigFile is the path to a kubeconfig file.
	KubeConfigFile string
	// acceptContentTypes defines the Accept header sent by clients when connecting to a server, overriding the
	// default value of 'application/json'. This field will control all connections to the server used by a particular
	// client.
	AcceptContentTypes string
	// contentType is the content type used when sending data to the server from this client.
	ContentType string
	// qps controls the number of queries per second allowed for this connection.
	QPS float32
	// burst allows extra queries to accumulate when a client is exceeding its rate.
	Burst int
}

// KubeProxyIPTablesConfiguration contains iptables-related configuration
// details for the Kubernetes proxy server.
type KubeProxyIPTablesConfiguration struct {
	// masqueradeBit is the bit of the iptables fwmark space to use for SNAT if using
	// the pure iptables proxy mode. Values must be within the range [0, 31].
	MasqueradeBit *int32
	// masqueradeAll tells kube-proxy to SNAT everything if using the pure iptables proxy mode.
	MasqueradeAll bool
	// syncPeriod is the period that iptables rules are refreshed (e.g. '5s', '1m',
	// '2h22m').  Must be greater than 0.
	SyncPeriod metav1.Duration
	// minSyncPeriod is the minimum period that iptables rules are refreshed (e.g. '5s', '1m',
	// '2h22m').
	MinSyncPeriod metav1.Duration
}

// KubeProxyIPVSConfiguration contains ipvs-related configuration
// details for the Kubernetes proxy server.
type KubeProxyIPVSConfiguration struct {
	// syncPeriod is the period that ipvs rules are refreshed (e.g. '5s', '1m',
	// '2h22m').  Must be greater than 0.
	SyncPeriod metav1.Duration
	// minSyncPeriod is the minimum period that ipvs rules are refreshed (e.g. '5s', '1m',
	// '2h22m').
	MinSyncPeriod metav1.Duration
	// ipvs scheduler
	Scheduler string
}

// KubeProxyConntrackConfiguration contains conntrack settings for
// the Kubernetes proxy server.
type KubeProxyConntrackConfiguration struct {
	// max is the maximum number of NAT connections to track (0 to
	// leave as-is).  This takes precedence over conntrackMaxPerCore and conntrackMin.
	Max int32
	// maxPerCore is the maximum number of NAT connections to track
	// per CPU core (0 to leave the limit as-is and ignore conntrackMin).
	MaxPerCore int32
	// min is the minimum value of connect-tracking records to allocate,
	// regardless of conntrackMaxPerCore (set conntrackMaxPerCore=0 to leave the limit as-is).
	Min int32
	// tcpEstablishedTimeout is how long an idle TCP connection will be kept open
	// (e.g. '2s').  Must be greater than 0.
	TCPEstablishedTimeout metav1.Duration
	// tcpCloseWaitTimeout is how long an idle conntrack entry
	// in CLOSE_WAIT state will remain in the conntrack
	// table. (e.g. '60s'). Must be greater than 0 to set.
	TCPCloseWaitTimeout metav1.Duration
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// KubeProxyConfiguration contains everything necessary to configure the
// Kubernetes proxy server.
type KubeProxyConfiguration struct {
	metav1.TypeMeta

	// featureGates is a comma-separated list of key=value pairs that control
	// which alpha/beta features are enabled.
	//
	// TODO this really should be a map but that requires refactoring all
	// components to use config files because local-up-cluster.sh only supports
	// the --feature-gates flag right now, which is comma-separated key=value
	// pairs.
	FeatureGates string

	// bindAddress is the IP address for the proxy server to serve on (set to 0.0.0.0
	// for all interfaces)
	BindAddress string
	// healthzBindAddress is the IP address and port for the health check server to serve on,
	// defaulting to 0.0.0.0:10256
	HealthzBindAddress string
	// metricsBindAddress is the IP address and port for the metrics server to serve on,
	// defaulting to 127.0.0.1:10249 (set to 0.0.0.0 for all interfaces)
	MetricsBindAddress string
	// enableProfiling enables profiling via web interface on /debug/pprof handler.
	// Profiling handlers will be handled by metrics server.
	EnableProfiling bool
	// clusterCIDR is the CIDR range of the pods in the cluster. It is used to
	// bridge traffic coming from outside of the cluster. If not provided,
	// no off-cluster bridging will be performed.
	ClusterCIDR string
	// hostnameOverride, if non-empty, will be used as the identity instead of the actual hostname.
	HostnameOverride string
	// clientConnection specifies the kubeconfig file and client connection settings for the proxy
	// server to use when communicating with the apiserver.
	ClientConnection ClientConnectionConfiguration
	// iptables contains iptables-related configuration options.
	IPTables KubeProxyIPTablesConfiguration
	// ipvs contains ipvs-related configuration options.
	IPVS KubeProxyIPVSConfiguration
	// oomScoreAdj is the oom-score-adj value for kube-proxy process. Values must be within
	// the range [-1000, 1000]
	OOMScoreAdj *int32
	// mode specifies which proxy mode to use.
	Mode ProxyMode
	// portRange is the range of host ports (beginPort-endPort, inclusive) that may be consumed
	// in order to proxy service traffic. If unspecified (0-0) then ports will be randomly chosen.
	PortRange string
	// resourceContainer is the absolute name of the resource-only container to create and run
	// the Kube-proxy in (Default: /kube-proxy).
	ResourceContainer string
	// udpIdleTimeout is how long an idle UDP connection will be kept open (e.g. '250ms', '2s').
	// Must be greater than 0. Only applicable for proxyMode=userspace.
	UDPIdleTimeout metav1.Duration
	// conntrack contains conntrack-related configuration options.
	Conntrack KubeProxyConntrackConfiguration
	// configSyncPeriod is how often configuration from the apiserver is refreshed. Must be greater
	// than 0.
	ConfigSyncPeriod metav1.Duration
}

// Currently two modes of proxying are available: 'userspace' (older, stable) or 'iptables'
// (newer, faster). If blank, use the best-available proxy (currently iptables, but may
// change in future versions).  If the iptables proxy is selected, regardless of how, but
// the system's kernel or iptables versions are insufficient, this always falls back to the
// userspace proxy.
type ProxyMode string

const (
	ProxyModeUserspace ProxyMode = "userspace"
	ProxyModeIPTables  ProxyMode = "iptables"
	ProxyModeIPVS      ProxyMode = "ipvs"
)

// IPVSSchedulerMethod is the algorithm for allocating TCP connections and
// UDP datagrams to real servers.  Scheduling algorithms are imple-
//wanted as kernel modules. Ten are shipped with the Linux Virtual Server.
type IPVSSchedulerMethod string

const (
	// Robin Robin distributes jobs equally amongst the available real servers.
	RoundRobin IPVSSchedulerMethod = "rr"
	// Weighted Round Robin assigns jobs to real servers proportionally to there real  servers' weight.
	// Servers  with  higher weights receive new jobs first and get more jobs than servers with lower weights.
	// Servers with equal weights get an equal distribution of new jobs.
	WeightedRoundRobin IPVSSchedulerMethod = "wrr"
	// Least Connection assigns more jobs to real servers with fewer active jobs.
	LeastConnection IPVSSchedulerMethod = "lc"
	// Weighted Least Connection assigns more jobs to servers with fewer jobs and
	// relative to the real servers’weight(Ci/Wi).
	WeightedLeastConnection IPVSSchedulerMethod = "wlc"
	// Locality Based Least Connection assigns jobs destined for the same IP address to the same server if
	// the server is not overloaded and available; otherwise assign jobs to servers with fewer jobs,
	// and keep it for future assignment.
	LocalityBasedLeastConnection IPVSSchedulerMethod = "lblc"
	// Locality Based Least Connection with Replication assigns jobs destined for the same IP address to the
	// least-connection node in the server set for the IP address.  If all the node in the server set are over loaded,
	// it picks up a node with fewer jobs in the cluster and adds it in the sever set for the target.
	// If the server set has not been modified for the specified time, the most loaded node is removed from the server set,
	// in order to avoid high degree of replication.
	LocalityBasedLeastConnectionWithReplication IPVSSchedulerMethod = "lblcr"
	// Source Hashing assigns jobs to servers through looking up a statically assigned hash table
	// by their source IP addresses.
	SourceHashing IPVSSchedulerMethod = "sh"
	// Destination Hashing assigns jobs to servers through looking up a statically assigned hash table
	// by their destination IP addresses.
	DestinationHashing IPVSSchedulerMethod = "dh"
	// Shortest Expected Delay assigns an incoming job to the server with the shortest expected delay.
	// The expected delay that the job will experience is (Ci + 1) / Ui if sent to the ith server, in which
	// Ci is the number of jobs on the the ith server and Ui is the fixed service rate (weight) of the ith server.
	ShortestExpectedDelay IPVSSchedulerMethod = "sed"
	// Never Queue assigns an incoming job to an idle server if there is, instead of waiting for a fast one;
	// if all the servers are busy, it adopts the Shortest Expected Delay policy to assign the job.
	NeverQueue IPVSSchedulerMethod = "nq"
)

func (m *ProxyMode) Set(s string) error {
	*m = ProxyMode(s)
	return nil
}

func (m *ProxyMode) String() string {
	if m != nil {
		return string(*m)
	}
	return ""
}

func (m *ProxyMode) Type() string {
	return "ProxyMode"
}

type ConfigurationMap map[string]string

func (m *ConfigurationMap) String() string {
	pairs := []string{}
	for k, v := range *m {
		pairs = append(pairs, fmt.Sprintf("%s=%s", k, v))
	}
	sort.Strings(pairs)
	return strings.Join(pairs, ",")
}

func (m *ConfigurationMap) Set(value string) error {
	for _, s := range strings.Split(value, ",") {
		if len(s) == 0 {
			continue
		}
		arr := strings.SplitN(s, "=", 2)
		if len(arr) == 2 {
			(*m)[strings.TrimSpace(arr[0])] = strings.TrimSpace(arr[1])
		} else {
			(*m)[strings.TrimSpace(arr[0])] = ""
		}
	}
	return nil
}

func (*ConfigurationMap) Type() string {
	return "mapStringString"
}
<commit_msg>fix lint errors in kubeproxyconfig types.<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 kubeproxyconfig

import (
	"fmt"
	"sort"
	"strings"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// ClientConnectionConfiguration contains details for constructing a client.
type ClientConnectionConfiguration struct {
	// kubeConfigFile is the path to a kubeconfig file.
	KubeConfigFile string
	// acceptContentTypes defines the Accept header sent by clients when connecting to a server, overriding the
	// default value of 'application/json'. This field will control all connections to the server used by a particular
	// client.
	AcceptContentTypes string
	// contentType is the content type used when sending data to the server from this client.
	ContentType string
	// qps controls the number of queries per second allowed for this connection.
	QPS float32
	// burst allows extra queries to accumulate when a client is exceeding its rate.
	Burst int
}

// KubeProxyIPTablesConfiguration contains iptables-related configuration
// details for the Kubernetes proxy server.
type KubeProxyIPTablesConfiguration struct {
	// masqueradeBit is the bit of the iptables fwmark space to use for SNAT if using
	// the pure iptables proxy mode. Values must be within the range [0, 31].
	MasqueradeBit *int32
	// masqueradeAll tells kube-proxy to SNAT everything if using the pure iptables proxy mode.
	MasqueradeAll bool
	// syncPeriod is the period that iptables rules are refreshed (e.g. '5s', '1m',
	// '2h22m').  Must be greater than 0.
	SyncPeriod metav1.Duration
	// minSyncPeriod is the minimum period that iptables rules are refreshed (e.g. '5s', '1m',
	// '2h22m').
	MinSyncPeriod metav1.Duration
}

// KubeProxyIPVSConfiguration contains ipvs-related configuration
// details for the Kubernetes proxy server.
type KubeProxyIPVSConfiguration struct {
	// syncPeriod is the period that ipvs rules are refreshed (e.g. '5s', '1m',
	// '2h22m').  Must be greater than 0.
	SyncPeriod metav1.Duration
	// minSyncPeriod is the minimum period that ipvs rules are refreshed (e.g. '5s', '1m',
	// '2h22m').
	MinSyncPeriod metav1.Duration
	// ipvs scheduler
	Scheduler string
}

// KubeProxyConntrackConfiguration contains conntrack settings for
// the Kubernetes proxy server.
type KubeProxyConntrackConfiguration struct {
	// max is the maximum number of NAT connections to track (0 to
	// leave as-is).  This takes precedence over conntrackMaxPerCore and conntrackMin.
	Max int32
	// maxPerCore is the maximum number of NAT connections to track
	// per CPU core (0 to leave the limit as-is and ignore conntrackMin).
	MaxPerCore int32
	// min is the minimum value of connect-tracking records to allocate,
	// regardless of conntrackMaxPerCore (set conntrackMaxPerCore=0 to leave the limit as-is).
	Min int32
	// tcpEstablishedTimeout is how long an idle TCP connection will be kept open
	// (e.g. '2s').  Must be greater than 0.
	TCPEstablishedTimeout metav1.Duration
	// tcpCloseWaitTimeout is how long an idle conntrack entry
	// in CLOSE_WAIT state will remain in the conntrack
	// table. (e.g. '60s'). Must be greater than 0 to set.
	TCPCloseWaitTimeout metav1.Duration
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// KubeProxyConfiguration contains everything necessary to configure the
// Kubernetes proxy server.
type KubeProxyConfiguration struct {
	metav1.TypeMeta

	// featureGates is a comma-separated list of key=value pairs that control
	// which alpha/beta features are enabled.
	//
	// TODO this really should be a map but that requires refactoring all
	// components to use config files because local-up-cluster.sh only supports
	// the --feature-gates flag right now, which is comma-separated key=value
	// pairs.
	FeatureGates string

	// bindAddress is the IP address for the proxy server to serve on (set to 0.0.0.0
	// for all interfaces)
	BindAddress string
	// healthzBindAddress is the IP address and port for the health check server to serve on,
	// defaulting to 0.0.0.0:10256
	HealthzBindAddress string
	// metricsBindAddress is the IP address and port for the metrics server to serve on,
	// defaulting to 127.0.0.1:10249 (set to 0.0.0.0 for all interfaces)
	MetricsBindAddress string
	// enableProfiling enables profiling via web interface on /debug/pprof handler.
	// Profiling handlers will be handled by metrics server.
	EnableProfiling bool
	// clusterCIDR is the CIDR range of the pods in the cluster. It is used to
	// bridge traffic coming from outside of the cluster. If not provided,
	// no off-cluster bridging will be performed.
	ClusterCIDR string
	// hostnameOverride, if non-empty, will be used as the identity instead of the actual hostname.
	HostnameOverride string
	// clientConnection specifies the kubeconfig file and client connection settings for the proxy
	// server to use when communicating with the apiserver.
	ClientConnection ClientConnectionConfiguration
	// iptables contains iptables-related configuration options.
	IPTables KubeProxyIPTablesConfiguration
	// ipvs contains ipvs-related configuration options.
	IPVS KubeProxyIPVSConfiguration
	// oomScoreAdj is the oom-score-adj value for kube-proxy process. Values must be within
	// the range [-1000, 1000]
	OOMScoreAdj *int32
	// mode specifies which proxy mode to use.
	Mode ProxyMode
	// portRange is the range of host ports (beginPort-endPort, inclusive) that may be consumed
	// in order to proxy service traffic. If unspecified (0-0) then ports will be randomly chosen.
	PortRange string
	// resourceContainer is the absolute name of the resource-only container to create and run
	// the Kube-proxy in (Default: /kube-proxy).
	ResourceContainer string
	// udpIdleTimeout is how long an idle UDP connection will be kept open (e.g. '250ms', '2s').
	// Must be greater than 0. Only applicable for proxyMode=userspace.
	UDPIdleTimeout metav1.Duration
	// conntrack contains conntrack-related configuration options.
	Conntrack KubeProxyConntrackConfiguration
	// configSyncPeriod is how often configuration from the apiserver is refreshed. Must be greater
	// than 0.
	ConfigSyncPeriod metav1.Duration
}

// Currently two modes of proxying are available: 'userspace' (older, stable) or 'iptables'
// (newer, faster). If blank, use the best-available proxy (currently iptables, but may
// change in future versions).  If the iptables proxy is selected, regardless of how, but
// the system's kernel or iptables versions are insufficient, this always falls back to the
// userspace proxy.
type ProxyMode string

const (
	ProxyModeUserspace ProxyMode = "userspace"
	ProxyModeIPTables  ProxyMode = "iptables"
	ProxyModeIPVS      ProxyMode = "ipvs"
)

// IPVSSchedulerMethod is the algorithm for allocating TCP connections and
// UDP datagrams to real servers.  Scheduling algorithms are imple-
//wanted as kernel modules. Ten are shipped with the Linux Virtual Server.
type IPVSSchedulerMethod string

const (
	// RoundRobin distributes jobs equally amongst the available real servers.
	RoundRobin IPVSSchedulerMethod = "rr"
	// WeightedRoundRobin assigns jobs to real servers proportionally to there real servers' weight.
	// Servers with higher weights receive new jobs first and get more jobs than servers with lower weights.
	// Servers with equal weights get an equal distribution of new jobs.
	WeightedRoundRobin IPVSSchedulerMethod = "wrr"
	// LeastConnection assigns more jobs to real servers with fewer active jobs.
	LeastConnection IPVSSchedulerMethod = "lc"
	// WeightedLeastConnection assigns more jobs to servers with fewer jobs and
	// relative to the real servers' weight(Ci/Wi).
	WeightedLeastConnection IPVSSchedulerMethod = "wlc"
	// LocalityBasedLeastConnection assigns jobs destined for the same IP address to the same server if
	// the server is not overloaded and available; otherwise assigns jobs to servers with fewer jobs,
	// and keep it for future assignment.
	LocalityBasedLeastConnection IPVSSchedulerMethod = "lblc"
	// LocalityBasedLeastConnectionWithReplication with Replication assigns jobs destined for the same IP address to the
	// least-connection node in the server set for the IP address. If all the node in the server set are overloaded,
	// it picks up a node with fewer jobs in the cluster and adds it to the sever set for the target.
	// If the server set has not been modified for the specified time, the most loaded node is removed from the server set,
	// in order to avoid high degree of replication.
	LocalityBasedLeastConnectionWithReplication IPVSSchedulerMethod = "lblcr"
	// SourceHashing assigns jobs to servers through looking up a statically assigned hash table
	// by their source IP addresses.
	SourceHashing IPVSSchedulerMethod = "sh"
	// DestinationHashing assigns jobs to servers through looking up a statically assigned hash table
	// by their destination IP addresses.
	DestinationHashing IPVSSchedulerMethod = "dh"
	// ShortestExpectedDelay assigns an incoming job to the server with the shortest expected delay.
	// The expected delay that the job will experience is (Ci + 1) / Ui if sent to the ith server, in which
	// Ci is the number of jobs on the the ith server and Ui is the fixed service rate (weight) of the ith server.
	ShortestExpectedDelay IPVSSchedulerMethod = "sed"
	// NeverQueue assigns an incoming job to an idle server if there is, instead of waiting for a fast one;
	// if all the servers are busy, it adopts the ShortestExpectedDelay policy to assign the job.
	NeverQueue IPVSSchedulerMethod = "nq"
)

func (m *ProxyMode) Set(s string) error {
	*m = ProxyMode(s)
	return nil
}

func (m *ProxyMode) String() string {
	if m != nil {
		return string(*m)
	}
	return ""
}

func (m *ProxyMode) Type() string {
	return "ProxyMode"
}

type ConfigurationMap map[string]string

func (m *ConfigurationMap) String() string {
	pairs := []string{}
	for k, v := range *m {
		pairs = append(pairs, fmt.Sprintf("%s=%s", k, v))
	}
	sort.Strings(pairs)
	return strings.Join(pairs, ",")
}

func (m *ConfigurationMap) Set(value string) error {
	for _, s := range strings.Split(value, ",") {
		if len(s) == 0 {
			continue
		}
		arr := strings.SplitN(s, "=", 2)
		if len(arr) == 2 {
			(*m)[strings.TrimSpace(arr[0])] = strings.TrimSpace(arr[1])
		} else {
			(*m)[strings.TrimSpace(arr[0])] = ""
		}
	}
	return nil
}

func (*ConfigurationMap) Type() string {
	return "mapStringString"
}
<|endoftext|>


<commit_before>// File operations. Retrieve players from csv

package main

import (
	"encoding/csv"
	"os"
	"strconv"

	"github.com/topher200/baseutil"
)

func ParsePlayers(inputFilename string) []Player {
	// Open our input Players file
	file, err := os.Open(inputFilename)
	baseutil.Check(err)
	defer file.Close()

	// Read in our csv. Throw away the header. Because we're getting our input
	// directly from the league signup form, we expect the input to be shaped like
	// this:
	// Field 3: First name
	// Field 4: Last name
	// Field 8: "Male" or "Female"
	// Field 38: Rating
	playersCsv := csv.NewReader(file)
	columnNames, err := playersCsv.Read()
	baseutil.Check(err)

	// Read in all players
	playersCsvLines, err := playersCsv.ReadAll()
	baseutil.Check(err)
	players := make([]Player, len(playersCsvLines))
	rows := make([]map[string]string, len(playersCsvLines))
	for rowNum, row := range playersCsvLines {
		rows[rowNum] = make(map[string]string)
		for columnNum, value := range row {
			if value == "" {
				continue
			}
			rows[rowNum][columnNames[columnNum]] = value
		}
	}

	for i, row := range rows {
		firstName := row["firstname"]
		lastName := row["lastname"]
		gender, err := StringToGender(row["gender"])
		baseutil.Check(err)
		rating, err := strconv.ParseFloat(row["rating"], 32)
		baseutil.Check(err)
		players[i] = Player{
			Name{firstName, lastName}, float32(rating), gender, uint8(0), Name{}}
	}
	return players
}

// ParseBaggages has the side effect of setting the .baggage for all Players
func ParseBaggages(inputFilename string, players []Player) {
	// Read in our csv. Throw away the header. We expect this format:
	// Field 0: Player 1 First Name
	// Field 1: Player 1 Last Name
	// Field 2: Player 2 First Name
	// Field 3: Player 2 Last Name
	file, err := os.Open(inputFilename)
	baseutil.Check(err)
	defer file.Close()
	baggagesCsv := csv.NewReader(file)
	_, err = baggagesCsv.Read()
	baseutil.Check(err)

	baggagesCsvLines, err := baggagesCsv.ReadAll()
	baseutil.Check(err)
	for _, baggage := range baggagesCsvLines {
		playerPointer, err := FindPlayer(players, Name{baggage[0], baggage[1]})
		baseutil.Check(err)
		if playerPointer.HasBaggage() {
			newLog.Panicf("Player %v already has baggage %v",
				*playerPointer, playerPointer.baggage)
		}
		playerPointer.baggage = Name{baggage[2], baggage[3]}
		newLog.Info("Found baggage of %v for %v",
			playerPointer.baggage, playerPointer.String())
	}
}
<commit_msg>move parsing to baseutil<commit_after>// File operations. Retrieve players from csv

package main

import (
	"encoding/csv"
	"os"
	"strconv"

	"github.com/topher200/baseutil"
)

func ParsePlayers(inputFilename string) []Player {
	mappedRows := baseutil.Parse(inputFilename)
	players := make([]Player, len(mappedRows))
	for i, row := range mappedRows {
		firstName := row["firstname"]
		lastName := row["lastname"]
		gender, err := StringToGender(row["gender"])
		baseutil.Check(err)
		rating, err := strconv.ParseFloat(row["rating"], 32)
		baseutil.Check(err)
		players[i] = Player{
			Name{firstName, lastName}, float32(rating), gender, uint8(0), Name{}}
	}
	return players
}

// ParseBaggages has the side effect of setting the .baggage for all Players
func ParseBaggages(inputFilename string, players []Player) {
	// Read in our csv. Throw away the header. We expect this format:
	// Field 0: Player 1 First Name
	// Field 1: Player 1 Last Name
	// Field 2: Player 2 First Name
	// Field 3: Player 2 Last Name
	file, err := os.Open(inputFilename)
	baseutil.Check(err)
	defer file.Close()
	baggagesCsv := csv.NewReader(file)
	_, err = baggagesCsv.Read()
	baseutil.Check(err)

	baggagesCsvLines, err := baggagesCsv.ReadAll()
	baseutil.Check(err)
	for _, baggage := range baggagesCsvLines {
		playerPointer, err := FindPlayer(players, Name{baggage[0], baggage[1]})
		baseutil.Check(err)
		if playerPointer.HasBaggage() {
			newLog.Panicf("Player %v already has baggage %v",
				*playerPointer, playerPointer.baggage)
		}
		playerPointer.baggage = Name{baggage[2], baggage[3]}
		newLog.Info("Found baggage of %v for %v",
			playerPointer.baggage, playerPointer.String())
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"os"
)

func main() {
	http.HandleFunc("/", handler)
	fmt.Println("listening...")
	err := http.ListenAndServe(":"+os.Getenv("PORT"), nil)
	if err != nil {
		panic(err)
	}
}

func handler(w http.ResponseWriter, r *http.Request) {
	// Read the Request Parameter "command"
	command := r.FormValue("command")

	if command == "/9gag" {
		jsonResp(w, "Hello World")
	} else {
		fmt.Fprint(w, "I do not understand your command.")
	}
}

func jsonResp(w http.ResponseWriter, msg string) {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	resp := map[string]string{"text": msg}
	r, err := json.Marshal(resp)
	if err != nil {
		fmt.Println("Couldn't marshal hook response:", err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
	w.Write(r)
}
<commit_msg>Reading the 9gag API and returning the formatted json for the bot.<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
)

type Response struct {
	Text        string
	Attachments []Attachments
}

type Attachments struct {
	Title      string
	Title_link string
	Thumb_url  string
}

type jsonData struct {
	Status  int64
	Message string
	Data    []Data
}

type Data struct {
	Id      string
	Caption string
	Images  struct {
		Small  string
		Cover  string
		Normal string
		Large  string
	}
	Media interface{}
	Link  string
	Votes struct {
		Count int64
	}
	Comments struct {
		Count int64
	}
}

func main() {
	http.HandleFunc("/", handler)
	fmt.Println("listening...")
	err := http.ListenAndServe(":"+os.Getenv("PORT"), nil)
	if err != nil {
		panic(err)
	}
}

func handler(w http.ResponseWriter, r *http.Request) {
	// Read the Request Parameter "command"
	command := r.FormValue("command")

	if command == "/9gag" {
		r, err := http.Get("http://infinigag.k3min.eu")
		if err != nil {
			fmt.Println("Error requesting data")
			return
		}
		body, err := ioutil.ReadAll(r.Body)
		if err != nil {
			fmt.Println("Error while opening file", err)
			return
		}
		x := new(jsonData)
		err = json.Unmarshal(body, &x)
		if err != nil {
			fmt.Println("Error while parsing file", err)
			return
		}
		jsonResp(w, x)
	} else {
		fmt.Fprint(w, "I do not understand your command.")
	}
}

func jsonResp(w http.ResponseWriter, x *jsonData) {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")

	attachments := make([]Attachments, 10)
	for i := 0; i < 9; i++ {
		attachments[i] = Attachments{
			Title:      x.Data[i].Caption,
			Title_link: x.Data[i].Link,
			Thumb_url:  x.Data[i].Images.Small,
		}
	}

	resp := Response{
		Text:        "lorem ipsum",
		Attachments: attachments,
	}

	r, err := json.Marshal(resp)
	if err != nil {
		fmt.Println("Couldn't marshal hook response:", err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
	w.Write(r)
}
<|endoftext|>


<commit_before>package aws

import (
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/endpoints"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/pkg/errors"
	"github.com/prometheus/client_golang/prometheus"
	"os"
	"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/metrics"
	"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/services"
	"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/throttle"
)

type Cloud interface {
	// EC2 provides API to AWS EC2
	EC2() services.EC2

	// ELBV2 provides API to AWS ELBV2
	ELBV2() services.ELBV2

	// ACM provides API to AWS ACM
	ACM() services.ACM

	// WAFv2 provides API to AWS WAFv2
	WAFv2() services.WAFv2

	// WAFRegional provides API to AWS WAFRegional
	WAFRegional() services.WAFRegional

	// Shield provides API to AWS Shield
	Shield() services.Shield

	// RGT provides API to AWS RGT
	RGT() services.RGT

	// Region for the kubernetes cluster
	Region() string

	// VPC ID for the the kubernetes cluster
	VpcID() string
}

// NewCloud constructs new Cloud implementation.
func NewCloud(cfg CloudConfig, metricsRegisterer prometheus.Registerer) (Cloud, error) {

	if len(cfg.VpcID) == 0 {
		metadataSess := session.Must(session.NewSession(aws.NewConfig()))
		metadata := services.NewEC2Metadata(metadataSess)
		vpcId, err := metadata.VpcID()
		if err != nil {
			return nil, errors.Wrap(err, "failed to introspect vpcID from EC2Metadata, specify --aws-vpc-id instead if EC2Metadata is unavailable")
		}
		cfg.VpcID = vpcId
	}

	if len(cfg.Region) == 0 {
		region := os.Getenv("AWS_DEFAULT_REGION")
		if region == "" {
			region = os.Getenv("AWS_REGION")
		}
		cfg.Region = region
	}

	awsCFG := aws.NewConfig().WithRegion(cfg.Region).WithSTSRegionalEndpoint(endpoints.RegionalSTSEndpoint).WithMaxRetries(cfg.MaxRetries)
	sess := session.Must(session.NewSession(awsCFG))
	injectUserAgent(&sess.Handlers)

	if cfg.ThrottleConfig != nil {
		throttler := throttle.NewThrottler(cfg.ThrottleConfig)
		throttler.InjectHandlers(&sess.Handlers)
	}
	if metricsRegisterer != nil {
		metricsCollector, err := metrics.NewCollector(metricsRegisterer)
		if err != nil {
			return nil, errors.Wrapf(err, "failed to initialize sdk metrics collector")
		}
		metricsCollector.InjectHandlers(&sess.Handlers)
	}

	return &defaultCloud{
		cfg:         cfg,
		ec2:         services.NewEC2(sess),
		elbv2:       services.NewELBV2(sess),
		acm:         services.NewACM(sess),
		wafv2:       services.NewWAFv2(sess),
		wafRegional: services.NewWAFRegional(sess, cfg.Region),
		shield:      services.NewShield(sess),
		rgt:         services.NewRGT(sess),
	}, nil
}

var _ Cloud = &defaultCloud{}

type defaultCloud struct {
	cfg CloudConfig

	ec2   services.EC2
	elbv2 services.ELBV2

	acm         services.ACM
	wafv2       services.WAFv2
	wafRegional services.WAFRegional
	shield      services.Shield
	rgt         services.RGT
}

func (c *defaultCloud) EC2() services.EC2 {
	return c.ec2
}

func (c *defaultCloud) ELBV2() services.ELBV2 {
	return c.elbv2
}

func (c *defaultCloud) ACM() services.ACM {
	return c.acm
}

func (c *defaultCloud) WAFv2() services.WAFv2 {
	return c.wafv2
}

func (c *defaultCloud) WAFRegional() services.WAFRegional {
	return c.wafRegional
}

func (c *defaultCloud) Shield() services.Shield {
	return c.shield
}

func (c *defaultCloud) RGT() services.RGT {
	return c.rgt
}

func (c *defaultCloud) Region() string {
	return c.cfg.Region
}

func (c *defaultCloud) VpcID() string {
	return c.cfg.VpcID
}
<commit_msg>Add code for IMDS call  if env unconfigured<commit_after>package aws

import (
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/endpoints"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/pkg/errors"
	"github.com/prometheus/client_golang/prometheus"
	"os"
	"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/metrics"
	"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/services"
	"sigs.k8s.io/aws-load-balancer-controller/pkg/aws/throttle"
)

type Cloud interface {
	// EC2 provides API to AWS EC2
	EC2() services.EC2

	// ELBV2 provides API to AWS ELBV2
	ELBV2() services.ELBV2

	// ACM provides API to AWS ACM
	ACM() services.ACM

	// WAFv2 provides API to AWS WAFv2
	WAFv2() services.WAFv2

	// WAFRegional provides API to AWS WAFRegional
	WAFRegional() services.WAFRegional

	// Shield provides API to AWS Shield
	Shield() services.Shield

	// RGT provides API to AWS RGT
	RGT() services.RGT

	// Region for the kubernetes cluster
	Region() string

	// VPC ID for the the kubernetes cluster
	VpcID() string
}

// NewCloud constructs new Cloud implementation.
func NewCloud(cfg CloudConfig, metricsRegisterer prometheus.Registerer) (Cloud, error) {
	metadata := (services.EC2Metadata)(nil)
	if len(cfg.VpcID) == 0 {
		metadataSess := session.Must(session.NewSession(aws.NewConfig()))
		metadata = services.NewEC2Metadata(metadataSess)
		vpcId, err := metadata.VpcID()
		if err != nil {
			return nil, errors.Wrap(err, "failed to introspect vpcID from EC2Metadata, specify --aws-vpc-id instead if EC2Metadata is unavailable")
		}
		cfg.VpcID = vpcId
	}

	if len(cfg.Region) == 0 {
		region := os.Getenv("AWS_DEFAULT_REGION")
		if region == "" {
			region = os.Getenv("AWS_REGION")
		}

		if region == ""{
			if metadata  == nil {
				metadataSess := session.Must(session.NewSession(aws.NewConfig()))
				metadata = services.NewEC2Metadata(metadataSess)
			}
			err := (error)(nil)
			region, err = metadata.Region()
			if err != nil {
				return nil, errors.Wrap(err, "failed to introspect region from EC2Metadata, specify --aws-region instead if EC2Metadata is unavailable")
			}
		}
		cfg.Region = region
	}

	awsCFG := aws.NewConfig().WithRegion(cfg.Region).WithSTSRegionalEndpoint(endpoints.RegionalSTSEndpoint).WithMaxRetries(cfg.MaxRetries)
	sess := session.Must(session.NewSession(awsCFG))
	injectUserAgent(&sess.Handlers)

	if cfg.ThrottleConfig != nil {
		throttler := throttle.NewThrottler(cfg.ThrottleConfig)
		throttler.InjectHandlers(&sess.Handlers)
	}
	if metricsRegisterer != nil {
		metricsCollector, err := metrics.NewCollector(metricsRegisterer)
		if err != nil {
			return nil, errors.Wrapf(err, "failed to initialize sdk metrics collector")
		}
		metricsCollector.InjectHandlers(&sess.Handlers)
	}

	return &defaultCloud{
		cfg:         cfg,
		ec2:         services.NewEC2(sess),
		elbv2:       services.NewELBV2(sess),
		acm:         services.NewACM(sess),
		wafv2:       services.NewWAFv2(sess),
		wafRegional: services.NewWAFRegional(sess, cfg.Region),
		shield:      services.NewShield(sess),
		rgt:         services.NewRGT(sess),
	}, nil
}

var _ Cloud = &defaultCloud{}

type defaultCloud struct {
	cfg CloudConfig

	ec2   services.EC2
	elbv2 services.ELBV2

	acm         services.ACM
	wafv2       services.WAFv2
	wafRegional services.WAFRegional
	shield      services.Shield
	rgt         services.RGT
}

func (c *defaultCloud) EC2() services.EC2 {
	return c.ec2
}

func (c *defaultCloud) ELBV2() services.ELBV2 {
	return c.elbv2
}

func (c *defaultCloud) ACM() services.ACM {
	return c.acm
}

func (c *defaultCloud) WAFv2() services.WAFv2 {
	return c.wafv2
}

func (c *defaultCloud) WAFRegional() services.WAFRegional {
	return c.wafRegional
}

func (c *defaultCloud) Shield() services.Shield {
	return c.shield
}

func (c *defaultCloud) RGT() services.RGT {
	return c.rgt
}

func (c *defaultCloud) Region() string {
	return c.cfg.Region
}

func (c *defaultCloud) VpcID() string {
	return c.cfg.VpcID
}
<|endoftext|>


<commit_before>package sskg_test

import (
	"bytes"
	"testing"

	"github.com/codahale/sskg"
)

func TestNext(t *testing.T) {
	seq := sskg.New(make([]byte, 32), make([]byte, 32), 1<<32, 32)
	for i := 0; i < 10000; i++ {
		seq.Next()
	}

	if v := seq.Key(); !bytes.Equal(expected, v) {
		t.Errorf("Key was %#v, but expected %#v", v, expected)
	}
}

func TestSeek(t *testing.T) {
	seq := sskg.New(make([]byte, 32), make([]byte, 32), 1<<32, 32)
	seq.Seek(10000)

	if v := seq.Key(); !bytes.Equal(expected, v) {
		t.Errorf("Key was %#v, but expected %#v", v, expected)
	}
}

func BenchmarkNext(b *testing.B) {
	seq := sskg.New(make([]byte, 32), make([]byte, 32), 1<<32, 32)
	b.ResetTimer()
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		seq.Next()
	}
}

var (
	expected = []byte{
		0xf7, 0xd2, 0xf8, 0x38, 0xb0, 0x6b, 0x60, 0xe4, 0x29, 0xe1, 0x45, 0xe9,
		0xbb, 0xa4, 0x87, 0x76, 0xb8, 0xd6, 0x2a, 0xa4, 0xf1, 0x6c, 0x64, 0x2f,
		0x18, 0x13, 0x5e, 0x41, 0xb, 0xc8, 0x7b, 0xce,
	}
)
<commit_msg>Add benchmarks for Next and Seek comparatively.<commit_after>package sskg_test

import (
	"bytes"
	"testing"

	"github.com/codahale/sskg"
)

func TestNext(t *testing.T) {
	seq := sskg.New(make([]byte, 32), make([]byte, 32), 1<<32, 32)
	for i := 0; i < 10000; i++ {
		seq.Next()
	}

	if v := seq.Key(); !bytes.Equal(expected, v) {
		t.Errorf("Key was %#v, but expected %#v", v, expected)
	}
}

func TestSeek(t *testing.T) {
	seq := sskg.New(make([]byte, 32), make([]byte, 32), 1<<32, 32)
	seq.Seek(10000)

	if v := seq.Key(); !bytes.Equal(expected, v) {
		t.Errorf("Key was %#v, but expected %#v", v, expected)
	}
}

func BenchmarkNext(b *testing.B) {
	seq := sskg.New(make([]byte, 32), make([]byte, 32), 1<<32, 32)
	b.ResetTimer()
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		seq.Next()
	}
}

func BenchmarkNext1000(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		seq := sskg.New(make([]byte, 32), make([]byte, 32), 1<<32, 32)
		for j := 0; j < 1000; j++ {
			seq.Next()
		}
	}
}

func BenchmarkSeek1000(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		seq := sskg.New(make([]byte, 32), make([]byte, 32), 1<<32, 32)
		seq.Seek(1000)
	}
}

var (
	expected = []byte{
		0xf7, 0xd2, 0xf8, 0x38, 0xb0, 0x6b, 0x60, 0xe4, 0x29, 0xe1, 0x45, 0xe9,
		0xbb, 0xa4, 0x87, 0x76, 0xb8, 0xd6, 0x2a, 0xa4, 0xf1, 0x6c, 0x64, 0x2f,
		0x18, 0x13, 0x5e, 0x41, 0xb, 0xc8, 0x7b, 0xce,
	}
)
<|endoftext|>


<commit_before>package models

const (
	// 生成的数据表的文件的模版: gen_table_*.go
	codeTemplate = `// DON'T EDIT *** generated by go-db-models *** DON'T EDIT //
package {{.PackageName}}

{{range $k, $v := .Imports}}
import "{{$v}}"{{end}}
import "strings"
import "database/sql"

// 对应数据表：{{.Name}}
type {{.Name|Format2StructName}}Table struct {
{{range $k, $v := .Fields}}
{{$v.Name|Format2StructName}}  {{$v.Type}} {{$v.Name|Format2StructTag}}{{end}}
}

const {{.Name|Format2Title}}SelectFields string = "{{.SelectFields}}"

{{if .QueryBy.FieldName}}
// 查询单行记录（根据某个字段）
func {{.Name|Format2StructName}}QueryBy{{.QueryBy.FieldName|Format2StructName}}(db *sql.DB, {{.QueryBy.FieldName|Format2Title}}Val {{.QueryBy.FieldType}}) ({{.Name}} *{{.Name|Format2StructName}}Table, err error) {
	queryString := "SELECT " + {{.Name|Format2Title}}SelectFields + " FROM {{.Name|AddBackquote}} WHERE {{.QueryBy.FieldName|AddBackquote}} = ?"
	{{.Name}} = &{{.Name|Format2StructName}}Table{}
	err = db.QueryRow(queryString, {{.QueryBy.FieldName|Format2Title}}Val).Scan( {{range $k, $v := .Fields}}
		&{{$.Name}}.{{$v.Name|Format2StructName}},{{end}}
	)

	if err != nil {
		return nil, err
	}

	return {{.Name}}, nil
}
{{end}}

// 查询单行记录
func {{.Name|Format2StructName}}QueryRow(db *sql.DB, queryString string) ({{.Name}} *{{.Name|Format2StructName}}Table, err error) {
	queryString = strings.Replace(queryString, SelectFieldsTemp, {{.Name|Format2Title}}SelectFields, 1)
	{{.Name}} = &{{.Name|Format2StructName}}Table{}
	err = db.QueryRow(queryString).Scan( {{range $k, $v := .Fields}}
		&{{$.Name}}.{{$v.Name|Format2StructName}},{{end}}
	)

	if err != nil {
		return nil, err
	}

	return {{.Name}}, nil
}

// 查询多行记录
func {{.Name|Format2StructName}}Query(db *sql.DB, queryString string) ({{.Name}} []*{{.Name|Format2StructName}}Table, err error) {
	queryString = strings.Replace(queryString, SelectFieldsTemp, {{.Name|Format2Title}}SelectFields, 1)
	rows, err := db.Query(queryString)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	for rows.Next() {
		var oneRow = &{{.Name|Format2StructName}}Table{}
		err = rows.Scan( {{range $k, $v := .Fields}}
			&oneRow.{{$v.Name|Format2StructName}},{{end}}
		)
		if err != nil {
			return nil, err
		}

		{{.Name}} = append({{.Name}}, oneRow)
	}

	return {{.Name}}, nil
}
`
	// 生成的gen_common.go文件的模版
	commonCodeTemplate = `// DON'T EDIT *** generated by go-db-models *** DON'T EDIT //
package {{.PackageName}}

const (
	SelectFieldsTemp string = "{select-fields-temp}"
)
`
)
<commit_msg>优化生成后的代码<commit_after>package models

const (
	// 生成的数据表的文件的模版: gen_table_*.go
	codeTemplate = `// DON'T EDIT *** generated by go-db-models *** DON'T EDIT //
package {{.PackageName}}

{{range $k, $v := .Imports}}
import "{{$v}}"{{end}}
import "strings"
import "database/sql"

// 对应数据表：{{.Name}}
type {{.Name|Format2StructName}}Table struct {
{{range $k, $v := .Fields}}
{{$v.Name|Format2StructName}}  {{$v.Type}} {{$v.Name|Format2StructTag}}{{end}}
}

const {{.Name|Format2Title}}SelectFields string = " {{.SelectFields}} "

{{if .QueryBy.FieldName}}
// 查询单行记录（根据某个字段）
func {{.Name|Format2StructName}}QueryBy{{.QueryBy.FieldName|Format2StructName}}(db *sql.DB, {{.QueryBy.FieldName|Format2Title}}Val {{.QueryBy.FieldType}}) ({{.Name}} *{{.Name|Format2StructName}}Table, err error) {
	queryString := "SELECT " + {{.Name|Format2Title}}SelectFields + " FROM {{.Name|AddBackquote}} WHERE {{.QueryBy.FieldName|AddBackquote}} = ?"
	{{.Name}} = &{{.Name|Format2StructName}}Table{}
	err = db.QueryRow(queryString, {{.QueryBy.FieldName|Format2Title}}Val).Scan( {{range $k, $v := .Fields}}
		&{{$.Name}}.{{$v.Name|Format2StructName}},{{end}}
	)

	if err != nil {
		return nil, err
	}

	return {{.Name}}, nil
}
{{end}}

// 查询单行记录
func {{.Name|Format2StructName}}QueryRowWhere(db *sql.DB, where string) ({{.Name}} *{{.Name|Format2StructName}}Table, err error) {
	queryString := "SELECT " + {{.Name|Format2Title}}SelectFields + " FROM {{.Name|AddBackquote}} WHERE " + where
	return do{{.Name|Format2StructName}}QueryRow(db, queryString)
}

// 查询单行记录
func {{.Name|Format2StructName}}QueryRow(db *sql.DB, queryString string) ({{.Name}} *{{.Name|Format2StructName}}Table, err error) {
	queryString = strings.Replace(queryString, SelectFieldsTemp, {{.Name|Format2Title}}SelectFields, 1)
	return do{{.Name|Format2StructName}}QueryRow(db, queryString)
}

// 查询单行记录
func do{{.Name|Format2StructName}}QueryRow(db *sql.DB, queryString string) ({{.Name}} *{{.Name|Format2StructName}}Table, err error) {
	{{.Name}} = &{{.Name|Format2StructName}}Table{}
	err = db.QueryRow(queryString).Scan( {{range $k, $v := .Fields}}
		&{{$.Name}}.{{$v.Name|Format2StructName}},{{end}}
	)

	if err != nil {
		return nil, err
	}

	return {{.Name}}, nil
}

// 查询多行记录
func {{.Name|Format2StructName}}QueryWhere(db *sql.DB, where string) ({{.Name}} []*{{.Name|Format2StructName}}Table, err error) {
	queryString := "SELECT " + {{.Name|Format2Title}}SelectFields + " FROM {{.Name|AddBackquote}} WHERE " + where
	return do{{.Name|Format2StructName}}Query(db, queryString)
}

// 查询多行记录
func {{.Name|Format2StructName}}Query(db *sql.DB, queryString string) ({{.Name}} []*{{.Name|Format2StructName}}Table, err error) {
	queryString = strings.Replace(queryString, SelectFieldsTemp, {{.Name|Format2Title}}SelectFields, 1)
	return do{{.Name|Format2StructName}}Query(db, queryString)
}

// 查询多行记录（执行）
func do{{.Name|Format2StructName}}Query(db *sql.DB, queryString string) ({{.Name}} []*{{.Name|Format2StructName}}Table, err error) {
	rows, err := db.Query(queryString)
	if err != nil {
		return nil, err
	}
	defer rows.Close()

	for rows.Next() {
		var oneRow = &{{.Name|Format2StructName}}Table{}
		err = rows.Scan( {{range $k, $v := .Fields}}
			&oneRow.{{$v.Name|Format2StructName}},{{end}}
		)
		if err != nil {
			return nil, err
		}

		{{.Name}} = append({{.Name}}, oneRow)
	}

	return {{.Name}}, nil
}
`
	// 生成的gen_common.go文件的模版
	commonCodeTemplate = `// DON'T EDIT *** generated by go-db-models *** DON'T EDIT //
package {{.PackageName}}

const (
	SelectFieldsTemp string = "{select-fields-temp}"
)
`
)
<|endoftext|>


<commit_before>package mpris2

import dbus "github.com/guelfey/go.dbus"

type Player struct {
	Name string // name of the player
	obj *dbus.Object // associated dbus object
}

func NewPlayer(name string) (*Player, error) {
	player := new(Player)
	player.Name = "org.mpris.MediaPlayer2." + name

	conn, err := dbus.SessionBus()
	if err != nil {
		return nil, err
	}

	player.obj = conn.Object(player.Name, "/org/mpris/MediaPlayer2")

	return player, err
}

func (player *Player) Next() {
	player.obj.Call("org.mpris.MediaPlayer2.Player.Next", 0)
}

func (player *Player) Previous() {
	player.obj.Call("org.mpris.MediaPlayer2.Player.Previous", 0)
}

func (player *Player) Pause() {
	player.obj.Call("org.mpris.MediaPlayer2.Player.Pause", 0)
}

func (player *Player) PlayPause() {
	player.obj.Call("org.mpris.MediaPlayer2.Player.PlayPause", 0)
}

func (player *Player) Stop() {
	player.obj.Call("org.mpris.MediaPlayer2.Player.Stop", 0)
}

func (player *Player) Play() {
	player.obj.Call("org.mpris.MediaPlayer2.Player.Play", 0)
}

// TODO: fix this function
func (player *Player) Seek(offset uint32) {
	player.obj.Call("org.mpris.MediaPlayer2.Player.Seek", 0, offset)
}
<commit_msg>update<commit_after>package mpris2

import dbus "github.com/guelfey/go.dbus"

type Player struct {
	Name string // name of the player
	obj *dbus.Object // associated dbus object
}

func NewPlayer(name string) (*Player, error) {
	player := new(Player)
	player.Name = "org.mpris.MediaPlayer2." + name

	conn, err := dbus.SessionBus()
	if err != nil {
		return nil, err
	}

	player.obj = conn.Object(player.Name, "/org/mpris/MediaPlayer2")

	return player, err
}

// MediaPlayer2 Methods

// Brings the media player's user interface to the front
// using any appropriate mechanism available
func (player *Player) Raise() {
	player.obj.Call("org.mpris.MediaPlayer2.Raise", 0)
}

// Causes the media player to stop running
func (player *Player) Quit() {
	player.obj.Call("org.mpris.MediaPlayer2.Quit", 0)
}

// MediaPlayer2.Player Methods

// Skips to the next track in the tracklist
func (player *Player) Next() {
	player.obj.Call("org.mpris.MediaPlayer2.Player.Next", 0)
}

// Skips to the previous track in the tracklist
func (player *Player) Previous() {
	player.obj.Call("org.mpris.MediaPlayer2.Player.Previous", 0)
}

// Pauses playback
func (player *Player) Pause() {
	player.obj.Call("org.mpris.MediaPlayer2.Player.Pause", 0)
}

// Pauses playback
// If playback is already paused, resumes playback
func (player *Player) PlayPause() {
	player.obj.Call("org.mpris.MediaPlayer2.Player.PlayPause", 0)
}

// Stops playback
func (player *Player) Stop() {
	player.obj.Call("org.mpris.MediaPlayer2.Player.Stop", 0)
}

// Starts or resumes playback
func (player *Player) Play() {
	player.obj.Call("org.mpris.MediaPlayer2.Player.Play", 0)
}

// Seeks forward in the current track by the specified
// number of microseconds
func (player *Player) Seek(offset uint32) {
	player.obj.Call("org.mpris.MediaPlayer2.Player.Seek", 0, offset)
}
<|endoftext|>


<commit_before>package isolated

import (
	"code.cloudfoundry.org/cli/integration/helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("update-org-quota command", func() {
	Describe("help", func() {
		When("--help flag is set", func() {
			It("Displays command usage to output", func() {
				session := helpers.CF("update-org-quota", "--help")
				Eventually(session).Should(Say("NAME:"))
				Eventually(session).Should(Say("update-org-quota - Update an existing organization quota"))
				Eventually(session).Should(Say("USAGE:"))
				Eventually(session).Should(Say(`cf update-org-quota QUOTA [-m TOTAL_MEMORY] [-i INSTANCE_MEMORY] \[-n NEW_NAME\] \[-r ROUTES\] \[-s SERVICE_INSTANCES\] \[-a APP_INSTANCES\] \[--allow-paid-service-plans | --disallow-paid-service-plans\] \[--reserved-route-ports RESERVED_ROUTE_PORTS\]`))
				Eventually(session).Should(Say("OPTIONS:"))
				Eventually(session).Should(Say(`-a\s+Total number of application instances. -1 represents an unlimited amount.`))
				Eventually(session).Should(Say(`--allow-paid-service-plans\s+Allow provisioning instances of paid service plans.`))
				Eventually(session).Should(Say(`--disallow-paid-service-plans\s+Disallow provisioning instances of paid service plans.`))
				Eventually(session).Should(Say(`-i\s+Maximum amount of memory a process can have \(e.g. 1024M, 1G, 10G\). -1 represents an unlimited amount.`))
				Eventually(session).Should(Say(`-m\s+Total amount of memory all processes can have \(e.g. 1024M, 1G, 10G\).  -1 represents an unlimited amount.`))
				Eventually(session).Should(Say(`-n\s+New name`))
				Eventually(session).Should(Say(`-r\s+Total number of routes. -1 represents an unlimited amount.`))
				Eventually(session).Should(Say(`--reserved-route-ports\s+Maximum number of routes that may be created with ports. -1 represents an unlimited amount.`))
				Eventually(session).Should(Say(`-s\s+Total number of service instances. -1 represents an unlimited amount.`))
				Eventually(session).Should(Say("SEE ALSO:"))
				Eventually(session).Should(Say("org, org-quota"))
				Eventually(session).Should(Exit(0))
			})

		})
	})

	Describe("command behavior", func() {
		var (
			orgName   string
			spaceName string
			quotaName string
			username  string
		)

		BeforeEach(func() {
			orgName = helpers.NewOrgName()
			spaceName = helpers.NewSpaceName()
			username, _ = helpers.GetCredentials()

			helpers.SetupCF(orgName, spaceName)
			quotaName = helpers.QuotaName()
			totalMemory := "24M"
			instanceMemory := "6M"
			routes := "8"
			serviceInstances := "2"
			appInstances := "3"
			reservedRoutePorts := "1"
			session := helpers.CF("create-org-quota", quotaName, "-m", totalMemory, "-i", instanceMemory, "-r", routes, "-s", serviceInstances, "-a", appInstances, "--allow-paid-service-plans", "--reserved-route-ports", reservedRoutePorts)
			Eventually(session).Should(Exit(0))
		})

		AfterEach(func() {
			helpers.QuickDeleteOrg(orgName)
		})

		It("updates a quota", func() {
			totalMemory := "25M"
			instanceMemory := "5M"
			serviceInstances := "1"
			appInstances := "2"
			reservedRoutePorts := "0"
			session := helpers.CF("update-org-quota", quotaName, "-m", totalMemory, "-i", instanceMemory, "-s", serviceInstances, "-a", appInstances, "--disallow-paid-service-plans", "--reserved-route-ports", reservedRoutePorts)
			Eventually(session).Should(Say(`Updating org quota %s as %s\.\.\.`, quotaName, username))
			Eventually(session).Should(Exit(0))

			session = helpers.CF("org-quota", quotaName)
			Eventually(session).Should(Say(`total memory:\s+%s`, totalMemory))
			Eventually(session).Should(Say(`instance memory:\s+%s`, instanceMemory))
			Eventually(session).Should(Say(`routes:\s+%s`, "8"))
			Eventually(session).Should(Say(`service instances:\s+%s`, serviceInstances))
			Eventually(session).Should(Say(`paid service plans:\s+%s`, "disallowed"))
			Eventually(session).Should(Say(`app instances:\s+%s`, appInstances))
			Eventually(session).Should(Say(`route ports:\s+%s`, reservedRoutePorts))
			Eventually(session).Should(Say("OK"))
			Eventually(session).Should(Exit(0))
		})

		When("the -n rename flag is provided", func() {
			var newQuotaName string

			BeforeEach(func() {
				newQuotaName = helpers.QuotaName()
			})

			It("renames the quota", func() {
				session := helpers.CF("update-org-quota", quotaName, "-n", newQuotaName)

				Eventually(session).Should(Say(`Updating org quota %s as %s\.\.\.`, quotaName, username))
				Eventually(session).Should(Exit(0))

				session = helpers.CF("org-quota", newQuotaName)
				Eventually(session).Should(Exit(0))
			})

			When("an org quota with the new name already exists", func() {
				It("returns an unprocessable error from the API", func() {
					session := helpers.CF("update-org-quota", quotaName, "-n", "default")

					Eventually(session.Err).Should(Say(`Organization Quota 'default' already exists\.`))
					Eventually(session).Should(Say("FAILED"))
					Eventually(session).Should(Exit(1))
				})
			})
		})

		When("the named quota does not exist", func() {
			It("displays a missing quota error message and fails", func() {
				session := helpers.CF("update-org-quota", "bogus-org-quota")
				Eventually(session).Should(Say(`Updating org quota bogus-org-quota as %s\.\.\.`, username))
				Eventually(session).Should(Say("FAILED"))
				Eventually(session.Err).Should(Say(`Quota %s not found`, "bogus-org-quota"))
				Eventually(session).Should(Exit(1))
			})
		})

		When("no user-provided updates to the quota are specified", func() {
			It("behaves idempotently and succeeds", func() {
				session := helpers.CF("update-org-quota", quotaName)
				Eventually(session).Should(Say(`Updating org quota %s as %s\.\.\.`, quotaName, username))
				Eventually(session).Should(Say("OK"))
				Eventually(session).Should(Exit(0))
			})
		})

		When("conflicting flags are specified", func() {
			It("displays a flag conflict error message and fails", func() {
				session := helpers.CF("update-org-quota", quotaName, "--allow-paid-service-plans", "--disallow-paid-service-plans")
				Eventually(session).Should(Say("FAILED"))
				Eventually(session.Err).Should(Say(`Incorrect Usage: The following arguments cannot be used together: --allow-paid-service-plans, --disallow-paid-service-plans`))
				Eventually(session).Should(Exit(1))
			})
		})
	})
})
<commit_msg>v7: Remove old assertion from update-org-quota integration tests<commit_after>package isolated

import (
	"code.cloudfoundry.org/cli/integration/helpers"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	. "github.com/onsi/gomega/gbytes"
	. "github.com/onsi/gomega/gexec"
)

var _ = Describe("update-org-quota command", func() {
	Describe("help", func() {
		When("--help flag is set", func() {
			It("Displays command usage to output", func() {
				session := helpers.CF("update-org-quota", "--help")
				Eventually(session).Should(Say("NAME:"))
				Eventually(session).Should(Say("update-org-quota - Update an existing organization quota"))
				Eventually(session).Should(Say("USAGE:"))
				Eventually(session).Should(Say(`cf update-org-quota QUOTA [-m TOTAL_MEMORY] [-i INSTANCE_MEMORY] \[-n NEW_NAME\] \[-r ROUTES\] \[-s SERVICE_INSTANCES\] \[-a APP_INSTANCES\] \[--allow-paid-service-plans | --disallow-paid-service-plans\] \[--reserved-route-ports RESERVED_ROUTE_PORTS\]`))
				Eventually(session).Should(Say("OPTIONS:"))
				Eventually(session).Should(Say(`-a\s+Total number of application instances. -1 represents an unlimited amount.`))
				Eventually(session).Should(Say(`--allow-paid-service-plans\s+Allow provisioning instances of paid service plans.`))
				Eventually(session).Should(Say(`--disallow-paid-service-plans\s+Disallow provisioning instances of paid service plans.`))
				Eventually(session).Should(Say(`-i\s+Maximum amount of memory a process can have \(e.g. 1024M, 1G, 10G\). -1 represents an unlimited amount.`))
				Eventually(session).Should(Say(`-m\s+Total amount of memory all processes can have \(e.g. 1024M, 1G, 10G\).  -1 represents an unlimited amount.`))
				Eventually(session).Should(Say(`-n\s+New name`))
				Eventually(session).Should(Say(`-r\s+Total number of routes. -1 represents an unlimited amount.`))
				Eventually(session).Should(Say(`--reserved-route-ports\s+Maximum number of routes that may be created with ports. -1 represents an unlimited amount.`))
				Eventually(session).Should(Say(`-s\s+Total number of service instances. -1 represents an unlimited amount.`))
				Eventually(session).Should(Say("SEE ALSO:"))
				Eventually(session).Should(Say("org, org-quota"))
				Eventually(session).Should(Exit(0))
			})
		})
	})

	Describe("command behavior", func() {
		var (
			orgName   string
			spaceName string
			quotaName string
			username  string
		)

		BeforeEach(func() {
			orgName = helpers.NewOrgName()
			spaceName = helpers.NewSpaceName()
			username, _ = helpers.GetCredentials()

			helpers.SetupCF(orgName, spaceName)
			quotaName = helpers.QuotaName()
			totalMemory := "24M"
			instanceMemory := "6M"
			routes := "8"
			serviceInstances := "2"
			appInstances := "3"
			reservedRoutePorts := "1"
			session := helpers.CF("create-org-quota", quotaName, "-m", totalMemory, "-i", instanceMemory, "-r", routes, "-s", serviceInstances, "-a", appInstances, "--allow-paid-service-plans", "--reserved-route-ports", reservedRoutePorts)
			Eventually(session).Should(Exit(0))
		})

		AfterEach(func() {
			helpers.QuickDeleteOrg(orgName)
		})

		It("updates a quota", func() {
			totalMemory := "25M"
			instanceMemory := "5M"
			serviceInstances := "1"
			appInstances := "2"
			reservedRoutePorts := "0"
			session := helpers.CF("update-org-quota", quotaName, "-m", totalMemory, "-i", instanceMemory, "-s", serviceInstances, "-a", appInstances, "--disallow-paid-service-plans", "--reserved-route-ports", reservedRoutePorts)
			Eventually(session).Should(Say(`Updating org quota %s as %s\.\.\.`, quotaName, username))
			Eventually(session).Should(Exit(0))

			session = helpers.CF("org-quota", quotaName)
			Eventually(session).Should(Say(`total memory:\s+%s`, totalMemory))
			Eventually(session).Should(Say(`instance memory:\s+%s`, instanceMemory))
			Eventually(session).Should(Say(`routes:\s+%s`, "8"))
			Eventually(session).Should(Say(`service instances:\s+%s`, serviceInstances))
			Eventually(session).Should(Say(`paid service plans:\s+%s`, "disallowed"))
			Eventually(session).Should(Say(`app instances:\s+%s`, appInstances))
			Eventually(session).Should(Say(`route ports:\s+%s`, reservedRoutePorts))
			Eventually(session).Should(Exit(0))
		})

		When("the -n rename flag is provided", func() {
			var newQuotaName string

			BeforeEach(func() {
				newQuotaName = helpers.QuotaName()
			})

			It("renames the quota", func() {
				session := helpers.CF("update-org-quota", quotaName, "-n", newQuotaName)

				Eventually(session).Should(Say(`Updating org quota %s as %s\.\.\.`, quotaName, username))
				Eventually(session).Should(Exit(0))

				session = helpers.CF("org-quota", newQuotaName)
				Eventually(session).Should(Exit(0))
			})

			When("an org quota with the new name already exists", func() {
				It("returns an unprocessable error from the API", func() {
					session := helpers.CF("update-org-quota", quotaName, "-n", "default")

					Eventually(session.Err).Should(Say(`Organization Quota 'default' already exists\.`))
					Eventually(session).Should(Say("FAILED"))
					Eventually(session).Should(Exit(1))
				})
			})
		})

		When("the named quota does not exist", func() {
			It("displays a missing quota error message and fails", func() {
				session := helpers.CF("update-org-quota", "bogus-org-quota")
				Eventually(session).Should(Say(`Updating org quota bogus-org-quota as %s\.\.\.`, username))
				Eventually(session).Should(Say("FAILED"))
				Eventually(session.Err).Should(Say(`Quota %s not found`, "bogus-org-quota"))
				Eventually(session).Should(Exit(1))
			})
		})

		When("no user-provided updates to the quota are specified", func() {
			It("behaves idempotently and succeeds", func() {
				session := helpers.CF("update-org-quota", quotaName)
				Eventually(session).Should(Say(`Updating org quota %s as %s\.\.\.`, quotaName, username))
				Eventually(session).Should(Say("OK"))
				Eventually(session).Should(Exit(0))
			})
		})

		When("conflicting flags are specified", func() {
			It("displays a flag conflict error message and fails", func() {
				session := helpers.CF("update-org-quota", quotaName, "--allow-paid-service-plans", "--disallow-paid-service-plans")
				Eventually(session).Should(Say("FAILED"))
				Eventually(session.Err).Should(Say(`Incorrect Usage: The following arguments cannot be used together: --allow-paid-service-plans, --disallow-paid-service-plans`))
				Eventually(session).Should(Exit(1))
			})
		})
	})
})
<|endoftext|>