<commit_before>package transloadit

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"os"
	"time"
)

type Assembly struct {
	client *Client
	// Notify url to send a request to once the assembly finishes.
	// See https://transloadit.com/docs#notifications.
	NotifyUrl string
	// Optional template id to use instead of adding steps.
	TemplateId string
	// Wait until the assembly completes (or is canceled).
	Blocking bool
	steps    map[string]map[string]interface{}
	readers  []*upload
}

type upload struct {
	Field  string
	Name   string
	Reader io.ReadCloser
}

type AssemblyReplay struct {
	assemblyId string
	client     *Client
	// Notify url to send a request to once the assembly finishes.
	// See https://transloadit.com/docs#notifications.
	NotifyUrl string
	// Wait until the assembly completes (or is canceled).
	Blocking bool
	// Reparse the template when replaying. Useful if the template has changed
	// since the orignal assembly was created.
	ReparseTemplate bool
	steps           map[string]map[string]interface{}
}

type AssemblyList struct {
	Assemblies []*AssemblyListItem `json:"items"`
	Count      int                 `json:"count"`
}

type AssemblyListItem struct {
	AssemblyId        string    `json:"id"`
	AccountId         string    `json:"account_id"`
	TemplateId        string    `json:"template_id"`
	Instance          string    `json:"instance"`
	NotifyUrl         string    `json:"notify_url"`
	RedirectUrl       string    `json:"redirect_url"`
	ExecutionDuration float32   `json:"execution_duration"`
	ExecutionStart    *Time     `json:"execution_start"`
	Created           time.Time `json:"created"`
	Ok                string    `json:"ok"`
	Error             string    `json:"error"`
	Files             string    `json:"files"`
}

type Time struct {
	*time.Time
}

func (t *Time) UnmarshalJSON(b []byte) error {
	// The error is ignored intentionally, as the date returned by Transloadit
	// may be invalid, e.g. "0000-00-00". This invalid date value actually
	// represents the absence of a date and we therefore make t.Time as nil-pointer.
	_ = json.Unmarshal(b, &t.Time)
	return nil
}

type AssemblyInfo struct {
	AssemblyId             string                 `json:"assembly_id"`
	ParentId               string                 `json:"parent_id"`
	AssemblyUrl            string                 `json:"assembly_url"`
	AssemblySslUrl         string                 `json:"assembly_ssl_url"`
	BytesReceived          int                    `json:"bytes_received"`
	BytesExpected          int                    `json:"bytes_expected"`
	ClientAgent            string                 `json:"client_agent"`
	ClientIp               string                 `json:"client_ip"`
	ClientReferer          string                 `json:"client_referer"`
	StartDate              string                 `json:"start_date"`
	IsInfinite             bool                   `json:"is_infinite"`
	HasDupeJobs            bool                   `json:"has_dupe_jobs"`
	UploadDuration         float32                `json:"upload_duration"`
	NotifyUrl              string                 `json:"notify_url"`
	NotifyStart            string                 `json:"notify_start"`
	NotifyStatus           string                 `json:"notify_status"`
	NotifyDuation          float32                `json:"notify_duration"`
	LastJobCompleted       string                 `json:"last_job_completed"`
	ExecutionDuration      float32                `json:"execution_duration"`
	ExecutionStart         string                 `json:"execution_start"`
	Created                string                 `json:"created"`
	Ok                     string                 `json:"ok"`
	Message                string                 `json:"message"`
	Files                  string                 `json:"files"`
	Fields                 map[string]interface{} `json:"fields"`
	BytesUsage             int                    `json:"bytes_usage"`
	FilesToStoreOnS3       int                    `json:"files_to_store_on_s3"`
	QueuedFilesToStoreOnS3 int                    `json:"queued_files_to_store_on_s3"`
	ExecutingJobs          []string               `json:"executing_jobs"`
	StartedJobs            []string               `json:"started_jobs"`
	ParentAssemblyStatus   *AssemblyInfo          `json:"parent_assembly_status"`
	Uploads                []*FileInfo            `json:"uploads"`
	Results                map[string][]*FileInfo `json:"results"`
	Params                 string                 `json:"params"`
	Error                  string                 `json:"error"`
}

type FileInfo struct {
	Id               string                 `json:"id"`
	Name             string                 `json:"name"`
	Basename         string                 `json:"basename"`
	Ext              string                 `json:"ext"`
	Size             int                    `json:"size"`
	Mime             string                 `json:"mime"`
	Type             string                 `json:"type"`
	Field            string                 `json:"field"`
	Md5Hash          string                 `json:"md5hash"`
	OriginalMd5Hash  string                 `json:"original_md5hash"`
	OriginalId       string                 `json:"original_id"`
	OriginalBasename string                 `json:"original_basename"`
	Url              string                 `json:"url"`
	SslUrl           string                 `json:"ssl_url"`
	Meta             map[string]interface{} `json:"meta"`
}

// Create a new assembly instance which can be executed later.
func (client *Client) CreateAssembly() *Assembly {
	return &Assembly{
		client:  client,
		steps:   make(map[string]map[string]interface{}),
		readers: make([]*upload, 0),
	}
}

// Add another reader to upload later.
func (assembly *Assembly) AddReader(field, name string, reader io.ReadCloser) {
	assembly.readers = append(assembly.readers, &upload{
		Field:  field,
		Name:   name,
		Reader: reader,
	})
}

// Add another file to upload later.
func (assembly *Assembly) AddFile(field, name string) error {
	file, err := os.Open(name)
	if err != nil {
		return err
	}

	assembly.AddReader(field, name, file)
	return nil
}

// Add a step to the assembly.
func (assembly *Assembly) AddStep(name string, details map[string]interface{}) {
	assembly.steps[name] = details
}

// Start the assembly and upload all files.
// When an error is returned you should also check AssemblyInfo.Error for more
// information about the error. This happens when there is an error returned by
// the Transloadit API:
//  info, err := assembly.Upload()
//  if err != nil {
//  	if info != nil && info.Error != "" {
//  		// See info.Error
//  	}
//  	panic(err)
//  }
func (assembly *Assembly) Upload() (*AssemblyInfo, error) {
	req, err := assembly.makeRequest()
	if err != nil {
		return nil, fmt.Errorf("failed to create assembly request: %s", err)
	}

	var info AssemblyInfo
	// TODO: add context.Context
	if err = assembly.client.doRequest(req, &info); err != nil {
		return nil, err
	}

	if info.Error != "" {
		return &info, fmt.Errorf("failed to create assembly: %s", info.Error)
	}

	if !assembly.Blocking {
		return &info, err
	}

	watcher := assembly.client.WaitForAssembly(info.AssemblyUrl)

	select {
	case res := <-watcher.Response:
		// Assembly completed
		return res, nil
	case err := <-watcher.Error:
		// Error appeared
		return nil, err
	}
}

func (assembly *Assembly) makeRequest() (*http.Request, error) {
	// Get bored instance to upload files to
	bored, err := assembly.client.getBoredInstance()
	if err != nil {
		return nil, fmt.Errorf("unable to create upload request: %s", err)
	}

	// TODO: test with huge files
	url := "http://api2-" + bored + "/assemblies"
	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)

	// Add files to upload
	for _, reader := range assembly.readers {
		part, err := writer.CreateFormFile(reader.Field, reader.Name)
		if err != nil {
			return nil, fmt.Errorf("unable to create upload request: %s", err)
		}

		_, err = io.Copy(part, reader.Reader)
		if err != nil {
			return nil, fmt.Errorf("unable to create upload request: %s", err)
		}

		err = reader.Reader.Close()
		if err != nil {
			return nil, fmt.Errorf("unable to create upload request: %s", err)
		}
	}

	options := make(map[string]interface{})

	if len(assembly.steps) != 0 {
		options["steps"] = assembly.steps
	}

	if assembly.TemplateId != "" {
		options["template_id"] = assembly.TemplateId
	}

	if assembly.NotifyUrl != "" {
		options["notify_url"] = assembly.NotifyUrl
	}

	params, signature, err := assembly.client.sign(options)
	if err != nil {
		return nil, fmt.Errorf("unable to create upload request: %s", err)
	}

	// Add additional keys and values
	err = writer.WriteField("params", params)
	if err != nil {
		return nil, fmt.Errorf("unable to create upload request: %s", err)
	}
	err = writer.WriteField("signature", signature)
	if err != nil {
		return nil, fmt.Errorf("unable to create upload request: %s", err)
	}

	// Close multipart writer
	err = writer.Close()
	if err != nil {
		return nil, fmt.Errorf("unable to create upload request: %s", err)
	}

	// Create HTTP request
	req, err := http.NewRequest("POST", url, body)
	if err != nil {
		return nil, fmt.Errorf("unable to create upload request: %s", err)
	}

	req.Header.Set("Content-Type", writer.FormDataContentType())

	return req, nil
}

// Get information about an assembly using its url.
func (client *Client) GetAssembly(assemblyUrl string) (*AssemblyInfo, error) {
	var info AssemblyInfo
	err := client.request("GET", assemblyUrl, nil, &info)

	return &info, err
}

// Cancel an assembly using its URL. This function will return the updated
// information about the assembly after the cancellation.
func (client *Client) CancelAssembly(assemblyUrl string) (*AssemblyInfo, error) {
	var info AssemblyInfo
	err := client.request("DELETE", assemblyUrl, nil, &info)

	return &info, err
}

// Create a new AssemblyReplay instance.
func (client *Client) ReplayAssembly(assemblyId string) *AssemblyReplay {
	return &AssemblyReplay{
		client:     client,
		steps:      make(map[string]map[string]interface{}),
		assemblyId: assemblyId,
	}
}

// Add a step to override the original ones.
func (assembly *AssemblyReplay) AddStep(name string, details map[string]interface{}) {
	assembly.steps[name] = details
}

// Start the assembly replay.
func (assembly *AssemblyReplay) Start() (*AssemblyInfo, error) {
	options := map[string]interface{}{
		"steps": assembly.steps,
	}

	if assembly.ReparseTemplate {
		options["reparse_template"] = 1
	}

	if assembly.NotifyUrl != "" {
		options["notify_url"] = assembly.NotifyUrl
	}

	var info AssemblyInfo
	err := assembly.client.request("POST", "assemblies/"+assembly.assemblyId+"/replay", options, &info)
	if err != nil {
		return nil, err
	}

	if info.Error != "" {
		return &info, fmt.Errorf("failed to start assembly replay: %s", info.Error)
	}

	if !assembly.Blocking {
		return &info, nil
	}

	watcher := assembly.client.WaitForAssembly(info.AssemblyUrl)

	select {
	case res := <-watcher.Response:
		// Assembly completed
		return res, nil
	case err := <-watcher.Error:
		// Error appeared
		return nil, err
	}
}

// List all assemblies matching the criterias.
func (client *Client) ListAssemblies(options *ListOptions) (*AssemblyList, error) {
	var assemblies AssemblyList
	err := client.listRequest("assemblies", options, &assemblies)

	return &assemblies, err
}
<commit_msg>Do not buffer multipart request before sending request<commit_after>package transloadit

import (
	"encoding/json"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"os"
	"time"
)

type Assembly struct {
	client *Client
	// Notify url to send a request to once the assembly finishes.
	// See https://transloadit.com/docs#notifications.
	NotifyUrl string
	// Optional template id to use instead of adding steps.
	TemplateId string
	// Wait until the assembly completes (or is canceled).
	Blocking bool
	steps    map[string]map[string]interface{}
	readers  []*upload
}

type upload struct {
	Field  string
	Name   string
	Reader io.ReadCloser
}

type AssemblyReplay struct {
	assemblyId string
	client     *Client
	// Notify url to send a request to once the assembly finishes.
	// See https://transloadit.com/docs#notifications.
	NotifyUrl string
	// Wait until the assembly completes (or is canceled).
	Blocking bool
	// Reparse the template when replaying. Useful if the template has changed
	// since the orignal assembly was created.
	ReparseTemplate bool
	steps           map[string]map[string]interface{}
}

type AssemblyList struct {
	Assemblies []*AssemblyListItem `json:"items"`
	Count      int                 `json:"count"`
}

type AssemblyListItem struct {
	AssemblyId        string    `json:"id"`
	AccountId         string    `json:"account_id"`
	TemplateId        string    `json:"template_id"`
	Instance          string    `json:"instance"`
	NotifyUrl         string    `json:"notify_url"`
	RedirectUrl       string    `json:"redirect_url"`
	ExecutionDuration float32   `json:"execution_duration"`
	ExecutionStart    *Time     `json:"execution_start"`
	Created           time.Time `json:"created"`
	Ok                string    `json:"ok"`
	Error             string    `json:"error"`
	Files             string    `json:"files"`
}

type Time struct {
	*time.Time
}

func (t *Time) UnmarshalJSON(b []byte) error {
	// The error is ignored intentionally, as the date returned by Transloadit
	// may be invalid, e.g. "0000-00-00". This invalid date value actually
	// represents the absence of a date and we therefore make t.Time as nil-pointer.
	_ = json.Unmarshal(b, &t.Time)
	return nil
}

type AssemblyInfo struct {
	AssemblyId             string                 `json:"assembly_id"`
	ParentId               string                 `json:"parent_id"`
	AssemblyUrl            string                 `json:"assembly_url"`
	AssemblySslUrl         string                 `json:"assembly_ssl_url"`
	BytesReceived          int                    `json:"bytes_received"`
	BytesExpected          int                    `json:"bytes_expected"`
	ClientAgent            string                 `json:"client_agent"`
	ClientIp               string                 `json:"client_ip"`
	ClientReferer          string                 `json:"client_referer"`
	StartDate              string                 `json:"start_date"`
	IsInfinite             bool                   `json:"is_infinite"`
	HasDupeJobs            bool                   `json:"has_dupe_jobs"`
	UploadDuration         float32                `json:"upload_duration"`
	NotifyUrl              string                 `json:"notify_url"`
	NotifyStart            string                 `json:"notify_start"`
	NotifyStatus           string                 `json:"notify_status"`
	NotifyDuation          float32                `json:"notify_duration"`
	LastJobCompleted       string                 `json:"last_job_completed"`
	ExecutionDuration      float32                `json:"execution_duration"`
	ExecutionStart         string                 `json:"execution_start"`
	Created                string                 `json:"created"`
	Ok                     string                 `json:"ok"`
	Message                string                 `json:"message"`
	Files                  string                 `json:"files"`
	Fields                 map[string]interface{} `json:"fields"`
	BytesUsage             int                    `json:"bytes_usage"`
	FilesToStoreOnS3       int                    `json:"files_to_store_on_s3"`
	QueuedFilesToStoreOnS3 int                    `json:"queued_files_to_store_on_s3"`
	ExecutingJobs          []string               `json:"executing_jobs"`
	StartedJobs            []string               `json:"started_jobs"`
	ParentAssemblyStatus   *AssemblyInfo          `json:"parent_assembly_status"`
	Uploads                []*FileInfo            `json:"uploads"`
	Results                map[string][]*FileInfo `json:"results"`
	Params                 string                 `json:"params"`
	Error                  string                 `json:"error"`
}

type FileInfo struct {
	Id               string                 `json:"id"`
	Name             string                 `json:"name"`
	Basename         string                 `json:"basename"`
	Ext              string                 `json:"ext"`
	Size             int                    `json:"size"`
	Mime             string                 `json:"mime"`
	Type             string                 `json:"type"`
	Field            string                 `json:"field"`
	Md5Hash          string                 `json:"md5hash"`
	OriginalMd5Hash  string                 `json:"original_md5hash"`
	OriginalId       string                 `json:"original_id"`
	OriginalBasename string                 `json:"original_basename"`
	Url              string                 `json:"url"`
	SslUrl           string                 `json:"ssl_url"`
	Meta             map[string]interface{} `json:"meta"`
}

// Create a new assembly instance which can be executed later.
func (client *Client) CreateAssembly() *Assembly {
	return &Assembly{
		client:  client,
		steps:   make(map[string]map[string]interface{}),
		readers: make([]*upload, 0),
	}
}

// Add another reader to upload later.
func (assembly *Assembly) AddReader(field, name string, reader io.ReadCloser) {
	assembly.readers = append(assembly.readers, &upload{
		Field:  field,
		Name:   name,
		Reader: reader,
	})
}

// Add another file to upload later.
func (assembly *Assembly) AddFile(field, name string) error {
	file, err := os.Open(name)
	if err != nil {
		return err
	}

	assembly.AddReader(field, name, file)
	return nil
}

// Add a step to the assembly.
func (assembly *Assembly) AddStep(name string, details map[string]interface{}) {
	assembly.steps[name] = details
}

// Start the assembly and upload all files.
// When an error is returned you should also check AssemblyInfo.Error for more
// information about the error. This happens when there is an error returned by
// the Transloadit API:
//  info, err := assembly.Upload()
//  if err != nil {
//  	if info != nil && info.Error != "" {
//  		// See info.Error
//  	}
//  	panic(err)
//  }
func (assembly *Assembly) Upload() (*AssemblyInfo, error) {
	req, err := assembly.makeRequest()
	if err != nil {
		return nil, fmt.Errorf("failed to create assembly request: %s", err)
	}

	var info AssemblyInfo
	// TODO: add context.Context
	if err = assembly.client.doRequest(req, &info); err != nil {
		return nil, err
	}

	if info.Error != "" {
		return &info, fmt.Errorf("failed to create assembly: %s", info.Error)
	}

	if !assembly.Blocking {
		return &info, err
	}

	watcher := assembly.client.WaitForAssembly(info.AssemblyUrl)

	select {
	case res := <-watcher.Response:
		// Assembly completed
		return res, nil
	case err := <-watcher.Error:
		// Error appeared
		return nil, err
	}
}

func (assembly *Assembly) makeRequest() (*http.Request, error) {
	// Get bored instance to upload files to
	bored, err := assembly.client.getBoredInstance()
	if err != nil {
		return nil, fmt.Errorf("unable to create upload request: %s", err)
	}

	// TODO: test with huge files
	url := "http://api2-" + bored + "/assemblies"
	bodyReader, bodyWriter := io.Pipe()
	multiWriter := multipart.NewWriter(bodyWriter)

	options := make(map[string]interface{})

	if len(assembly.steps) != 0 {
		options["steps"] = assembly.steps
	}

	if assembly.TemplateId != "" {
		options["template_id"] = assembly.TemplateId
	}

	if assembly.NotifyUrl != "" {
		options["notify_url"] = assembly.NotifyUrl
	}

	params, signature, err := assembly.client.sign(options)
	if err != nil {
		return nil, fmt.Errorf("unable to create upload request: %s", err)
	}

	// All writes to the multipart.Writer multiWriter _must_ happen inside this
	// goroutine because the writer is connected to the HTTP requst using an
	// in-memory pipe. Therefore a write to the multipart.Writer will block until
	// a corresponding read is happening from the HTTP request. The gist is that
	// the writes and reads must not occur sequentially but in parallel.
	go func() {
		defer bodyWriter.Close()
		defer multiWriter.Close()
		// Add additional keys and values

		if err := multiWriter.WriteField("params", params); err != nil {
			fmt.Println(fmt.Errorf("unable to write params field: %s", err))
		}
		if err := multiWriter.WriteField("signature", signature); err != nil {
			fmt.Println(fmt.Errorf("unable to write signature field: %s", err))
		}

		// Add files to upload
		for _, reader := range assembly.readers {
			defer reader.Reader.Close()

			part, err := multiWriter.CreateFormFile(reader.Field, reader.Name)
			if err != nil {
				fmt.Println(fmt.Errorf("unable to create form field: %s", err))
			}

			if _, err := io.Copy(part, reader.Reader); err != nil {
				fmt.Println(fmt.Errorf("unable to create upload request: %s", err))
			}
		}
	}()

	// Create HTTP request
	req, err := http.NewRequest("POST", url, bodyReader)
	if err != nil {
		return nil, fmt.Errorf("unable to create upload request: %s", err)
	}

	req.Header.Set("Content-Type", multiWriter.FormDataContentType())

	return req, nil
}

// Get information about an assembly using its url.
func (client *Client) GetAssembly(assemblyUrl string) (*AssemblyInfo, error) {
	var info AssemblyInfo
	err := client.request("GET", assemblyUrl, nil, &info)

	return &info, err
}

// Cancel an assembly using its URL. This function will return the updated
// information about the assembly after the cancellation.
func (client *Client) CancelAssembly(assemblyUrl string) (*AssemblyInfo, error) {
	var info AssemblyInfo
	err := client.request("DELETE", assemblyUrl, nil, &info)

	return &info, err
}

// Create a new AssemblyReplay instance.
func (client *Client) ReplayAssembly(assemblyId string) *AssemblyReplay {
	return &AssemblyReplay{
		client:     client,
		steps:      make(map[string]map[string]interface{}),
		assemblyId: assemblyId,
	}
}

// Add a step to override the original ones.
func (assembly *AssemblyReplay) AddStep(name string, details map[string]interface{}) {
	assembly.steps[name] = details
}

// Start the assembly replay.
func (assembly *AssemblyReplay) Start() (*AssemblyInfo, error) {
	options := map[string]interface{}{
		"steps": assembly.steps,
	}

	if assembly.ReparseTemplate {
		options["reparse_template"] = 1
	}

	if assembly.NotifyUrl != "" {
		options["notify_url"] = assembly.NotifyUrl
	}

	var info AssemblyInfo
	err := assembly.client.request("POST", "assemblies/"+assembly.assemblyId+"/replay", options, &info)
	if err != nil {
		return nil, err
	}

	if info.Error != "" {
		return &info, fmt.Errorf("failed to start assembly replay: %s", info.Error)
	}

	if !assembly.Blocking {
		return &info, nil
	}

	watcher := assembly.client.WaitForAssembly(info.AssemblyUrl)

	select {
	case res := <-watcher.Response:
		// Assembly completed
		return res, nil
	case err := <-watcher.Error:
		// Error appeared
		return nil, err
	}
}

// List all assemblies matching the criterias.
func (client *Client) ListAssemblies(options *ListOptions) (*AssemblyList, error) {
	var assemblies AssemblyList
	err := client.listRequest("assemblies", options, &assemblies)

	return &assemblies, err
}
<|endoftext|>


<commit_before>package dhcp6

import (
	"net"
	"math/rand"
	"time"
	"math/big"
	"hash/fnv"
	"sync"
	"fmt"
)

type AssociationExpiration struct {
	expiresAt time.Time
	ia *IdentityAssociation
}

type Fifo struct {q []interface{}}

func newFifo() Fifo {
	return Fifo{q: make([]interface{}, 0, 1000)}
}

func (f *Fifo) Push(v interface{}) {
	f.q = append(f.q, v)
}

func (f *Fifo) Shift() interface{} {
	var to_ret interface{}
	to_ret, f.q = f.q[0], f.q[1:]
	return to_ret
}

func (f *Fifo) Size() int {
	return len(f.q)
}

func (f *Fifo) Peek() interface{} {
	if len(f.q) == 0 {
		return nil
	}
	return f.q[0]
}

type RandomAddressPool struct {
	poolStartAddress               *big.Int
	poolSize                 	   uint64
	identityAssociations           map[uint64]*IdentityAssociation
	usedIps                        map[uint64]struct{}
	identityAssociationExpirations Fifo
	validLifetime                  uint32 // in seconds
	timeNow                        func() time.Time
	lock                           sync.Mutex
}

func NewRandomAddressPool(poolStartAddress net.IP, poolSize uint64, validLifetime uint32) *RandomAddressPool {
	to_ret := &RandomAddressPool{}
	to_ret.validLifetime = validLifetime
	to_ret.poolStartAddress = big.NewInt(0)
	to_ret.poolStartAddress.SetBytes(poolStartAddress)
	to_ret.poolSize = poolSize
	to_ret.identityAssociations = make(map[uint64]*IdentityAssociation)
	to_ret.usedIps = make(map[uint64]struct{})
	to_ret.identityAssociationExpirations = newFifo()
	to_ret.timeNow = func() time.Time { return time.Now() }

	ticker := time.NewTicker(time.Second * 10).C
	go func() {
		for {
			<- ticker
			to_ret.ExpireIdentityAssociations()
		}
	}()

	return to_ret
}

func (p *RandomAddressPool) ReserveAddresses(clientId []byte, interfaceIds [][]byte) ([]*IdentityAssociation, error) {
	p.lock.Lock()
	defer p.lock.Unlock()

	ret := make([]*IdentityAssociation, 0, len(interfaceIds))
	rng := rand.New(rand.NewSource(p.timeNow().UnixNano()))

	for _, interfaceId := range (interfaceIds) {
		clientIdHash := p.calculateIaIdHash(clientId, interfaceId)
		association, exists := p.identityAssociations[clientIdHash];

		if exists {
			ret = append(ret, association)
			continue
		}
		if uint64(len(p.usedIps)) == p.poolSize {
			return ret, fmt.Errorf("No more free ip addresses are currently available in the pool")
		}

		for {
			// we assume that ip addresses adhere to high 64 bits for net and subnet ids, low 64 bits are for host id rule
			hostOffset := rng.Uint64() % p.poolSize
			newIp := big.NewInt(0).Add(p.poolStartAddress, big.NewInt(0).SetUint64(hostOffset))
			_, exists := p.usedIps[newIp.Uint64()];
			if !exists {
				timeNow := p.timeNow()
				association := &IdentityAssociation{ClientId: clientId,
					InterfaceId: interfaceId,
					IpAddress: newIp.Bytes(),
					CreatedAt: timeNow}
				p.identityAssociations[clientIdHash] = association
				p.usedIps[newIp.Uint64()] = struct{}{}
				p.identityAssociationExpirations.Push(&AssociationExpiration{expiresAt: p.calculateAssociationExpiration(timeNow), ia: association})
				ret = append(ret, association)
				break
			}
		}
	}

	return ret, nil
}

func  (p *RandomAddressPool) ReleaseAddresses(clientId []byte, interfaceIds [][]byte) {
	p.lock.Lock()
	defer p.lock.Unlock()

	for _, interfaceId := range(interfaceIds) {
		association, exists := p.identityAssociations[p.calculateIaIdHash(clientId, interfaceId)]
		if !exists {
			continue
		}
		delete(p.usedIps, big.NewInt(0).SetBytes(association.IpAddress).Uint64())
		delete(p.identityAssociations, p.calculateIaIdHash(clientId, interfaceId))
	}
}

func (p *RandomAddressPool) ExpireIdentityAssociations() {
	p.lock.Lock()
	defer p.lock.Unlock()

	for {
		if p.identityAssociationExpirations.Size() < 1 { break }
		expiration := p.identityAssociationExpirations.Peek().(*AssociationExpiration)
		if p.timeNow().Before(expiration.expiresAt) { break }
		p.identityAssociationExpirations.Shift()
		delete(p.identityAssociations, p.calculateIaIdHash(expiration.ia.ClientId, expiration.ia.InterfaceId))
		delete(p.usedIps, big.NewInt(0).SetBytes(expiration.ia.IpAddress).Uint64())
	}
}

func (p *RandomAddressPool) calculateAssociationExpiration(now time.Time) time.Time {
	return now.Add(time.Duration(p.validLifetime)*time.Second)
}

func (p *RandomAddressPool) calculateIaIdHash(clientId, interfaceId []byte) uint64 {
	h := fnv.New64a()
	h.Write(clientId)
	h.Write(interfaceId)
	return h.Sum64()
}
<commit_msg>For compatibility with 1.7 replaced rand.Uint64() call with calls to rand.Uint32()<commit_after>package dhcp6

import (
	"net"
	"math/rand"
	"time"
	"math/big"
	"hash/fnv"
	"sync"
	"fmt"
)

type AssociationExpiration struct {
	expiresAt time.Time
	ia *IdentityAssociation
}

type Fifo struct {q []interface{}}

func newFifo() Fifo {
	return Fifo{q: make([]interface{}, 0, 1000)}
}

func (f *Fifo) Push(v interface{}) {
	f.q = append(f.q, v)
}

func (f *Fifo) Shift() interface{} {
	var to_ret interface{}
	to_ret, f.q = f.q[0], f.q[1:]
	return to_ret
}

func (f *Fifo) Size() int {
	return len(f.q)
}

func (f *Fifo) Peek() interface{} {
	if len(f.q) == 0 {
		return nil
	}
	return f.q[0]
}

type RandomAddressPool struct {
	poolStartAddress               *big.Int
	poolSize                 	   uint64
	identityAssociations           map[uint64]*IdentityAssociation
	usedIps                        map[uint64]struct{}
	identityAssociationExpirations Fifo
	validLifetime                  uint32 // in seconds
	timeNow                        func() time.Time
	lock                           sync.Mutex
}

func NewRandomAddressPool(poolStartAddress net.IP, poolSize uint64, validLifetime uint32) *RandomAddressPool {
	to_ret := &RandomAddressPool{}
	to_ret.validLifetime = validLifetime
	to_ret.poolStartAddress = big.NewInt(0)
	to_ret.poolStartAddress.SetBytes(poolStartAddress)
	to_ret.poolSize = poolSize
	to_ret.identityAssociations = make(map[uint64]*IdentityAssociation)
	to_ret.usedIps = make(map[uint64]struct{})
	to_ret.identityAssociationExpirations = newFifo()
	to_ret.timeNow = func() time.Time { return time.Now() }

	ticker := time.NewTicker(time.Second * 10).C
	go func() {
		for {
			<- ticker
			to_ret.ExpireIdentityAssociations()
		}
	}()

	return to_ret
}

func (p *RandomAddressPool) ReserveAddresses(clientId []byte, interfaceIds [][]byte) ([]*IdentityAssociation, error) {
	p.lock.Lock()
	defer p.lock.Unlock()

	ret := make([]*IdentityAssociation, 0, len(interfaceIds))
	rng := rand.New(rand.NewSource(p.timeNow().UnixNano()))

	for _, interfaceId := range (interfaceIds) {
		clientIdHash := p.calculateIaIdHash(clientId, interfaceId)
		association, exists := p.identityAssociations[clientIdHash];

		if exists {
			ret = append(ret, association)
			continue
		}
		if uint64(len(p.usedIps)) == p.poolSize {
			return ret, fmt.Errorf("No more free ip addresses are currently available in the pool")
		}

		for {
			// we assume that ip addresses adhere to high 64 bits for net and subnet ids, low 64 bits are for host id rule
			hostOffset := randomUint64(rng) % p.poolSize
			newIp := big.NewInt(0).Add(p.poolStartAddress, big.NewInt(0).SetUint64(hostOffset))
			_, exists := p.usedIps[newIp.Uint64()];
			if !exists {
				timeNow := p.timeNow()
				association := &IdentityAssociation{ClientId: clientId,
					InterfaceId: interfaceId,
					IpAddress: newIp.Bytes(),
					CreatedAt: timeNow}
				p.identityAssociations[clientIdHash] = association
				p.usedIps[newIp.Uint64()] = struct{}{}
				p.identityAssociationExpirations.Push(&AssociationExpiration{expiresAt: p.calculateAssociationExpiration(timeNow), ia: association})
				ret = append(ret, association)
				break
			}
		}
	}

	return ret, nil
}

func  (p *RandomAddressPool) ReleaseAddresses(clientId []byte, interfaceIds [][]byte) {
	p.lock.Lock()
	defer p.lock.Unlock()

	for _, interfaceId := range(interfaceIds) {
		association, exists := p.identityAssociations[p.calculateIaIdHash(clientId, interfaceId)]
		if !exists {
			continue
		}
		delete(p.usedIps, big.NewInt(0).SetBytes(association.IpAddress).Uint64())
		delete(p.identityAssociations, p.calculateIaIdHash(clientId, interfaceId))
	}
}

func (p *RandomAddressPool) ExpireIdentityAssociations() {
	p.lock.Lock()
	defer p.lock.Unlock()

	for {
		if p.identityAssociationExpirations.Size() < 1 { break }
		expiration := p.identityAssociationExpirations.Peek().(*AssociationExpiration)
		if p.timeNow().Before(expiration.expiresAt) { break }
		p.identityAssociationExpirations.Shift()
		delete(p.identityAssociations, p.calculateIaIdHash(expiration.ia.ClientId, expiration.ia.InterfaceId))
		delete(p.usedIps, big.NewInt(0).SetBytes(expiration.ia.IpAddress).Uint64())
	}
}

func (p *RandomAddressPool) calculateAssociationExpiration(now time.Time) time.Time {
	return now.Add(time.Duration(p.validLifetime)*time.Second)
}

func (p *RandomAddressPool) calculateIaIdHash(clientId, interfaceId []byte) uint64 {
	h := fnv.New64a()
	h.Write(clientId)
	h.Write(interfaceId)
	return h.Sum64()
}

func randomUint64(rng *rand.Rand) uint64 {
	return uint64(rng.Uint32())<<32 + uint64(rand.Uint32())
}
<|endoftext|>


<commit_before>package digests

import (
	"testing"

	"github.com/ion-channel/ionic/scanner"
	"github.com/ion-channel/ionic/scans"

	"github.com/franela/goblin"
	. "github.com/onsi/gomega"
)

func TestDependenciesDigests(t *testing.T) {
	g := goblin.Goblin(t)
	RegisterFailHandler(func(m string, _ ...int) { g.Fail(m) })

	g.Describe("Dependencies", func() {
		g.It("should produce digests", func() {
			s := &scanner.ScanStatus{}
			s.Status = scanner.ScanStatusFinished
			e := scans.NewEval()
			e.TranslatedResults = &scans.TranslatedResults{
				Type: "dependency",
				Data: scans.DependencyResults{
					Dependencies: nil,
					Meta: scans.DependencyMeta{
						FirstDegreeCount:     2,
						NoVersionCount:       1,
						TotalUniqueCount:     115,
						UpdateAvailableCount: 2,
					},
				},
			}

			ds, err := dependencyDigests(s, e)
			Expect(err).To(BeNil())
			Expect(len(ds)).To(Equal(4))
			Expect(ds[0].Title).To(Equal("dependencies outdated"))
			Expect(string(ds[0].Data)).To(Equal(`{"count":2}`))
			Expect(ds[0].Pending).To(BeFalse())
			Expect(ds[0].Errored).To(BeFalse())

			Expect(ds[1].Title).To(Equal("dependency no version specified"))
			Expect(string(ds[1].Data)).To(Equal(`{"count":1}`))
			Expect(ds[1].Warning).To(BeTrue())
			Expect(ds[1].Pending).To(BeFalse())
			Expect(ds[1].Errored).To(BeFalse())

			Expect(ds[2].Title).To(Equal("direct dependencies"))
			Expect(string(ds[2].Data)).To(Equal(`{"count":2}`))
			Expect(ds[2].Pending).To(BeFalse())
			Expect(ds[2].Errored).To(BeFalse())

			Expect(ds[3].Title).To(Equal("transitive dependencies"))
			Expect(string(ds[3].Data)).To(Equal(`{"count":113}`))
			Expect(ds[3].Pending).To(BeFalse())
			Expect(ds[3].Errored).To(BeFalse())
		})

		g.It("should have no warning with transitive dependencies", func() {
			s := &scanner.ScanStatus{}
			e := scans.NewEval()
			e.TranslatedResults = &scans.TranslatedResults{
				Type: "dependency",
				Data: scans.DependencyResults{
					Dependencies: nil,
					Meta: scans.DependencyMeta{
						FirstDegreeCount:     2,
						NoVersionCount:       1,
						TotalUniqueCount:     115,
						UpdateAvailableCount: 2,
					},
				},
			}

			ds, err := dependencyDigests(s, e)
			Expect(err).To(BeNil())
			Expect(ds[3].Warning).To(BeFalse())
			Expect(ds[3].WarningMessage).To(BeEmpty())
			Expect(string(ds[3].Data)).To(ContainSubstring("count\":113"))
			Expect(string(ds[3].Title)).To(Equal("transitive dependencies"))
		})

		g.It("should have a warning with transitive dependencies", func() {
			s := &scanner.ScanStatus{}
			e := scans.NewEval()
			e.TranslatedResults = &scans.TranslatedResults{
				Type: "dependency",
				Data: scans.DependencyResults{
					Dependencies: nil,
					Meta: scans.DependencyMeta{
						FirstDegreeCount:     2,
						NoVersionCount:       1,
						TotalUniqueCount:     2,
						UpdateAvailableCount: 2,
					},
				},
			}

			ds, err := dependencyDigests(s, e)
			Expect(err).To(BeNil())
			Expect(ds[3].Warning).To(BeTrue())
			Expect(ds[3].WarningMessage).To(Equal("no transitive dependencies found"))
			Expect(string(ds[3].Data)).To(ContainSubstring("count\":0"))
			Expect(string(ds[3].Title)).To(Equal("transitive dependencies"))
		})

		g.It("should have no warning with direct dependencies", func() {
			s := &scanner.ScanStatus{}
			e := scans.NewEval()
			e.TranslatedResults = &scans.TranslatedResults{
				Type: "dependency",
				Data: scans.DependencyResults{
					Dependencies: nil,
					Meta: scans.DependencyMeta{
						FirstDegreeCount:     13,
						NoVersionCount:       1,
						TotalUniqueCount:     115,
						UpdateAvailableCount: 2,
					},
				},
			}

			ds, err := dependencyDigests(s, e)
			Expect(err).To(BeNil())
			Expect(ds[2].Warning).To(BeFalse())
			Expect(ds[2].WarningMessage).To(BeEmpty())
			Expect(string(ds[2].Data)).To(ContainSubstring("count\":13"))
			Expect(string(ds[2].Title)).To(Equal("direct dependencies"))
		})

		g.It("should have a warning with direct dependencies", func() {
			s := &scanner.ScanStatus{}
			e := scans.NewEval()
			e.TranslatedResults = &scans.TranslatedResults{
				Type: "dependency",
				Data: scans.DependencyResults{
					Dependencies: nil,
					Meta: scans.DependencyMeta{
						FirstDegreeCount:     0,
						NoVersionCount:       1,
						TotalUniqueCount:     2,
						UpdateAvailableCount: 2,
					},
				},
			}

			ds, err := dependencyDigests(s, e)
			Expect(err).To(BeNil())
			Expect(ds[2].Warning).To(BeTrue())
			Expect(ds[2].WarningMessage).To(Equal("no direct dependencies found"))
			Expect(string(ds[2].Data)).To(ContainSubstring("count\":0"))
			Expect(string(ds[2].Title)).To(Equal("direct dependencies"))
		})
	})

}
<commit_msg>Adding the source data for no version deps<commit_after>package digests

import (
	"testing"

	"github.com/ion-channel/ionic/scanner"
	"github.com/ion-channel/ionic/scans"

	"github.com/franela/goblin"
	. "github.com/onsi/gomega"
)

func TestDependenciesDigests(t *testing.T) {
	g := goblin.Goblin(t)
	RegisterFailHandler(func(m string, _ ...int) { g.Fail(m) })

	g.Describe("Dependencies", func() {
		g.It("should produce digests", func() {
			s := &scanner.ScanStatus{}
			s.Status = scanner.ScanStatusFinished
			e := scans.NewEval()
			e.TranslatedResults = &scans.TranslatedResults{
				Type: "dependency",
				Data: scans.DependencyResults{
					Dependencies: nil,
					Meta: scans.DependencyMeta{
						FirstDegreeCount:     2,
						NoVersionCount:       1,
						TotalUniqueCount:     115,
						UpdateAvailableCount: 2,
					},
				},
			}

			ds, err := dependencyDigests(s, e)
			Expect(err).To(BeNil())
			Expect(len(ds)).To(Equal(4))
			Expect(ds[0].Title).To(Equal("dependencies outdated"))
			Expect(string(ds[0].Data)).To(Equal(`{"count":2}`))
			Expect(ds[0].Pending).To(BeFalse())
			Expect(ds[0].Errored).To(BeFalse())

			Expect(ds[1].Title).To(Equal("dependency no version specified"))
			Expect(string(ds[1].Data)).To(Equal(`{"count":1}`))
			Expect(ds[1].Warning).To(BeTrue())
			Expect(ds[1].Pending).To(BeFalse())
			Expect(ds[1].Errored).To(BeFalse())

			Expect(ds[2].Title).To(Equal("direct dependencies"))
			Expect(string(ds[2].Data)).To(Equal(`{"count":2}`))
			Expect(ds[2].Pending).To(BeFalse())
			Expect(ds[2].Errored).To(BeFalse())

			Expect(ds[3].Title).To(Equal("transitive dependencies"))
			Expect(string(ds[3].Data)).To(Equal(`{"count":113}`))
			Expect(ds[3].Pending).To(BeFalse())
			Expect(ds[3].Errored).To(BeFalse())
		})

		g.It("should produce no version digest with relevent data", func() {
			s := &scanner.ScanStatus{}
			s.Status = scanner.ScanStatusFinished
			e := scans.NewEval()
			e.TranslatedResults = &scans.TranslatedResults{
				Type: "dependency",
				Data: scans.DependencyResults{
					Dependencies: []scans.Dependency{
						scans.Dependency{
							Name:        "ExpectNoVersion",
							Requirement: "",
						},
						scans.Dependency{
							Name:        "ExpectVersion",
							Requirement: "1.1.1",
						},
					},
					Meta: scans.DependencyMeta{
						FirstDegreeCount:     2,
						NoVersionCount:       1,
						TotalUniqueCount:     115,
						UpdateAvailableCount: 2,
					},
				},
			}

			ds, err := dependencyDigests(s, e)
			Expect(err).To(BeNil())
			Expect(len(ds)).To(Equal(4))

			Expect(ds[1].Title).To(Equal("dependency no version specified"))
			Expect(string(ds[1].Data)).To(Equal(`{"count":1}`))
			Expect(string(ds[1].SourceData)).To(Equal(`{"type":"dependency","data":[{"latest_version":"","org":"","name":"ExpectNoVersion","type":"","package":"","version":"","scope":"","requirement":""}]}`))
			Expect(ds[1].Warning).To(BeTrue())
			Expect(ds[1].Pending).To(BeFalse())
			Expect(ds[1].Errored).To(BeFalse())
		})

		g.It("should have no warning with transitive dependencies", func() {
			s := &scanner.ScanStatus{}
			e := scans.NewEval()
			e.TranslatedResults = &scans.TranslatedResults{
				Type: "dependency",
				Data: scans.DependencyResults{
					Dependencies: nil,
					Meta: scans.DependencyMeta{
						FirstDegreeCount:     2,
						NoVersionCount:       1,
						TotalUniqueCount:     115,
						UpdateAvailableCount: 2,
					},
				},
			}

			ds, err := dependencyDigests(s, e)
			Expect(err).To(BeNil())
			Expect(ds[3].Warning).To(BeFalse())
			Expect(ds[3].WarningMessage).To(BeEmpty())
			Expect(string(ds[3].Data)).To(ContainSubstring("count\":113"))
			Expect(string(ds[3].Title)).To(Equal("transitive dependencies"))
		})

		g.It("should have a warning with transitive dependencies", func() {
			s := &scanner.ScanStatus{}
			e := scans.NewEval()
			e.TranslatedResults = &scans.TranslatedResults{
				Type: "dependency",
				Data: scans.DependencyResults{
					Dependencies: nil,
					Meta: scans.DependencyMeta{
						FirstDegreeCount:     2,
						NoVersionCount:       1,
						TotalUniqueCount:     2,
						UpdateAvailableCount: 2,
					},
				},
			}

			ds, err := dependencyDigests(s, e)
			Expect(err).To(BeNil())
			Expect(ds[3].Warning).To(BeTrue())
			Expect(ds[3].WarningMessage).To(Equal("no transitive dependencies found"))
			Expect(string(ds[3].Data)).To(ContainSubstring("count\":0"))
			Expect(string(ds[3].Title)).To(Equal("transitive dependencies"))
		})

		g.It("should have no warning with direct dependencies", func() {
			s := &scanner.ScanStatus{}
			e := scans.NewEval()
			e.TranslatedResults = &scans.TranslatedResults{
				Type: "dependency",
				Data: scans.DependencyResults{
					Dependencies: nil,
					Meta: scans.DependencyMeta{
						FirstDegreeCount:     13,
						NoVersionCount:       1,
						TotalUniqueCount:     115,
						UpdateAvailableCount: 2,
					},
				},
			}

			ds, err := dependencyDigests(s, e)
			Expect(err).To(BeNil())
			Expect(ds[2].Warning).To(BeFalse())
			Expect(ds[2].WarningMessage).To(BeEmpty())
			Expect(string(ds[2].Data)).To(ContainSubstring("count\":13"))
			Expect(string(ds[2].Title)).To(Equal("direct dependencies"))
		})

		g.It("should have a warning with direct dependencies", func() {
			s := &scanner.ScanStatus{}
			e := scans.NewEval()
			e.TranslatedResults = &scans.TranslatedResults{
				Type: "dependency",
				Data: scans.DependencyResults{
					Dependencies: nil,
					Meta: scans.DependencyMeta{
						FirstDegreeCount:     0,
						NoVersionCount:       1,
						TotalUniqueCount:     2,
						UpdateAvailableCount: 2,
					},
				},
			}

			ds, err := dependencyDigests(s, e)
			Expect(err).To(BeNil())
			Expect(ds[2].Warning).To(BeTrue())
			Expect(ds[2].WarningMessage).To(Equal("no direct dependencies found"))
			Expect(string(ds[2].Data)).To(ContainSubstring("count\":0"))
			Expect(string(ds[2].Title)).To(Equal("direct dependencies"))
		})
	})

}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Tigera, Inc. All rights reserved.

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

package unversioned

// All resources (and resource lists) implement the Resource interface.
type Resource interface {
	GetTypeMetadata() TypeMetadata
}

// Define available versions.
var (
	Version_1_0 = "1.0"
	VersionCurrent = Version_1_0
)

// ---- Type metadata ----
//
// All resource and resource lists embed a TypeMetadata as an anonymous field.
type TypeMetadata struct {
	Kind       string  `json:"kind" validate:"required"`
	APIVersion string  `json:"apiVersion" validate:"required"`
}

func (md TypeMetadata) GetTypeMetadata() TypeMetadata {
	return md
}

// All resource Metadata (not lists) implement the ResourceMetadata interface.
type ResourceMetadata interface {
	GetObjectMetadata() ObjectMetadata
}

// ---- Metadata common to all resources ----
type ObjectMetadata struct {
}

func (md ObjectMetadata) GetObjectMetadata() ObjectMetadata {
	return md
}

// ---- Metadata common to all lists ----
type ListMetadata struct {
}
<commit_msg>change required version back to v1<commit_after>// Copyright (c) 2016 Tigera, Inc. All rights reserved.

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

package unversioned

// All resources (and resource lists) implement the Resource interface.
type Resource interface {
	GetTypeMetadata() TypeMetadata
}

// Define available versions.
var (

	// `apiVersion` in the config yaml files
	VersionV1      = "v1"
	VersionCurrent = VersionV1
)

// ---- Type metadata ----
//
// All resource and resource lists embed a TypeMetadata as an anonymous field.
type TypeMetadata struct {
	Kind       string `json:"kind" validate:"required"`
	APIVersion string `json:"apiVersion" validate:"required"`
}

func (md TypeMetadata) GetTypeMetadata() TypeMetadata {
	return md
}

// All resource Metadata (not lists) implement the ResourceMetadata interface.
type ResourceMetadata interface {
	GetObjectMetadata() ObjectMetadata
}

// ---- Metadata common to all resources ----
type ObjectMetadata struct {
}

func (md ObjectMetadata) GetObjectMetadata() ObjectMetadata {
	return md
}

// ---- Metadata common to all lists ----
type ListMetadata struct {
}
<|endoftext|>


<commit_before>package ast

import (
  "encoding/json"
)

// CastNode
type CastNode struct {
  Location Location
  Type ITypeNode
  Expr IExprNode
}

func NewCastNode(location Location, t ITypeNode, expr IExprNode) CastNode {
  return CastNode { location, t, expr }
}

func (self CastNode) String() string {
  panic("not implemented")
}

func (self CastNode) MarshalJSON() ([]byte, error) {
  var x struct {
    ClassName string
    Location Location
    Type ITypeNode
    Expr IExprNode
  }
  x.ClassName = "ast.CastNode"
  x.Location = self.Location
  x.Type = self.Type
  x.Expr = self.Expr
  return json.Marshal(x)
}

func (self CastNode) IsExpr() bool {
  return true
}

func (self CastNode) GetLocation() Location {
  return self.Location
}

// SizeofExprNode
type SizeofExprNode struct {
  Location Location
  Expr IExprNode
  Type ITypeNode
}

func NewSizeofExprNode(location Location, expr IExprNode, t ITypeNode) SizeofExprNode {
  return SizeofExprNode { location, expr, t }
}

func (self SizeofExprNode) String() string {
  panic("not implemented")
}

func (self SizeofExprNode) MarshalJSON() ([]byte, error) {
  var x struct {
    ClassName string
    Location Location
    Expr IExprNode
    Type ITypeNode
  }
  x.ClassName = "ast.SizeofExprNode"
  x.Location = self.Location
  x.Expr = self.Expr
  x.Type = self.Type
  return json.Marshal(x)
}

func (self SizeofExprNode) IsExpr() bool {
  return true
}

func (self SizeofExprNode) GetLocation() Location {
  return self.Location
}

// SizeofTypeNode
type SizeofTypeNode struct {
  Location Location
  Type ITypeNode
  Operand ITypeNode
}

func NewSizeofTypeNode(location Location, t ITypeNode, operand ITypeNode) SizeofTypeNode {
  return SizeofTypeNode { location, t, operand }
}

func (self SizeofTypeNode) String() string {
  panic("not implemented")
}

func (self SizeofTypeNode) MarshalJSON() ([]byte, error) {
  var x struct {
    ClassName string
    Location Location
    Type ITypeNode
    Operand ITypeNode
  }
  x.ClassName = "ast.SizeofTypeNode"
  x.Location = self.Location
  x.Type = self.Type
  x.Operand = self.Operand
  return json.Marshal(x)
}

func (self SizeofTypeNode) IsExpr() bool {
  return true
}

func (self SizeofTypeNode) GetLocation() Location {
  return self.Location
}
<commit_msg>Add more type nodes<commit_after>package ast

import (
  "encoding/json"
  "fmt"
  "bitbucket.org/yyuu/bs/typesys"
)

// CastNode
type CastNode struct {
  Location Location
  Type ITypeNode
  Expr IExprNode
}

func NewCastNode(location Location, t ITypeNode, expr IExprNode) CastNode {
  return CastNode { location, t, expr }
}

func (self CastNode) String() string {
  return fmt.Sprintf("(%s %s)", self.Type, self.Expr)
}

func (self CastNode) MarshalJSON() ([]byte, error) {
  var x struct {
    ClassName string
    Location Location
    Type ITypeNode
    Expr IExprNode
  }
  x.ClassName = "ast.CastNode"
  x.Location = self.Location
  x.Type = self.Type
  x.Expr = self.Expr
  return json.Marshal(x)
}

func (self CastNode) IsExpr() bool {
  return true
}

func (self CastNode) GetLocation() Location {
  return self.Location
}

// SizeofExprNode
type SizeofExprNode struct {
  Location Location
  Expr IExprNode
  Type ITypeNode
}

func NewSizeofExprNode(location Location, expr IExprNode, t typesys.ITypeRef) SizeofExprNode {
  return SizeofExprNode { location, expr, NewTypeNode(location, t) }
}

func (self SizeofExprNode) String() string {
  return fmt.Sprintf("(sizeof %s)", self.Expr)
}

func (self SizeofExprNode) MarshalJSON() ([]byte, error) {
  var x struct {
    ClassName string
    Location Location
    Expr IExprNode
    Type ITypeNode
  }
  x.ClassName = "ast.SizeofExprNode"
  x.Location = self.Location
  x.Expr = self.Expr
  x.Type = self.Type
  return json.Marshal(x)
}

func (self SizeofExprNode) IsExpr() bool {
  return true
}

func (self SizeofExprNode) GetLocation() Location {
  return self.Location
}

// SizeofTypeNode
type SizeofTypeNode struct {
  Location Location
  Type ITypeNode
  Operand ITypeNode
}

func NewSizeofTypeNode(location Location, operand ITypeNode, t typesys.ITypeRef) SizeofTypeNode {
  return SizeofTypeNode { location, operand, NewTypeNode(location, t) }
}

func (self SizeofTypeNode) String() string {
  return fmt.Sprintf("(sizeof %s)", self.Type)
}

func (self SizeofTypeNode) MarshalJSON() ([]byte, error) {
  var x struct {
    ClassName string
    Location Location
    Type ITypeNode
    Operand ITypeNode
  }
  x.ClassName = "ast.SizeofTypeNode"
  x.Location = self.Location
  x.Type = self.Type
  x.Operand = self.Operand
  return json.Marshal(x)
}

func (self SizeofTypeNode) IsExpr() bool {
  return true
}

func (self SizeofTypeNode) GetLocation() Location {
  return self.Location
}

// TypeNode
type TypeNode struct {
  Location Location
  TypeRef typesys.ITypeRef
}

func NewTypeNode(location Location, t typesys.ITypeRef) TypeNode {
  return TypeNode { location, t }
}

func (self TypeNode) String() string {
  return fmt.Sprintf("(type %s)", self.TypeRef)
}

func (self TypeNode) MarshalJSON() ([]byte, error) {
  var x struct {
    ClassName string
    Location Location
    TypeRef typesys.ITypeRef
  }
  x.ClassName = "ast.TypeNode"
  x.Location = self.Location
  x.TypeRef = self.TypeRef
  return json.Marshal(x)
}

func (self TypeNode) IsType() bool {
  return true
}

func (self TypeNode) GetLocation() Location {
  return self.Location
}

// TypedefNode
type TypedefNode struct {
  Location Location
  TypeNode ITypeNode
  Name string
}

func NewTypedefNode(location Location, t ITypeNode, name string) TypedefNode {
  return TypedefNode { location, t, name }
}

func (self TypedefNode) String() string {
  return fmt.Sprintf("(typedef %s %s)", self.Name, self.TypeNode)
}

func (self TypedefNode) MarshalJSON() ([]byte, error) {
  var x struct {
    ClassName string
    Location Location
    TypeNode ITypeNode
    Name string
  }
  x.ClassName = "ast.TypedefNode"
  x.Location = self.Location
  x.TypeNode = self.TypeNode
  x.Name = self.Name
  return json.Marshal(x)
}

func (self TypedefNode) IsType() bool {
  return true
}

func (self TypedefNode) GetLocation() Location {
  return self.Location
}
<|endoftext|>


<commit_before>// Copyright (c) 2016, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

package sh

import (
	"reflect"
	"strings"
	"testing"
)

func TestParseAST(t *testing.T) {
	tests := []struct {
		in   string
		want prog
	}{
		{
			in:   "",
			want: prog{},
		},
		{
			in:   "# comment",
			want: prog{},
		},
		{
			in: "foo",
			want: prog{stmts: []node{
				command{args: []lit{"foo"}},
			}},
		},
		{
			in: "# comment\nfoo",
			want: prog{stmts: []node{
				command{args: []lit{"foo"}},
			}},
		},
		{
			in: "foo arg1 arg2",
			want: prog{stmts: []node{
				command{args: []lit{"foo", "arg1", "arg2"}},
			}},
		},
		{
			in: "( foo; )",
			want: prog{stmts: []node{
				subshell{stmts: []node{
					command{args: []lit{"foo"}},
				}},
			}},
		},
		{
			in: "{ foo; }",
			want: prog{stmts: []node{
				block{stmts: []node{
					command{args: []lit{"foo"}},
				}},
			}},
		},
		{
			in: "if foo; then bar; fi",
			want: prog{stmts: []node{ ifStmt{
				cond: command{args: []lit{"foo"}},
				thenStmts: []node{
					command{args: []lit{"bar"}},
				}},
			}},
		},
		{
			in: "if foo; then bar; else pass; fi",
			want: prog{stmts: []node{ifStmt{
				cond: command{args: []lit{"foo"}},
				thenStmts: []node{
					command{args: []lit{"bar"}},
				},
				elseStmts: []node{
					command{args: []lit{"pass"}},
				}},
			}},
		},
		{
			in: "if a; then a; elif b; then b; elif c; then c; else d; fi",
			want: prog{stmts: []node{ifStmt{
				cond: command{args: []lit{"a"}},
				thenStmts: []node{
					command{args: []lit{"a"}},
				},
				elifs: []node{
					elif{cond: command{args: []lit{"b"}},
						thenStmts: []node{
							command{args: []lit{"b"}},
						}},
					elif{cond: command{args: []lit{"c"}},
						thenStmts: []node{
							command{args: []lit{"c"}},
						}},
				},
				elseStmts: []node{
					command{args: []lit{"d"}},
				}},
			}},
		},
		{
			in: "while foo; do bar; done",
			want: prog{stmts: []node{ whileStmt{
				cond: command{args: []lit{"foo"}},
				doStmts: []node{
					command{args: []lit{"bar"}},
				}},
			}},
		},
		{
			in: "echo ' ' \"foo bar\"",
			want: prog{stmts: []node{
				command{args: []lit{"echo", "' '", "\"foo bar\""}},
			}},
		},
		{
			in: "$a ${b} s{s s=s",
			want: prog{stmts: []node{
				command{args: []lit{"$a", "${b}", "s{s", "s=s"}},
			}},
		},
	}
	for _, c := range tests {
		r := strings.NewReader(c.in)
		got, err := parse(r, "")
		if err != nil {
			t.Fatalf("Unexpected error in %q: %v", c.in, err)
		}
		if !reflect.DeepEqual(got, c.want) {
			t.Fatalf("AST mismatch in %q\nwant: %s\ngot:  %s\ndumps:\n%#v\n%#v",
				c.in, c.want.String(), got.String(), c.want, got)
		}
	}
}
<commit_msg>Remove redundant prog{} from all AST tests<commit_after>// Copyright (c) 2016, Daniel Martí <mvdan@mvdan.cc>
// See LICENSE for licensing information

package sh

import (
	"reflect"
	"strings"
	"testing"
)

var tests = []struct {
	in   string
	want []node
}{
	{
		in:   "",
		want: nil,
	},
	{
		in:   "# comment",
		want: nil,
	},
	{
		in: "foo",
		want: []node{
			command{args: []lit{"foo"}},
		},
	},
	{
		in: "# comment\nfoo",
		want: []node{
			command{args: []lit{"foo"}},
		},
	},
	{
		in: "foo arg1 arg2",
		want: []node{
			command{args: []lit{"foo", "arg1", "arg2"}},
		},
	},
	{
		in: "( foo; )",
		want: []node{
			subshell{stmts: []node{
				command{args: []lit{"foo"}},
			}},
		},
	},
	{
		in: "{ foo; }",
		want: []node{
			block{stmts: []node{
				command{args: []lit{"foo"}},
			}},
		},
	},
	{
		in: "if foo; then bar; fi",
		want: []node{ifStmt{
			cond: command{args: []lit{"foo"}},
			thenStmts: []node{
				command{args: []lit{"bar"}},
			}},
		},
	},
	{
		in: "if foo; then bar; else pass; fi",
		want: []node{ifStmt{
			cond: command{args: []lit{"foo"}},
			thenStmts: []node{
				command{args: []lit{"bar"}},
			},
			elseStmts: []node{
				command{args: []lit{"pass"}},
			}},
		},
	},
	{
		in: "if a; then a; elif b; then b; elif c; then c; else d; fi",
		want: []node{ifStmt{
			cond: command{args: []lit{"a"}},
			thenStmts: []node{
				command{args: []lit{"a"}},
			},
			elifs: []node{
				elif{cond: command{args: []lit{"b"}},
					thenStmts: []node{
						command{args: []lit{"b"}},
					}},
				elif{cond: command{args: []lit{"c"}},
					thenStmts: []node{
						command{args: []lit{"c"}},
					}},
			},
			elseStmts: []node{
				command{args: []lit{"d"}},
			}},
		},
	},
	{
		in: "while foo; do bar; done",
		want: []node{whileStmt{
			cond: command{args: []lit{"foo"}},
			doStmts: []node{
				command{args: []lit{"bar"}},
			}},
		},
	},
	{
		in: "echo ' ' \"foo bar\"",
		want: []node{
			command{args: []lit{"echo", "' '", "\"foo bar\""}},
		},
	},
	{
		in: "$a ${b} s{s s=s",
		want: []node{
			command{args: []lit{"$a", "${b}", "s{s", "s=s"}},
		},
	},
}

func TestParseAST(t *testing.T) {
	for _, c := range tests {
		r := strings.NewReader(c.in)
		got, err := parse(r, "")
		if err != nil {
			t.Fatalf("Unexpected error in %q: %v", c.in, err)
		}
		want := prog{
			stmts: c.want,
		}
		if !reflect.DeepEqual(got, want) {
			t.Fatalf("AST mismatch in %q\nwant: %s\ngot:  %s\ndumps:\n%#v\n%#v",
				c.in, want.String(), got.String(), want, got)
		}
	}
}
<|endoftext|>


<commit_before>package id3go

import (
	"io"
	"bufio"
)

type ID3v2Header struct {
	Version           [2]int
	Size              int32
	Unsynchronization bool
	Extended          bool
	Experimental      bool
	Footer            bool
}

type ID3 struct {
	fileName string

	Header ID3v2Header

	Name   string
	Artist string
	Album  string
	Year   string
	Track  string
	Disc   string
	Genre  string
	Length string
}

func parseV2Header(reader *bufio.Reader, tag *ID3) {

}

func isTag(reader *bufio.Reader) bool {

}

func ParseTag(reader io.Reader) {

}
<commit_msg>Delete id3tag.go<commit_after><|endoftext|>


<commit_before>package http

import (
	"fmt"
	"io"
	"log"
	gohttp "net/http"
	"os"
	"path/filepath"
	"time"

	"github.com/wanelo/image-server/core"
)

var ImageDownloads map[string][]chan error

func FetchOriginal(ic *core.ImageConfiguration) error {
	c := make(chan error)
	go uniqueFetchOriginal(c, ic)
	return <-c
}

// Even if simultaneous calls request the same image, only the first one will download
// the image, and will then notify all requesters. The channel returns an error object
func uniqueFetchOriginal(c chan error, ic *core.ImageConfiguration) {
	key := ic.ServerConfiguration.Adapters.SourceMapper.RemoteImageURL(ic)

	_, present := ImageDownloads[key]

	if present {
		ImageDownloads[key] = append(ImageDownloads[key], c)
	} else {
		ImageDownloads[key] = []chan error{c}

		err := downloadAndSaveOriginal(ic)
		for _, cc := range ImageDownloads[key] {
			cc <- err
		}
		delete(ImageDownloads, key)
	}
}

func downloadAndSaveOriginal(ic *core.ImageConfiguration) error {
	path := ic.LocalOriginalImagePath()
	if _, err := os.Stat(path); os.IsNotExist(err) {
		start := time.Now()

		remoteURL := ic.ServerConfiguration.Adapters.SourceMapper.RemoteImageURL(ic)
		resp, err := gohttp.Get(remoteURL)

		log.Printf("Downloaded from %s with code %d", remoteURL, resp.StatusCode)
		if err != nil || resp.StatusCode != 200 {
			log.Printf("Unable to download image: %s, status code: %d", remoteURL, resp.StatusCode)
			log.Println(err)
			go func() {
				ic.ServerConfiguration.Events.OriginalDownloadUnavailable <- ic
			}()
			return fmt.Errorf("unable to download image: %s, status code: %d", remoteURL, resp.StatusCode)
		}
		defer resp.Body.Close()

		dir := filepath.Dir(path)
		os.MkdirAll(dir, 0700)

		out, err := os.Create(path)
		defer out.Close()
		if err != nil {
			log.Printf("Unable to create file: %s", path)
			log.Println(err)
			return fmt.Errorf("unable to create file: %s", path)
		}

		io.Copy(out, resp.Body)
		log.Printf("Took %s to download image: %s", time.Since(start), path)

		go func() {
			ic.ServerConfiguration.Events.OriginalDownloaded <- ic
		}()
	}
	return nil
}
<commit_msg>Only log successful log if no errors<commit_after>package http

import (
	"fmt"
	"io"
	"log"
	gohttp "net/http"
	"os"
	"path/filepath"
	"time"

	"github.com/wanelo/image-server/core"
)

var ImageDownloads map[string][]chan error

func FetchOriginal(ic *core.ImageConfiguration) error {
	c := make(chan error)
	go uniqueFetchOriginal(c, ic)
	return <-c
}

// Even if simultaneous calls request the same image, only the first one will download
// the image, and will then notify all requesters. The channel returns an error object
func uniqueFetchOriginal(c chan error, ic *core.ImageConfiguration) {
	key := ic.ServerConfiguration.Adapters.SourceMapper.RemoteImageURL(ic)

	_, present := ImageDownloads[key]

	if present {
		ImageDownloads[key] = append(ImageDownloads[key], c)
	} else {
		ImageDownloads[key] = []chan error{c}

		err := downloadAndSaveOriginal(ic)
		for _, cc := range ImageDownloads[key] {
			cc <- err
		}
		delete(ImageDownloads, key)
	}
}

func downloadAndSaveOriginal(ic *core.ImageConfiguration) error {
	path := ic.LocalOriginalImagePath()
	if _, err := os.Stat(path); os.IsNotExist(err) {
		start := time.Now()

		remoteURL := ic.ServerConfiguration.Adapters.SourceMapper.RemoteImageURL(ic)
		resp, err := gohttp.Get(remoteURL)

		if err != nil || resp.StatusCode != 200 {
			log.Printf("Unable to download image: %s, status code: %d", remoteURL, resp.StatusCode)
			log.Println(err)
			go func() {
				ic.ServerConfiguration.Events.OriginalDownloadUnavailable <- ic
			}()
			return fmt.Errorf("unable to download image: %s, status code: %d", remoteURL, resp.StatusCode)
		}
		log.Printf("Downloaded from %s with code %d", remoteURL, resp.StatusCode)
		defer resp.Body.Close()

		dir := filepath.Dir(path)
		os.MkdirAll(dir, 0700)

		out, err := os.Create(path)
		defer out.Close()
		if err != nil {
			log.Printf("Unable to create file: %s", path)
			log.Println(err)
			return fmt.Errorf("unable to create file: %s", path)
		}

		io.Copy(out, resp.Body)
		log.Printf("Took %s to download image: %s", time.Since(start), path)

		go func() {
			ic.ServerConfiguration.Events.OriginalDownloaded <- ic
		}()
	}
	return nil
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Skaffold 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 integration

import (
	"context"
	"os"
	"os/exec"
	"testing"
	"time"

	"4d63.com/tz"
	"github.com/GoogleContainerTools/skaffold/integration/skaffold"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
	"github.com/docker/docker/api/types"
)

const imageName = "simple-build:"

func TestBuild(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping integration test")
	}
	if ShouldRunGCPOnlyTests() {
		t.Skip("skipping test that is not gcp only")
	}

	tests := []struct {
		description string
		dir         string
		args        []string
		expectImage string
		setup       func(t *testing.T, workdir string) (teardown func())
	}{
		{
			description: "docker build",
			dir:         "testdata/build",
		},
		{
			description: "testing skaffold itself in alpine",
			dir:         "testdata/alpine",
		},
		{
			description: "git tagger",
			dir:         "testdata/tagPolicy",
			args:        []string{"-p", "gitCommit"},
			setup:       setupGitRepo,
			expectImage: imageName + "v1",
		},
		{
			description: "sha256 tagger",
			dir:         "testdata/tagPolicy",
			args:        []string{"-p", "sha256"},
			expectImage: imageName + "latest",
		},
		{
			description: "dateTime tagger",
			dir:         "testdata/tagPolicy",
			args:        []string{"-p", "dateTime"},
			// around midnight this test might fail, if the tests above run slowly
			expectImage: imageName + nowInChicago(),
		},
		{
			description: "envTemplate tagger",
			dir:         "testdata/tagPolicy",
			args:        []string{"-p", "envTemplate"},
			expectImage: imageName + "tag",
		},
	}
	for _, test := range tests {
		t.Run(test.description, func(t *testing.T) {
			if test.setup != nil {
				teardown := test.setup(t, test.dir)
				defer teardown()
			}

			// remove image in case it is already present
			removeImage(t, test.expectImage)
			skaffold.Build(test.args...).InDir(test.dir).RunOrFail(t)
			checkImageExists(t, test.expectImage)
		})
	}
}

// removeImage removes the given image if present.
func removeImage(t *testing.T, image string) {
	t.Helper()

	if image == "" {
		return
	}

	client, err := docker.NewAPIClient(false, nil)
	failNowIfError(t, err)

	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))
	defer cancel()
	_, _ = client.ImageRemove(ctx, image, types.ImageRemoveOptions{
		Force:         true,
		PruneChildren: true,
	})
}

// checkImageExists asserts that the given image is present
func checkImageExists(t *testing.T, image string) {
	t.Helper()

	if image == "" {
		return
	}

	client, err := docker.NewAPIClient(false, nil)
	failNowIfError(t, err)

	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))
	defer cancel()
	if !client.ImageExists(ctx, image) {
		t.Errorf("expected image '%s' not present", image)
	}
}

// setupGitRepo sets up a clean repo with tag v1
func setupGitRepo(t *testing.T, dir string) func() {
	gitArgs := [][]string{
		{"init"},
		{"config", "user.email", "john@doe.org"},
		{"config", "user.name", "John Doe"},
		{"add", "."},
		{"commit", "-m", "Initial commit"},
		{"tag", "v1"},
	}

	for _, args := range gitArgs {
		cmd := exec.Command("git", args...)
		cmd.Dir = dir
		if buf, err := util.RunCmdOut(cmd); err != nil {
			t.Logf(string(buf))
			t.Fatal(err)
		}
	}

	return func() {
		os.RemoveAll(dir + "/.git")
	}
}

// nowInChicago returns the dateTime string as generated by the dateTime tagger
func nowInChicago() string {
	loc, _ := tz.LoadLocation("America/Chicago")
	return time.Now().In(loc).Format("2006-01-02")
}

func failNowIfError(t *testing.T, err error) {
	if err != nil {
		t.Fatal(err)
	}
}
<commit_msg>revert accidental experiment<commit_after>/*
Copyright 2019 The Skaffold 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 integration

import (
	"context"
	"os"
	"os/exec"
	"testing"
	"time"

	"4d63.com/tz"
	"github.com/GoogleContainerTools/skaffold/integration/skaffold"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
	"github.com/docker/docker/api/types"
)

const imageName = "simple-build:"

func TestBuild(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping integration test")
	}
	if ShouldRunGCPOnlyTests() {
		t.Skip("skipping test that is not gcp only")
	}

	tests := []struct {
		description string
		dir         string
		args        []string
		expectImage string
		setup       func(t *testing.T, workdir string) (teardown func())
	}{
		{
			description: "docker build",
			dir:         "testdata/build",
		},
		{
			description: "git tagger",
			dir:         "testdata/tagPolicy",
			args:        []string{"-p", "gitCommit"},
			setup:       setupGitRepo,
			expectImage: imageName + "v1",
		},
		{
			description: "sha256 tagger",
			dir:         "testdata/tagPolicy",
			args:        []string{"-p", "sha256"},
			expectImage: imageName + "latest",
		},
		{
			description: "dateTime tagger",
			dir:         "testdata/tagPolicy",
			args:        []string{"-p", "dateTime"},
			// around midnight this test might fail, if the tests above run slowly
			expectImage: imageName + nowInChicago(),
		},
		{
			description: "envTemplate tagger",
			dir:         "testdata/tagPolicy",
			args:        []string{"-p", "envTemplate"},
			expectImage: imageName + "tag",
		},
	}
	for _, test := range tests {
		t.Run(test.description, func(t *testing.T) {
			if test.setup != nil {
				teardown := test.setup(t, test.dir)
				defer teardown()
			}

			// remove image in case it is already present
			removeImage(t, test.expectImage)
			skaffold.Build(test.args...).InDir(test.dir).RunOrFail(t)
			checkImageExists(t, test.expectImage)
		})
	}
}

// removeImage removes the given image if present.
func removeImage(t *testing.T, image string) {
	t.Helper()

	if image == "" {
		return
	}

	client, err := docker.NewAPIClient(false, nil)
	failNowIfError(t, err)

	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))
	defer cancel()
	_, _ = client.ImageRemove(ctx, image, types.ImageRemoveOptions{
		Force:         true,
		PruneChildren: true,
	})
}

// checkImageExists asserts that the given image is present
func checkImageExists(t *testing.T, image string) {
	t.Helper()

	if image == "" {
		return
	}

	client, err := docker.NewAPIClient(false, nil)
	failNowIfError(t, err)

	ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(5*time.Second))
	defer cancel()
	if !client.ImageExists(ctx, image) {
		t.Errorf("expected image '%s' not present", image)
	}
}

// setupGitRepo sets up a clean repo with tag v1
func setupGitRepo(t *testing.T, dir string) func() {
	gitArgs := [][]string{
		{"init"},
		{"config", "user.email", "john@doe.org"},
		{"config", "user.name", "John Doe"},
		{"add", "."},
		{"commit", "-m", "Initial commit"},
		{"tag", "v1"},
	}

	for _, args := range gitArgs {
		cmd := exec.Command("git", args...)
		cmd.Dir = dir
		if buf, err := util.RunCmdOut(cmd); err != nil {
			t.Logf(string(buf))
			t.Fatal(err)
		}
	}

	return func() {
		os.RemoveAll(dir + "/.git")
	}
}

// nowInChicago returns the dateTime string as generated by the dateTime tagger
func nowInChicago() string {
	loc, _ := tz.LoadLocation("America/Chicago")
	return time.Now().In(loc).Format("2006-01-02")
}

func failNowIfError(t *testing.T, err error) {
	if err != nil {
		t.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package federation

import(
  "bytes"
  "encoding/json"
  "log"
  "net/http"
  "strings"
)

type RequestHandler struct {
  app *App
}

func (rh *RequestHandler) Main(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "application/json")

  requestType := r.URL.Query().Get("type")
  q := r.URL.Query().Get("q")
  switch  {
    case requestType == "name" && q != "":
      rh.MakeDatabaseRequest(rh.app.config.FederationQuery, w, r);
    case requestType == "id" && q != "":
      rh.MakeDatabaseRequest( rh.app.config.ReverseFederationQuery, w, r);
    default:
      http.Error(w, ErrorResponseString("invalid_request", "Invalid request"), http.StatusBadRequest)
  }
}

func (rh *RequestHandler) MakeDatabaseRequest(query string, w http.ResponseWriter, r *http.Request) {
  record := Record{}

  q := r.URL.Query().Get("q")

  if r.URL.Query().Get("type") == "name" {
    name := ""
    domain := ""

    if i := strings.Index(q, "*"); i >= 0 {
      name = q[:i]
      domain = q[i+1:]
    }

    if name == "" || domain != rh.app.config.Domain {
      http.Error(w, ErrorResponseString("not_found", "Account not found"), http.StatusNotFound)
      return
    }

    q = name
  }

  err := rh.app.database.Get(&record, query, q)

  if err != nil {
    if err.Error() == "sql: no rows in result set" {
      log.Print("Federation record NOT found")
      http.Error(w, ErrorResponseString("not_found", "Account not found"), http.StatusNotFound)
    } else {
      log.Print("Server error: ", err)
      http.Error(w, ErrorResponseString("server_error", "Server error"), http.StatusInternalServerError)
    }
    return
  }

  log.Print("Federation record found")

  var usernameBuffer bytes.Buffer
  usernameBuffer.WriteString(record.Username)
  usernameBuffer.WriteString("*")
  usernameBuffer.WriteString(rh.app.config.Domain)

  record.Username = usernameBuffer.String()
  json, err := json.Marshal(record)

  if err != nil {
    http.Error(w, ErrorResponseString("server_error", "Server error"), http.StatusInternalServerError)
    return
  }

  w.Write(json)
}

func ErrorResponseString(code string, message string) string {
  error := Error{Code: code, Message: message}
  json, _ := json.Marshal(error)
  return string(json)
}
<commit_msg>Formatting<commit_after>package federation

import(
  "bytes"
  "encoding/json"
  "log"
  "net/http"
  "strings"
)

type RequestHandler struct {
  app *App
}

func (rh *RequestHandler) Main(w http.ResponseWriter, r *http.Request) {
  w.Header().Set("Content-Type", "application/json")

  requestType := r.URL.Query().Get("type")
  q := r.URL.Query().Get("q")
  switch  {
    case requestType == "name" && q != "":
      rh.MakeDatabaseRequest(rh.app.config.FederationQuery, w, r);
    case requestType == "id" && q != "":
      rh.MakeDatabaseRequest(rh.app.config.ReverseFederationQuery, w, r);
    default:
      http.Error(w, ErrorResponseString("invalid_request", "Invalid request"), http.StatusBadRequest)
  }
}

func (rh *RequestHandler) MakeDatabaseRequest(query string, w http.ResponseWriter, r *http.Request) {
  record := Record{}

  q := r.URL.Query().Get("q")

  if r.URL.Query().Get("type") == "name" {
    name := ""
    domain := ""

    if i := strings.Index(q, "*"); i >= 0 {
      name = q[:i]
      domain = q[i+1:]
    }

    if name == "" || domain != rh.app.config.Domain {
      http.Error(w, ErrorResponseString("not_found", "Account not found"), http.StatusNotFound)
      return
    }

    q = name
  }

  err := rh.app.database.Get(&record, query, q)

  if err != nil {
    if err.Error() == "sql: no rows in result set" {
      log.Print("Federation record NOT found")
      http.Error(w, ErrorResponseString("not_found", "Account not found"), http.StatusNotFound)
    } else {
      log.Print("Server error: ", err)
      http.Error(w, ErrorResponseString("server_error", "Server error"), http.StatusInternalServerError)
    }
    return
  }

  log.Print("Federation record found")

  var usernameBuffer bytes.Buffer
  usernameBuffer.WriteString(record.Username)
  usernameBuffer.WriteString("*")
  usernameBuffer.WriteString(rh.app.config.Domain)

  record.Username = usernameBuffer.String()
  json, err := json.Marshal(record)

  if err != nil {
    http.Error(w, ErrorResponseString("server_error", "Server error"), http.StatusInternalServerError)
    return
  }

  w.Write(json)
}

func ErrorResponseString(code string, message string) string {
  error := Error{Code: code, Message: message}
  json, _ := json.Marshal(error)
  return string(json)
}
<|endoftext|>


<commit_before>package main

type TaskCommand struct{}

var taskCommand TaskCommand

func init() {
	parser.AddCommand("task", "Work with tasks", "Allows you to work with stories and tasks.", &taskCommand)
}

func (tc *TaskCommand) Execute(args []string) error {
	jc := NewJiraClient(options)
	iss, err := jc.GetIssue(args[0])
	if err != nil {
		return err
	}
	switch args[1] {
	case "grab":
		err = iss.Assign(options.User, jc)
		if err != nil {
			return err
		}
	case "start":
		err = iss.StartProgress(jc)
		if err != nil {
			return err
		}
	case "stop":
		err = iss.StopProgress(jc)
		if err != nil {
			return err
		}
	}

	return nil
}
<commit_msg>Added some basic '-h' nicety.<commit_after>package main

type TaskCommand struct{}

var taskCommand TaskCommand

func init() {
	parser.AddCommand("task", "Work with tasks",
		`gojira task TASK-1234 start|stop|grab

Allows you to work with stories and tasks.
`, &taskCommand)
}

func (tc *TaskCommand) Execute(args []string) error {
	jc := NewJiraClient(options)
	iss, err := jc.GetIssue(args[0])
	if err != nil {
		return err
	}
	switch args[1] {
	case "grab":
		err = iss.Assign(options.User, jc)
		if err != nil {
			return err
		}
	case "start":
		err = iss.StartProgress(jc)
		if err != nil {
			return err
		}
	case "stop":
		err = iss.StopProgress(jc)
		if err != nil {
			return err
		}
	}

	return nil
}
<|endoftext|>


<commit_before>/*
Copyright 2019 The Kubernetes Authors.

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

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

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

package e2e_metric_only

import (
	"context"
	"flag"
	"fmt"
	"os"
	"path"
	"testing"
	"time"

	"k8s.io/node-problem-detector/test/e2e/lib/gce"
	"k8s.io/test-infra/boskos/client"

	"github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/reporters"
	compute "google.golang.org/api/compute/v1"
)

const junitFileName = "junit.xml"

var zone = flag.String("zone", "", "gce zone the hosts live in")
var project = flag.String("project", "", "gce project the hosts live in")
var image = flag.String("image", "", "image to test")
var imageFamily = flag.String("image-family", "", "image family to pick up the test image. Ignored when -image is set.")
var imageProject = flag.String("image-project", "", "gce project of the OS image")
var jobName = flag.String("job-name", "", "name of the Prow job running the test")
var sshKey = flag.String("ssh-key", "", "path to ssh private key.")
var sshUser = flag.String("ssh-user", "", "use predefined user for ssh.")
var npdBuildTar = flag.String("npd-build-tar", "", "tarball containing NPD to be tested.")
var artifactsDir = flag.String("artifacts-dir", "", "local directory to save test artifacts into.")
var boskosProjectType = flag.String("boskos-project-type", "gce-project",
	"specifies which project type to select from Boskos.")
var boskosServerURL = flag.String("boskos-server-url", "http://boskos.test-pods.svc.cluster.local",
	"specifies Boskos server URL.")
var boskosWaitDuration = flag.Duration("boskos-wait-duration", 5*time.Minute,
	"Duration to wait before quitting getting Boskos resource.")

var computeService *compute.Service

func TestNPD(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}

	if *project == "" {
		boskosClient := client.NewClient(*jobName, *boskosServerURL)
		*project = acquireProjectOrDie(boskosClient)

		defer releaseProjectOrDie(boskosClient)
	}

	if *artifactsDir != "" {
		_, err := os.Stat(*artifactsDir)
		if err != nil && os.IsNotExist(err) {
			os.MkdirAll(*artifactsDir, os.ModeDir|0755)
		}
	}

	// The junit formatted result output is for showing test results on testgrid.
	junitReporter := reporters.NewJUnitReporter(path.Join(*artifactsDir, junitFileName))
	ginkgo.RunSpecsWithDefaultAndCustomReporters(t, "NPD Metric-only Suite", []ginkgo.Reporter{junitReporter})
}

func acquireProjectOrDie(boskosClient *client.Client) string {
	fmt.Printf("Renting project from Boskos\n")
	ctx, cancel := context.WithTimeout(context.Background(), *boskosWaitDuration)
	defer cancel()
	p, err := boskosClient.AcquireWait(ctx, *boskosProjectType, "free", "busy")
	if err != nil {
		panic(fmt.Sprintf("Unable to rent project from Boskos: %v\n", err))
	}
	fmt.Printf("Rented project %s from Boskos", p.Name)

	go func(boskosClient *client.Client, projectName string) {
		for range time.Tick(5 * time.Minute) {
			if err := boskosClient.UpdateOne(projectName, "busy", nil); err != nil {
				fmt.Printf("Failed to update status for project %s with Boskos: %v\n", projectName, err)
			}
		}
	}(boskosClient, p.Name)

	return p.Name
}

func releaseProjectOrDie(boskosClient *client.Client) {
	if !boskosClient.HasResource() {
		return
	}
	err := boskosClient.ReleaseAll("dirty")
	if err != nil {
		panic(fmt.Sprintf("Failed to release project to Boskos: %v", err))
	}
}

func TestMain(m *testing.M) {
	flag.Parse()

	var err error
	computeService, err = gce.GetComputeClient()
	if err != nil {
		panic(fmt.Sprintf("Unable to create gcloud compute service using defaults. Make sure you are authenticated. %v", err))
	}

	os.Exit(m.Run())
}
<commit_msg>fix make test early failure<commit_after>/*
Copyright 2019 The Kubernetes Authors.

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

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

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

package e2e_metric_only

import (
	"context"
	"flag"
	"fmt"
	"os"
	"path"
	"testing"
	"time"

	"k8s.io/node-problem-detector/test/e2e/lib/gce"
	"k8s.io/test-infra/boskos/client"

	"github.com/onsi/ginkgo"
	"github.com/onsi/ginkgo/reporters"
	compute "google.golang.org/api/compute/v1"
)

const junitFileName = "junit.xml"

var zone = flag.String("zone", "", "gce zone the hosts live in")
var project = flag.String("project", "", "gce project the hosts live in")
var image = flag.String("image", "", "image to test")
var imageFamily = flag.String("image-family", "", "image family to pick up the test image. Ignored when -image is set.")
var imageProject = flag.String("image-project", "", "gce project of the OS image")
var jobName = flag.String("job-name", "", "name of the Prow job running the test")
var sshKey = flag.String("ssh-key", "", "path to ssh private key.")
var sshUser = flag.String("ssh-user", "", "use predefined user for ssh.")
var npdBuildTar = flag.String("npd-build-tar", "", "tarball containing NPD to be tested.")
var artifactsDir = flag.String("artifacts-dir", "", "local directory to save test artifacts into.")
var boskosProjectType = flag.String("boskos-project-type", "gce-project",
	"specifies which project type to select from Boskos.")
var boskosServerURL = flag.String("boskos-server-url", "http://boskos.test-pods.svc.cluster.local",
	"specifies Boskos server URL.")
var boskosWaitDuration = flag.Duration("boskos-wait-duration", 5*time.Minute,
	"Duration to wait before quitting getting Boskos resource.")

var computeService *compute.Service

func TestNPD(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping test in short mode.")
	}

	var err error
	computeService, err = gce.GetComputeClient()
	if err != nil {
		panic(fmt.Sprintf("Unable to create gcloud compute service using defaults. Make sure you are authenticated. %v", err))
	}

	if *project == "" {
		boskosClient := client.NewClient(*jobName, *boskosServerURL)
		*project = acquireProjectOrDie(boskosClient)

		defer releaseProjectOrDie(boskosClient)
	}

	if *artifactsDir != "" {
		_, err := os.Stat(*artifactsDir)
		if err != nil && os.IsNotExist(err) {
			os.MkdirAll(*artifactsDir, os.ModeDir|0755)
		}
	}

	// The junit formatted result output is for showing test results on testgrid.
	junitReporter := reporters.NewJUnitReporter(path.Join(*artifactsDir, junitFileName))
	ginkgo.RunSpecsWithDefaultAndCustomReporters(t, "NPD Metric-only Suite", []ginkgo.Reporter{junitReporter})
}

func acquireProjectOrDie(boskosClient *client.Client) string {
	fmt.Printf("Renting project from Boskos\n")
	ctx, cancel := context.WithTimeout(context.Background(), *boskosWaitDuration)
	defer cancel()
	p, err := boskosClient.AcquireWait(ctx, *boskosProjectType, "free", "busy")
	if err != nil {
		panic(fmt.Sprintf("Unable to rent project from Boskos: %v\n", err))
	}
	fmt.Printf("Rented project %s from Boskos", p.Name)

	go func(boskosClient *client.Client, projectName string) {
		for range time.Tick(5 * time.Minute) {
			if err := boskosClient.UpdateOne(projectName, "busy", nil); err != nil {
				fmt.Printf("Failed to update status for project %s with Boskos: %v\n", projectName, err)
			}
		}
	}(boskosClient, p.Name)

	return p.Name
}

func releaseProjectOrDie(boskosClient *client.Client) {
	if !boskosClient.HasResource() {
		return
	}
	err := boskosClient.ReleaseAll("dirty")
	if err != nil {
		panic(fmt.Sprintf("Failed to release project to Boskos: %v", err))
	}
}

func TestMain(m *testing.M) {
	flag.Parse()

	os.Exit(m.Run())
}
<|endoftext|>


<commit_before>// +build e2e

/*
Copyright 2019 The Knative Authors

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

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

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

package e2e

import (
	"strconv"
	"testing"

	"github.com/knative/serving/pkg/apis/autoscaling"
	"github.com/knative/serving/pkg/apis/serving/v1alpha1"
	"github.com/knative/serving/test"
	v1a1test "github.com/knative/serving/test/v1alpha1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"knative.dev/pkg/test/logstream"
)

func TestMinScale(t *testing.T) {
	t.Parallel()
	cancel := logstream.Start(t)
	defer cancel()

	const minScale = 4

	clients := Setup(t)

	names := test.ResourceNames{
		Config: test.ObjectNameForTest(t),
		Image:  "helloworld",
	}

	if _, err := v1a1test.CreateConfiguration(t, clients, names, &v1a1test.Options{}, func(cfg *v1alpha1.Configuration) {
		if cfg.Spec.Template.Annotations == nil {
			cfg.Spec.Template.Annotations = make(map[string]string)
		}

		cfg.Spec.Template.Annotations[autoscaling.MinScaleAnnotationKey] = strconv.Itoa(minScale)

	}); err != nil {
		t.Fatalf("Failed to create Configuration: %v", err)
	}

	test.CleanupOnInterrupt(func() { test.TearDown(clients, names) })
	defer test.TearDown(clients, names)

	// Wait for the Config have a LatestCreatedRevisionName
	if err := v1a1test.WaitForConfigurationState(clients.ServingAlphaClient, names.Config, v1a1test.ConfigurationHasCreatedRevision, "ConfigurationHasCreatedRevision"); err != nil {
		t.Fatalf("The Configuration %q does not have a LatestCreatedRevisionName: %v", names.Config, err)
	}

	config, err := clients.ServingAlphaClient.Configs.Get(names.Config, metav1.GetOptions{})
	if err != nil {
		t.Fatalf("Failed to get Configuration after it was seen to be live: %v", err)
	}

	revName := config.Status.LatestCreatedRevisionName

	if err = v1a1test.WaitForRevisionState(clients.ServingAlphaClient, revName, v1a1test.IsRevisionReady, "RevisionIsReady"); err != nil {
		t.Fatal("Revision did not become ready.")
	}

	deployment, err := clients.KubeClient.Kube.ExtensionsV1beta1().Deployments(test.ServingNamespace).Get(revName+"-deployment", metav1.GetOptions{})
	if err != nil {
		t.Fatalf("Failed to get Deployment for Revision %s, err: %v", revName, err)
	}

	if deployment.Status.AvailableReplicas < int32(minScale) {
		t.Fatalf("Reported ready with %d replicas when minScale was %d", deployment.Status.AvailableReplicas, minScale)
	}
}
<commit_msg>Print error message from WaitForRevisionState in TestMinScale. (#4637)<commit_after>// +build e2e

/*
Copyright 2019 The Knative Authors

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

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

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

package e2e

import (
	"strconv"
	"testing"

	"github.com/knative/serving/pkg/apis/autoscaling"
	"github.com/knative/serving/pkg/apis/serving/v1alpha1"
	"github.com/knative/serving/test"
	v1a1test "github.com/knative/serving/test/v1alpha1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"knative.dev/pkg/test/logstream"
)

func TestMinScale(t *testing.T) {
	t.Parallel()
	cancel := logstream.Start(t)
	defer cancel()

	const minScale = 4

	clients := Setup(t)

	names := test.ResourceNames{
		Config: test.ObjectNameForTest(t),
		Image:  "helloworld",
	}

	if _, err := v1a1test.CreateConfiguration(t, clients, names, &v1a1test.Options{}, func(cfg *v1alpha1.Configuration) {
		if cfg.Spec.Template.Annotations == nil {
			cfg.Spec.Template.Annotations = make(map[string]string)
		}

		cfg.Spec.Template.Annotations[autoscaling.MinScaleAnnotationKey] = strconv.Itoa(minScale)

	}); err != nil {
		t.Fatalf("Failed to create Configuration: %v", err)
	}

	test.CleanupOnInterrupt(func() { test.TearDown(clients, names) })
	defer test.TearDown(clients, names)

	// Wait for the Config have a LatestCreatedRevisionName
	if err := v1a1test.WaitForConfigurationState(clients.ServingAlphaClient, names.Config, v1a1test.ConfigurationHasCreatedRevision, "ConfigurationHasCreatedRevision"); err != nil {
		t.Fatalf("The Configuration %q does not have a LatestCreatedRevisionName: %v", names.Config, err)
	}

	config, err := clients.ServingAlphaClient.Configs.Get(names.Config, metav1.GetOptions{})
	if err != nil {
		t.Fatalf("Failed to get Configuration after it was seen to be live: %v", err)
	}

	revName := config.Status.LatestCreatedRevisionName

	if err = v1a1test.WaitForRevisionState(clients.ServingAlphaClient, revName, v1a1test.IsRevisionReady, "RevisionIsReady"); err != nil {
		t.Fatalf("The Revision %q did not become ready: %v", revName, err)
	}

	deployment, err := clients.KubeClient.Kube.ExtensionsV1beta1().Deployments(test.ServingNamespace).Get(revName+"-deployment", metav1.GetOptions{})
	if err != nil {
		t.Fatalf("Failed to get Deployment for Revision %s, err: %v", revName, err)
	}

	if deployment.Status.AvailableReplicas < int32(minScale) {
		t.Fatalf("Reported ready with %d replicas when minScale was %d", deployment.Status.AvailableReplicas, minScale)
	}
}
<|endoftext|>