<commit_before>// Package binary provides a client-side library for the binary
// repository.
//
// TODO(jsimsa): Implement parallel download and upload.
package binary

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"time"

	"v.io/core/veyron2/context"
	"v.io/core/veyron2/services/mgmt/binary"
	"v.io/core/veyron2/services/mgmt/repository"
	verror "v.io/core/veyron2/verror2"
	"v.io/core/veyron2/vlog"

	"v.io/core/veyron/services/mgmt/lib/packages"
)

const pkgPath = "v.io/core/veyron/services/mgmt/lib/binary"

var (
	errOperationFailed = verror.Register(pkgPath+".errOperationFailed", verror.NoRetry, "{1:}{2:} operation failed{:_}")
)

const (
	nAttempts   = 2
	partSize    = 1 << 22
	subpartSize = 1 << 12
)

func Delete(ctx *context.T, name string) error {
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	if err := repository.BinaryClient(name).Delete(ctx); err != nil {
		vlog.Errorf("Delete() failed: %v", err)
		return err
	}
	return nil
}

type indexedPart struct {
	part   binary.PartInfo
	index  int
	offset int64
}

func downloadPartAttempt(ctx *context.T, w io.WriteSeeker, client repository.BinaryClientStub, ip *indexedPart) bool {
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	if _, err := w.Seek(ip.offset, 0); err != nil {
		vlog.Errorf("Seek(%v, 0) failed: %v", ip.offset, err)
		return false
	}
	stream, err := client.Download(ctx, int32(ip.index))
	if err != nil {
		vlog.Errorf("Download(%v) failed: %v", ip.index, err)
		return false
	}
	h, nreceived := md5.New(), 0
	rStream := stream.RecvStream()
	for rStream.Advance() {
		bytes := rStream.Value()
		if _, err := w.Write(bytes); err != nil {
			vlog.Errorf("Write() failed: %v", err)
			return false
		}
		h.Write(bytes)
		nreceived += len(bytes)
	}

	if err := rStream.Err(); err != nil {
		vlog.Errorf("Advance() failed: %v", err)
		return false
	}
	if err := stream.Finish(); err != nil {
		vlog.Errorf("Finish() failed: %v", err)
		return false
	}
	if expected, got := ip.part.Checksum, hex.EncodeToString(h.Sum(nil)); expected != got {
		vlog.Errorf("Unexpected checksum: expected %v, got %v", expected, got)
		return false
	}
	if expected, got := ip.part.Size, int64(nreceived); expected != got {
		vlog.Errorf("Unexpected size: expected %v, got %v", expected, got)
		return false
	}
	return true
}

func downloadPart(ctx *context.T, w io.WriteSeeker, client repository.BinaryClientStub, ip *indexedPart) bool {
	for i := 0; i < nAttempts; i++ {
		if downloadPartAttempt(ctx, w, client, ip) {
			return true
		}
	}
	return false
}

func download(ctx *context.T, w io.WriteSeeker, von string) (repository.MediaInfo, error) {
	client := repository.BinaryClient(von)
	parts, mediaInfo, err := client.Stat(ctx)
	if err != nil {
		vlog.Errorf("Stat() failed: %v", err)
		return repository.MediaInfo{}, err
	}
	for _, part := range parts {
		if part.Checksum == binary.MissingChecksum {
			return repository.MediaInfo{}, verror.Make(verror.NoExist, ctx)
		}
	}
	offset := int64(0)
	for i, part := range parts {
		ip := &indexedPart{part, i, offset}
		if !downloadPart(ctx, w, client, ip) {
			return repository.MediaInfo{}, verror.Make(errOperationFailed, ctx)
		}
		offset += part.Size
	}
	return mediaInfo, nil
}

func Download(ctx *context.T, von string) ([]byte, repository.MediaInfo, error) {
	dir, prefix := "", ""
	file, err := ioutil.TempFile(dir, prefix)
	if err != nil {
		vlog.Errorf("TempFile(%v, %v) failed: %v", dir, prefix, err)
		return nil, repository.MediaInfo{}, verror.Make(errOperationFailed, ctx)
	}
	defer os.Remove(file.Name())
	defer file.Close()
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	mediaInfo, err := download(ctx, file, von)
	if err != nil {
		return nil, repository.MediaInfo{}, verror.Make(errOperationFailed, ctx)
	}
	bytes, err := ioutil.ReadFile(file.Name())
	if err != nil {
		vlog.Errorf("ReadFile(%v) failed: %v", file.Name(), err)
		return nil, repository.MediaInfo{}, verror.Make(errOperationFailed, ctx)
	}
	return bytes, mediaInfo, nil
}

func DownloadToFile(ctx *context.T, von, path string) error {
	dir, prefix := "", ""
	file, err := ioutil.TempFile(dir, prefix)
	if err != nil {
		vlog.Errorf("TempFile(%v, %v) failed: %v", dir, prefix, err)
		return verror.Make(errOperationFailed, ctx)
	}
	defer file.Close()
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	mediaInfo, err := download(ctx, file, von)
	if err != nil {
		if err := os.Remove(file.Name()); err != nil {
			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
		}
		return verror.Make(errOperationFailed, ctx)
	}
	perm := os.FileMode(0600)
	if err := file.Chmod(perm); err != nil {
		vlog.Errorf("Chmod(%v) failed: %v", perm, err)
		if err := os.Remove(file.Name()); err != nil {
			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
		}
		return verror.Make(errOperationFailed, ctx)
	}
	if err := os.Rename(file.Name(), path); err != nil {
		vlog.Errorf("Rename(%v, %v) failed: %v", file.Name(), path, err)
		if err := os.Remove(file.Name()); err != nil {
			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
		}
		return verror.Make(errOperationFailed, ctx)
	}
	if err := packages.SaveMediaInfo(path, mediaInfo); err != nil {
		vlog.Errorf("packages.SaveMediaInfo(%v, %v) failed: %v", path, mediaInfo, err)
		if err := os.Remove(path); err != nil {
			vlog.Errorf("Remove(%v) failed: %v", path, err)
		}
		return verror.Make(errOperationFailed, ctx)
	}
	return nil
}

func DownloadURL(ctx *context.T, von string) (string, int64, error) {
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	url, ttl, err := repository.BinaryClient(von).DownloadURL(ctx)
	if err != nil {
		vlog.Errorf("DownloadURL() failed: %v", err)
		return "", 0, err
	}
	return url, ttl, nil
}

func uploadPartAttempt(ctx *context.T, r io.ReadSeeker, client repository.BinaryClientStub, part int, size int64) (bool, error) {
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	offset := int64(part * partSize)
	if _, err := r.Seek(offset, 0); err != nil {
		vlog.Errorf("Seek(%v, 0) failed: %v", offset, err)
		return false, nil
	}
	stream, err := client.Upload(ctx, int32(part))
	if err != nil {
		vlog.Errorf("Upload(%v) failed: %v", part, err)
		return false, nil
	}
	bufferSize := partSize
	if remaining := size - offset; remaining < int64(bufferSize) {
		bufferSize = int(remaining)
	}
	buffer := make([]byte, bufferSize)

	nread := 0
	for nread < len(buffer) {
		n, err := r.Read(buffer[nread:])
		nread += n
		if err != nil && (err != io.EOF || nread < len(buffer)) {
			vlog.Errorf("Read() failed: %v", err)
			return false, nil
		}
	}
	sender := stream.SendStream()
	for from := 0; from < len(buffer); from += subpartSize {
		to := from + subpartSize
		if to > len(buffer) {
			to = len(buffer)
		}
		if err := sender.Send(buffer[from:to]); err != nil {
			vlog.Errorf("Send() failed: %v", err)
			return false, nil
		}
	}
	if err := sender.Close(); err != nil {
		vlog.Errorf("Close() failed: %v", err)
		parts, _, statErr := client.Stat(ctx)
		if statErr != nil {
			vlog.Errorf("Stat() failed: %v", statErr)
			if deleteErr := client.Delete(ctx); err != nil {
				vlog.Errorf("Delete() failed: %v", deleteErr)
			}
			return false, err
		}
		if parts[part].Checksum == binary.MissingChecksum {
			return false, nil
		}
	}
	if err := stream.Finish(); err != nil {
		vlog.Errorf("Finish() failed: %v", err)
		parts, _, statErr := client.Stat(ctx)
		if statErr != nil {
			vlog.Errorf("Stat() failed: %v", statErr)
			if deleteErr := client.Delete(ctx); err != nil {
				vlog.Errorf("Delete() failed: %v", deleteErr)
			}
			return false, err
		}
		if parts[part].Checksum == binary.MissingChecksum {
			return false, nil
		}
	}
	return true, nil
}

func uploadPart(ctx *context.T, r io.ReadSeeker, client repository.BinaryClientStub, part int, size int64) error {
	for i := 0; i < nAttempts; i++ {
		if success, err := uploadPartAttempt(ctx, r, client, part, size); success || err != nil {
			return err
		}
	}
	return verror.Make(errOperationFailed, ctx)
}

func upload(ctx *context.T, r io.ReadSeeker, mediaInfo repository.MediaInfo, von string) error {
	client := repository.BinaryClient(von)
	offset, whence := int64(0), 2
	size, err := r.Seek(offset, whence)
	if err != nil {
		vlog.Errorf("Seek(%v, %v) failed: %v", offset, whence, err)
		return verror.Make(errOperationFailed, ctx)
	}
	nparts := (size-1)/partSize + 1
	if err := client.Create(ctx, int32(nparts), mediaInfo); err != nil {
		vlog.Errorf("Create() failed: %v", err)
		return err
	}
	for i := 0; int64(i) < nparts; i++ {
		if err := uploadPart(ctx, r, client, i, size); err != nil {
			return err
		}
	}
	return nil
}

func Upload(ctx *context.T, von string, data []byte, mediaInfo repository.MediaInfo) error {
	buffer := bytes.NewReader(data)
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	return upload(ctx, buffer, mediaInfo, von)
}

func UploadFromFile(ctx *context.T, von, path string) error {
	file, err := os.Open(path)
	defer file.Close()
	if err != nil {
		vlog.Errorf("Open(%v) failed: %v", err)
		return verror.Make(errOperationFailed, ctx)
	}
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	mediaInfo := packages.MediaInfoForFileName(path)
	return upload(ctx, file, mediaInfo, von)
}

func UploadFromDir(ctx *context.T, von, sourceDir string) error {
	dir, err := ioutil.TempDir("", "create-package-")
	if err != nil {
		return err
	}
	defer os.RemoveAll(dir)
	zipfile := filepath.Join(dir, "file.zip")
	if err := packages.CreateZip(zipfile, sourceDir); err != nil {
		return err
	}
	return UploadFromFile(ctx, von, zipfile)
}
<commit_msg>veyron/services/mgmt/lib/binary: Fix cross-fs rename<commit_after>// Package binary provides a client-side library for the binary
// repository.
//
// TODO(jsimsa): Implement parallel download and upload.
package binary

import (
	"bytes"
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"time"

	"v.io/core/veyron2/context"
	"v.io/core/veyron2/services/mgmt/binary"
	"v.io/core/veyron2/services/mgmt/repository"
	verror "v.io/core/veyron2/verror2"
	"v.io/core/veyron2/vlog"

	"v.io/core/veyron/services/mgmt/lib/packages"
)

const pkgPath = "v.io/core/veyron/services/mgmt/lib/binary"

var (
	errOperationFailed = verror.Register(pkgPath+".errOperationFailed", verror.NoRetry, "{1:}{2:} operation failed{:_}")
)

const (
	nAttempts   = 2
	partSize    = 1 << 22
	subpartSize = 1 << 12
)

func Delete(ctx *context.T, name string) error {
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	if err := repository.BinaryClient(name).Delete(ctx); err != nil {
		vlog.Errorf("Delete() failed: %v", err)
		return err
	}
	return nil
}

type indexedPart struct {
	part   binary.PartInfo
	index  int
	offset int64
}

func downloadPartAttempt(ctx *context.T, w io.WriteSeeker, client repository.BinaryClientStub, ip *indexedPart) bool {
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	if _, err := w.Seek(ip.offset, 0); err != nil {
		vlog.Errorf("Seek(%v, 0) failed: %v", ip.offset, err)
		return false
	}
	stream, err := client.Download(ctx, int32(ip.index))
	if err != nil {
		vlog.Errorf("Download(%v) failed: %v", ip.index, err)
		return false
	}
	h, nreceived := md5.New(), 0
	rStream := stream.RecvStream()
	for rStream.Advance() {
		bytes := rStream.Value()
		if _, err := w.Write(bytes); err != nil {
			vlog.Errorf("Write() failed: %v", err)
			return false
		}
		h.Write(bytes)
		nreceived += len(bytes)
	}

	if err := rStream.Err(); err != nil {
		vlog.Errorf("Advance() failed: %v", err)
		return false
	}
	if err := stream.Finish(); err != nil {
		vlog.Errorf("Finish() failed: %v", err)
		return false
	}
	if expected, got := ip.part.Checksum, hex.EncodeToString(h.Sum(nil)); expected != got {
		vlog.Errorf("Unexpected checksum: expected %v, got %v", expected, got)
		return false
	}
	if expected, got := ip.part.Size, int64(nreceived); expected != got {
		vlog.Errorf("Unexpected size: expected %v, got %v", expected, got)
		return false
	}
	return true
}

func downloadPart(ctx *context.T, w io.WriteSeeker, client repository.BinaryClientStub, ip *indexedPart) bool {
	for i := 0; i < nAttempts; i++ {
		if downloadPartAttempt(ctx, w, client, ip) {
			return true
		}
	}
	return false
}

func download(ctx *context.T, w io.WriteSeeker, von string) (repository.MediaInfo, error) {
	client := repository.BinaryClient(von)
	parts, mediaInfo, err := client.Stat(ctx)
	if err != nil {
		vlog.Errorf("Stat() failed: %v", err)
		return repository.MediaInfo{}, err
	}
	for _, part := range parts {
		if part.Checksum == binary.MissingChecksum {
			return repository.MediaInfo{}, verror.Make(verror.NoExist, ctx)
		}
	}
	offset := int64(0)
	for i, part := range parts {
		ip := &indexedPart{part, i, offset}
		if !downloadPart(ctx, w, client, ip) {
			return repository.MediaInfo{}, verror.Make(errOperationFailed, ctx)
		}
		offset += part.Size
	}
	return mediaInfo, nil
}

func Download(ctx *context.T, von string) ([]byte, repository.MediaInfo, error) {
	dir, prefix := "", ""
	file, err := ioutil.TempFile(dir, prefix)
	if err != nil {
		vlog.Errorf("TempFile(%v, %v) failed: %v", dir, prefix, err)
		return nil, repository.MediaInfo{}, verror.Make(errOperationFailed, ctx)
	}
	defer os.Remove(file.Name())
	defer file.Close()
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	mediaInfo, err := download(ctx, file, von)
	if err != nil {
		return nil, repository.MediaInfo{}, verror.Make(errOperationFailed, ctx)
	}
	bytes, err := ioutil.ReadFile(file.Name())
	if err != nil {
		vlog.Errorf("ReadFile(%v) failed: %v", file.Name(), err)
		return nil, repository.MediaInfo{}, verror.Make(errOperationFailed, ctx)
	}
	return bytes, mediaInfo, nil
}

func DownloadToFile(ctx *context.T, von, path string) error {
	dir := filepath.Dir(path)
	prefix := fmt.Sprintf(".download.%s.", filepath.Base(path))
	file, err := ioutil.TempFile(dir, prefix)
	if err != nil {
		vlog.Errorf("TempFile(%v, %v) failed: %v", dir, prefix, err)
		return verror.Make(errOperationFailed, ctx)
	}
	defer file.Close()
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	mediaInfo, err := download(ctx, file, von)
	if err != nil {
		if err := os.Remove(file.Name()); err != nil {
			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
		}
		return verror.Make(errOperationFailed, ctx)
	}
	perm := os.FileMode(0600)
	if err := file.Chmod(perm); err != nil {
		vlog.Errorf("Chmod(%v) failed: %v", perm, err)
		if err := os.Remove(file.Name()); err != nil {
			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
		}
		return verror.Make(errOperationFailed, ctx)
	}
	if err := os.Rename(file.Name(), path); err != nil {
		vlog.Errorf("Rename(%v, %v) failed: %v", file.Name(), path, err)
		if err := os.Remove(file.Name()); err != nil {
			vlog.Errorf("Remove(%v) failed: %v", file.Name(), err)
		}
		return verror.Make(errOperationFailed, ctx)
	}
	if err := packages.SaveMediaInfo(path, mediaInfo); err != nil {
		vlog.Errorf("packages.SaveMediaInfo(%v, %v) failed: %v", path, mediaInfo, err)
		if err := os.Remove(path); err != nil {
			vlog.Errorf("Remove(%v) failed: %v", path, err)
		}
		return verror.Make(errOperationFailed, ctx)
	}
	return nil
}

func DownloadURL(ctx *context.T, von string) (string, int64, error) {
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	url, ttl, err := repository.BinaryClient(von).DownloadURL(ctx)
	if err != nil {
		vlog.Errorf("DownloadURL() failed: %v", err)
		return "", 0, err
	}
	return url, ttl, nil
}

func uploadPartAttempt(ctx *context.T, r io.ReadSeeker, client repository.BinaryClientStub, part int, size int64) (bool, error) {
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	offset := int64(part * partSize)
	if _, err := r.Seek(offset, 0); err != nil {
		vlog.Errorf("Seek(%v, 0) failed: %v", offset, err)
		return false, nil
	}
	stream, err := client.Upload(ctx, int32(part))
	if err != nil {
		vlog.Errorf("Upload(%v) failed: %v", part, err)
		return false, nil
	}
	bufferSize := partSize
	if remaining := size - offset; remaining < int64(bufferSize) {
		bufferSize = int(remaining)
	}
	buffer := make([]byte, bufferSize)

	nread := 0
	for nread < len(buffer) {
		n, err := r.Read(buffer[nread:])
		nread += n
		if err != nil && (err != io.EOF || nread < len(buffer)) {
			vlog.Errorf("Read() failed: %v", err)
			return false, nil
		}
	}
	sender := stream.SendStream()
	for from := 0; from < len(buffer); from += subpartSize {
		to := from + subpartSize
		if to > len(buffer) {
			to = len(buffer)
		}
		if err := sender.Send(buffer[from:to]); err != nil {
			vlog.Errorf("Send() failed: %v", err)
			return false, nil
		}
	}
	if err := sender.Close(); err != nil {
		vlog.Errorf("Close() failed: %v", err)
		parts, _, statErr := client.Stat(ctx)
		if statErr != nil {
			vlog.Errorf("Stat() failed: %v", statErr)
			if deleteErr := client.Delete(ctx); err != nil {
				vlog.Errorf("Delete() failed: %v", deleteErr)
			}
			return false, err
		}
		if parts[part].Checksum == binary.MissingChecksum {
			return false, nil
		}
	}
	if err := stream.Finish(); err != nil {
		vlog.Errorf("Finish() failed: %v", err)
		parts, _, statErr := client.Stat(ctx)
		if statErr != nil {
			vlog.Errorf("Stat() failed: %v", statErr)
			if deleteErr := client.Delete(ctx); err != nil {
				vlog.Errorf("Delete() failed: %v", deleteErr)
			}
			return false, err
		}
		if parts[part].Checksum == binary.MissingChecksum {
			return false, nil
		}
	}
	return true, nil
}

func uploadPart(ctx *context.T, r io.ReadSeeker, client repository.BinaryClientStub, part int, size int64) error {
	for i := 0; i < nAttempts; i++ {
		if success, err := uploadPartAttempt(ctx, r, client, part, size); success || err != nil {
			return err
		}
	}
	return verror.Make(errOperationFailed, ctx)
}

func upload(ctx *context.T, r io.ReadSeeker, mediaInfo repository.MediaInfo, von string) error {
	client := repository.BinaryClient(von)
	offset, whence := int64(0), 2
	size, err := r.Seek(offset, whence)
	if err != nil {
		vlog.Errorf("Seek(%v, %v) failed: %v", offset, whence, err)
		return verror.Make(errOperationFailed, ctx)
	}
	nparts := (size-1)/partSize + 1
	if err := client.Create(ctx, int32(nparts), mediaInfo); err != nil {
		vlog.Errorf("Create() failed: %v", err)
		return err
	}
	for i := 0; int64(i) < nparts; i++ {
		if err := uploadPart(ctx, r, client, i, size); err != nil {
			return err
		}
	}
	return nil
}

func Upload(ctx *context.T, von string, data []byte, mediaInfo repository.MediaInfo) error {
	buffer := bytes.NewReader(data)
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	return upload(ctx, buffer, mediaInfo, von)
}

func UploadFromFile(ctx *context.T, von, path string) error {
	file, err := os.Open(path)
	defer file.Close()
	if err != nil {
		vlog.Errorf("Open(%v) failed: %v", err)
		return verror.Make(errOperationFailed, ctx)
	}
	ctx, cancel := context.WithTimeout(ctx, time.Minute)
	defer cancel()
	mediaInfo := packages.MediaInfoForFileName(path)
	return upload(ctx, file, mediaInfo, von)
}

func UploadFromDir(ctx *context.T, von, sourceDir string) error {
	dir, err := ioutil.TempDir("", "create-package-")
	if err != nil {
		return err
	}
	defer os.RemoveAll(dir)
	zipfile := filepath.Join(dir, "file.zip")
	if err := packages.CreateZip(zipfile, sourceDir); err != nil {
		return err
	}
	return UploadFromFile(ctx, von, zipfile)
}
<|endoftext|>


<commit_before>package template

import (
	"fmt"
	"github.com/mdevilliers/redishappy/types"
	"testing"
)

func TestLoadTempate(t *testing.T) {

	path := "../../example_haproxy_template.cfg"
	collection := types.NewMasterDetailsCollection()
	collection.AddOrReplace(&types.MasterDetails{Name: "one", Ip: "10.0.0.1", Port: 2345, ExternalPort: 5432})
	collection.AddOrReplace(&types.MasterDetails{Name: "two", Ip: "10.0.1.1", Port: 5432, ExternalPort: 2345})

	renderedTemplate, err := RenderTemplate(path, collection)

	if err != nil {
		t.Error("Error rendering test file")
	}

	fmt.Printf("%s", renderedTemplate)
}

func TestLoadNonExistingTempate(t *testing.T) {

	path := "does_not_exist_template.cfg"
	collection := types.NewMasterDetailsCollection()

	_, err := RenderTemplate(path, collection)

	if err == nil {
		t.Error("Template doesn't exist - this should error")
	}
}
<commit_msg>fixed up template test<commit_after>package template

import (
	"fmt"
	"github.com/mdevilliers/redishappy/types"
	"testing"
)

func TestLoadTempate(t *testing.T) {

	path := "../../example_haproxy_template.cfg"
	collection := types.NewMasterDetailsCollection()
	collection.AddOrReplace(&types.MasterDetails{Name: "one", Ip: "10.0.0.1", Port: 2345, ExternalPort: 5432})
	collection.AddOrReplace(&types.MasterDetails{Name: "two", Ip: "10.0.1.1", Port: 5432, ExternalPort: 2345})

	renderedTemplate, err := RenderTemplate(path, &collection)

	if err != nil {
		t.Error("Error rendering test file")
	}

	fmt.Printf("%s", renderedTemplate)
}

func TestLoadNonExistingTempate(t *testing.T) {

	path := "does_not_exist_template.cfg"
	collection := types.NewMasterDetailsCollection()

	_, err := RenderTemplate(path, &collection)

	if err == nil {
		t.Error("Template doesn't exist - this should error")
	}
}
<|endoftext|>


<commit_before>/*
Copyright (c) 2017 VMware, 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 vpx

import "github.com/vmware/govmomi/vim25/types"

// ServiceContent is the default template for the ServiceInstance content property.
// Capture method:
//   govc object.collect -s -dump - content
var ServiceContent = types.ServiceContent{
	RootFolder:        types.ManagedObjectReference{Type: "Folder", Value: "group-d1"},
	PropertyCollector: types.ManagedObjectReference{Type: "PropertyCollector", Value: "propertyCollector"},
	ViewManager:       &types.ManagedObjectReference{Type: "ViewManager", Value: "ViewManager"},
	About: types.AboutInfo{
		Name:                  "VMware vCenter Server",
		FullName:              "VMware vCenter Server 6.5.0 build-5973321",
		Vendor:                "VMware, Inc.",
		Version:               "6.5.0",
		Build:                 "5973321",
		LocaleVersion:         "INTL",
		LocaleBuild:           "000",
		OsType:                "linux-x64",
		ProductLineId:         "vpx",
		ApiType:               "VirtualCenter",
		ApiVersion:            "6.5",
		InstanceUuid:          "dbed6e0c-bd88-4ef6-b594-21283e1c677f",
		LicenseProductName:    "VMware VirtualCenter Server",
		LicenseProductVersion: "6.0",
	},
	Setting:                     &types.ManagedObjectReference{Type: "OptionManager", Value: "VpxSettings"},
	UserDirectory:               &types.ManagedObjectReference{Type: "UserDirectory", Value: "UserDirectory"},
	SessionManager:              &types.ManagedObjectReference{Type: "SessionManager", Value: "SessionManager"},
	AuthorizationManager:        &types.ManagedObjectReference{Type: "AuthorizationManager", Value: "AuthorizationManager"},
	ServiceManager:              &types.ManagedObjectReference{Type: "ServiceManager", Value: "ServiceMgr"},
	PerfManager:                 &types.ManagedObjectReference{Type: "PerformanceManager", Value: "PerfMgr"},
	ScheduledTaskManager:        &types.ManagedObjectReference{Type: "ScheduledTaskManager", Value: "ScheduledTaskManager"},
	AlarmManager:                &types.ManagedObjectReference{Type: "AlarmManager", Value: "AlarmManager"},
	EventManager:                &types.ManagedObjectReference{Type: "EventManager", Value: "EventManager"},
	TaskManager:                 &types.ManagedObjectReference{Type: "TaskManager", Value: "TaskManager"},
	ExtensionManager:            &types.ManagedObjectReference{Type: "ExtensionManager", Value: "ExtensionManager"},
	CustomizationSpecManager:    &types.ManagedObjectReference{Type: "CustomizationSpecManager", Value: "CustomizationSpecManager"},
	CustomFieldsManager:         &types.ManagedObjectReference{Type: "CustomFieldsManager", Value: "CustomFieldsManager"},
	AccountManager:              (*types.ManagedObjectReference)(nil),
	DiagnosticManager:           &types.ManagedObjectReference{Type: "DiagnosticManager", Value: "DiagMgr"},
	LicenseManager:              &types.ManagedObjectReference{Type: "LicenseManager", Value: "LicenseManager"},
	SearchIndex:                 &types.ManagedObjectReference{Type: "SearchIndex", Value: "SearchIndex"},
	FileManager:                 &types.ManagedObjectReference{Type: "FileManager", Value: "FileManager"},
	DatastoreNamespaceManager:   &types.ManagedObjectReference{Type: "DatastoreNamespaceManager", Value: "DatastoreNamespaceManager"},
	VirtualDiskManager:          &types.ManagedObjectReference{Type: "VirtualDiskManager", Value: "virtualDiskManager"},
	VirtualizationManager:       (*types.ManagedObjectReference)(nil),
	SnmpSystem:                  &types.ManagedObjectReference{Type: "HostSnmpSystem", Value: "SnmpSystem"},
	VmProvisioningChecker:       &types.ManagedObjectReference{Type: "VirtualMachineProvisioningChecker", Value: "ProvChecker"},
	VmCompatibilityChecker:      &types.ManagedObjectReference{Type: "VirtualMachineCompatibilityChecker", Value: "CompatChecker"},
	OvfManager:                  &types.ManagedObjectReference{Type: "OvfManager", Value: "OvfManager"},
	IpPoolManager:               &types.ManagedObjectReference{Type: "IpPoolManager", Value: "IpPoolManager"},
	DvSwitchManager:             &types.ManagedObjectReference{Type: "DistributedVirtualSwitchManager", Value: "DVSManager"},
	HostProfileManager:          &types.ManagedObjectReference{Type: "HostProfileManager", Value: "HostProfileManager"},
	ClusterProfileManager:       &types.ManagedObjectReference{Type: "ClusterProfileManager", Value: "ClusterProfileManager"},
	ComplianceManager:           &types.ManagedObjectReference{Type: "ProfileComplianceManager", Value: "MoComplianceManager"},
	LocalizationManager:         &types.ManagedObjectReference{Type: "LocalizationManager", Value: "LocalizationManager"},
	StorageResourceManager:      &types.ManagedObjectReference{Type: "StorageResourceManager", Value: "StorageResourceManager"},
	GuestOperationsManager:      &types.ManagedObjectReference{Type: "GuestOperationsManager", Value: "guestOperationsManager"},
	OverheadMemoryManager:       &types.ManagedObjectReference{Type: "OverheadMemoryManager", Value: "OverheadMemoryManager"},
	CertificateManager:          &types.ManagedObjectReference{Type: "CertificateManager", Value: "certificateManager"},
	IoFilterManager:             &types.ManagedObjectReference{Type: "IoFilterManager", Value: "IoFilterManager"},
	VStorageObjectManager:       &types.ManagedObjectReference{Type: "VcenterVStorageObjectManager", Value: "VStorageObjectManager"},
	HostSpecManager:             &types.ManagedObjectReference{Type: "HostSpecificationManager", Value: "HostSpecificationManager"},
	CryptoManager:               &types.ManagedObjectReference{Type: "CryptoManagerKmip", Value: "CryptoManager"},
	HealthUpdateManager:         &types.ManagedObjectReference{Type: "HealthUpdateManager", Value: "HealthUpdateManager"},
	FailoverClusterConfigurator: &types.ManagedObjectReference{Type: "FailoverClusterConfigurator", Value: "FailoverClusterConfigurator"},
	FailoverClusterManager:      &types.ManagedObjectReference{Type: "FailoverClusterManager", Value: "FailoverClusterManager"},
}
<commit_msg>vcsim: use node id for ServiceContent.InstanceUuid<commit_after>/*
Copyright (c) 2017 VMware, 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 vpx

import (
	"github.com/google/uuid"

	"github.com/vmware/govmomi/vim25/types"
)

// ServiceContent is the default template for the ServiceInstance content property.
// Capture method:
//   govc object.collect -s -dump - content
var ServiceContent = types.ServiceContent{
	RootFolder:        types.ManagedObjectReference{Type: "Folder", Value: "group-d1"},
	PropertyCollector: types.ManagedObjectReference{Type: "PropertyCollector", Value: "propertyCollector"},
	ViewManager:       &types.ManagedObjectReference{Type: "ViewManager", Value: "ViewManager"},
	About: types.AboutInfo{
		Name:                  "VMware vCenter Server",
		FullName:              "VMware vCenter Server 6.5.0 build-5973321",
		Vendor:                "VMware, Inc.",
		Version:               "6.5.0",
		Build:                 "5973321",
		LocaleVersion:         "INTL",
		LocaleBuild:           "000",
		OsType:                "linux-x64",
		ProductLineId:         "vpx",
		ApiType:               "VirtualCenter",
		ApiVersion:            "6.5",
		InstanceUuid:          uuid.NewSHA1(uuid.NameSpaceOID, uuid.NodeID()).String(),
		LicenseProductName:    "VMware VirtualCenter Server",
		LicenseProductVersion: "6.0",
	},
	Setting:                     &types.ManagedObjectReference{Type: "OptionManager", Value: "VpxSettings"},
	UserDirectory:               &types.ManagedObjectReference{Type: "UserDirectory", Value: "UserDirectory"},
	SessionManager:              &types.ManagedObjectReference{Type: "SessionManager", Value: "SessionManager"},
	AuthorizationManager:        &types.ManagedObjectReference{Type: "AuthorizationManager", Value: "AuthorizationManager"},
	ServiceManager:              &types.ManagedObjectReference{Type: "ServiceManager", Value: "ServiceMgr"},
	PerfManager:                 &types.ManagedObjectReference{Type: "PerformanceManager", Value: "PerfMgr"},
	ScheduledTaskManager:        &types.ManagedObjectReference{Type: "ScheduledTaskManager", Value: "ScheduledTaskManager"},
	AlarmManager:                &types.ManagedObjectReference{Type: "AlarmManager", Value: "AlarmManager"},
	EventManager:                &types.ManagedObjectReference{Type: "EventManager", Value: "EventManager"},
	TaskManager:                 &types.ManagedObjectReference{Type: "TaskManager", Value: "TaskManager"},
	ExtensionManager:            &types.ManagedObjectReference{Type: "ExtensionManager", Value: "ExtensionManager"},
	CustomizationSpecManager:    &types.ManagedObjectReference{Type: "CustomizationSpecManager", Value: "CustomizationSpecManager"},
	CustomFieldsManager:         &types.ManagedObjectReference{Type: "CustomFieldsManager", Value: "CustomFieldsManager"},
	AccountManager:              (*types.ManagedObjectReference)(nil),
	DiagnosticManager:           &types.ManagedObjectReference{Type: "DiagnosticManager", Value: "DiagMgr"},
	LicenseManager:              &types.ManagedObjectReference{Type: "LicenseManager", Value: "LicenseManager"},
	SearchIndex:                 &types.ManagedObjectReference{Type: "SearchIndex", Value: "SearchIndex"},
	FileManager:                 &types.ManagedObjectReference{Type: "FileManager", Value: "FileManager"},
	DatastoreNamespaceManager:   &types.ManagedObjectReference{Type: "DatastoreNamespaceManager", Value: "DatastoreNamespaceManager"},
	VirtualDiskManager:          &types.ManagedObjectReference{Type: "VirtualDiskManager", Value: "virtualDiskManager"},
	VirtualizationManager:       (*types.ManagedObjectReference)(nil),
	SnmpSystem:                  &types.ManagedObjectReference{Type: "HostSnmpSystem", Value: "SnmpSystem"},
	VmProvisioningChecker:       &types.ManagedObjectReference{Type: "VirtualMachineProvisioningChecker", Value: "ProvChecker"},
	VmCompatibilityChecker:      &types.ManagedObjectReference{Type: "VirtualMachineCompatibilityChecker", Value: "CompatChecker"},
	OvfManager:                  &types.ManagedObjectReference{Type: "OvfManager", Value: "OvfManager"},
	IpPoolManager:               &types.ManagedObjectReference{Type: "IpPoolManager", Value: "IpPoolManager"},
	DvSwitchManager:             &types.ManagedObjectReference{Type: "DistributedVirtualSwitchManager", Value: "DVSManager"},
	HostProfileManager:          &types.ManagedObjectReference{Type: "HostProfileManager", Value: "HostProfileManager"},
	ClusterProfileManager:       &types.ManagedObjectReference{Type: "ClusterProfileManager", Value: "ClusterProfileManager"},
	ComplianceManager:           &types.ManagedObjectReference{Type: "ProfileComplianceManager", Value: "MoComplianceManager"},
	LocalizationManager:         &types.ManagedObjectReference{Type: "LocalizationManager", Value: "LocalizationManager"},
	StorageResourceManager:      &types.ManagedObjectReference{Type: "StorageResourceManager", Value: "StorageResourceManager"},
	GuestOperationsManager:      &types.ManagedObjectReference{Type: "GuestOperationsManager", Value: "guestOperationsManager"},
	OverheadMemoryManager:       &types.ManagedObjectReference{Type: "OverheadMemoryManager", Value: "OverheadMemoryManager"},
	CertificateManager:          &types.ManagedObjectReference{Type: "CertificateManager", Value: "certificateManager"},
	IoFilterManager:             &types.ManagedObjectReference{Type: "IoFilterManager", Value: "IoFilterManager"},
	VStorageObjectManager:       &types.ManagedObjectReference{Type: "VcenterVStorageObjectManager", Value: "VStorageObjectManager"},
	HostSpecManager:             &types.ManagedObjectReference{Type: "HostSpecificationManager", Value: "HostSpecificationManager"},
	CryptoManager:               &types.ManagedObjectReference{Type: "CryptoManagerKmip", Value: "CryptoManager"},
	HealthUpdateManager:         &types.ManagedObjectReference{Type: "HealthUpdateManager", Value: "HealthUpdateManager"},
	FailoverClusterConfigurator: &types.ManagedObjectReference{Type: "FailoverClusterConfigurator", Value: "FailoverClusterConfigurator"},
	FailoverClusterManager:      &types.ManagedObjectReference{Type: "FailoverClusterManager", Value: "FailoverClusterManager"},
}
<|endoftext|>


<commit_before>package snapshot

import (
	"github.com/containerd/containerd/errdefs"
	"github.com/containerd/containerd/mount"
	"github.com/pkg/errors"
)

func (lm *localMounter) Mount() (string, error) {
	lm.mu.Lock()
	defer lm.mu.Unlock()

	if lm.mounts == nil {
		mounts, release, err := lm.mountable.Mount()
		if err != nil {
			return "", err
		}
		lm.mounts = mounts
		lm.release = release
	}

	// Windows can only mount a single mount at a given location.
	// Parent layers are carried in Options, opaquely to localMounter.
	if len(lm.mounts) != 1 {
		return "", errors.Wrapf(errdefs.ErrNotImplemented, "request to mount %d layers, only 1 is supported", len(lm.mounts))
	}

	// Windows mounts always activate in-place, so the target of the mount must be the source directory.
	// See https://github.com/containerd/containerd/pull/2366
	dir := lm.mounts[0].Source

	if err := lm.mounts[0].Mount(dir); err != nil {
		return "", errors.Wrapf(err, "failed to mount in-place: %v", lm.mounts[0])
	}
	lm.target = dir
	return lm.target, nil
}

func (lm *localMounter) Unmount() error {
	lm.mu.Lock()
	defer lm.mu.Unlock()

	if lm.target != "" {
		if err := mount.Unmount(lm.target, 0); err != nil {
			return err
		}
		lm.target = ""
	}

	if lm.release != nil {
		return lm.release()
	}

	return nil
}
<commit_msg>Shortcut read-only bind-mounts in Windows, like non-Windows<commit_after>package snapshot

import (
	"github.com/containerd/containerd/errdefs"
	"github.com/containerd/containerd/mount"
	"github.com/pkg/errors"
)

func (lm *localMounter) Mount() (string, error) {
	lm.mu.Lock()
	defer lm.mu.Unlock()

	if lm.mounts == nil {
		mounts, release, err := lm.mountable.Mount()
		if err != nil {
			return "", err
		}
		lm.mounts = mounts
		lm.release = release
	}

	// Windows can only mount a single mount at a given location.
	// Parent layers are carried in Options, opaquely to localMounter.
	if len(lm.mounts) != 1 {
		return "", errors.Wrapf(errdefs.ErrNotImplemented, "request to mount %d layers, only 1 is supported", len(lm.mounts))
	}

	if lm.mounts[0].Type == "bind" || lm.mounts[0].Type == "rbind" {
		ro := false
		for _, opt := range lm.mounts[0].Options {
			if opt == "ro" {
				ro = true
				break
			}
		}
		if !ro {
			return lm.mounts[0].Source, nil
		}
	}

	// Windows mounts always activate in-place, so the target of the mount must be the source directory.
	// See https://github.com/containerd/containerd/pull/2366
	dir := lm.mounts[0].Source

	if err := lm.mounts[0].Mount(dir); err != nil {
		return "", errors.Wrapf(err, "failed to mount in-place: %v", lm.mounts[0])
	}
	lm.target = dir
	return lm.target, nil
}

func (lm *localMounter) Unmount() error {
	lm.mu.Lock()
	defer lm.mu.Unlock()

	if lm.target != "" {
		if err := mount.Unmount(lm.target, 0); err != nil {
			return err
		}
		lm.target = ""
	}

	if lm.release != nil {
		return lm.release()
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright 2009 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sym

import (
	"fmt";
	"io";
	"log";
	"os";
)

/*
 * Internal ELF representation
 */

// Elf represents a decoded ELF binary.
type Elf struct {
	class int;
	data byteOrder;
	Type ElfType;
	Machine ElfMachine;
	Sections []*Section;
}

// Section represents a single section in an ELF binary.
type Section struct {
	r io.ReadSeeker;
	Name string;
	offset int64;
	Size uint64;
	Addr uint64;
}

/*
 * ELF reader
 */

type FormatError struct {
	off int64;
	msg string;
	val interface{};
}

func (e *FormatError) String() string {
	msg := e.msg;
	if e.val != nil {
		msg += fmt.Sprintf(" '%v' ", e.val);
	}
	msg += fmt.Sprintf("in record at byte %#x", e.off);
	return msg;
}

// NewElf reads and decodes an ELF binary.  The ELF binary is expected
// to start where the reader is currently positioned.
func NewElf(r io.ReadSeeker) (*Elf, os.Error) {
	// Read ELF identifier
	var ident [eiNIdent]uint8;
	off, err := r.Seek(0, 0);
	if err != nil {
		return nil, err;
	}
	start := off;
	n, err := io.ReadFull(r, &ident);
	if err != nil {
		if err == os.EOF {
			err = io.ErrUnexpectedEOF;
		}
		return nil, err;
	}

	// Decode identifier
	if ident[eiMag0] != '\x7f' || ident[eiMag1] != 'E' || ident[eiMag2] != 'L' || ident[eiMag3] != 'F' {
		return nil, &FormatError{off, "bad magic number", string(ident[eiMag0:eiMag3])};
	}
	e := &Elf{};

	switch ident[eiClass] {
	case elfClass32:
		e.class = 32;
	case elfClass64:
		e.class = 64;
	default:
		return nil, &FormatError{off, "unknown ELF class", ident[eiClass]};
	}

	switch ident[eiData] {
	case elfData2LSB:
		e.data = lsb;
	case elfData2MSB:
		e.data = msb;
	default:
		return nil, &FormatError{off, "unknown ELF data encoding", ident[eiData]};
	}

	if ident[eiVersion] != evCurrent {
		return nil, &FormatError{off, "unknown ELF version", ident[eiVersion]};
	}

	// TODO(austin) Do something with ABI?

	// Read ELF file header
	var shoff int64;
	var shentsize, shnum, shstrndx int;

	br := newBinaryReader(r, e.data);
	switch e.class {
	case 32:
		return nil, &FormatError{off, "ELF32 not implemented", nil};
	case 64:
		hdr := &elf64Ehdr{};
		br.ReadAny(hdr);
		if err := br.Error(); err != nil {
			return nil, err;
		}

		if hdr.Type > etCore && hdr.Type < etLoOS {
			return nil, &FormatError{off, "unknown ELF file type", hdr.Type};
		}
		e.Type = ElfType(hdr.Type);
		e.Machine = ElfMachine(hdr.Machine);
		if hdr.Version != evCurrent {
			return nil, &FormatError{off, "unknown second ELF version", hdr.Version};
		}

		shoff = int64(hdr.Shoff);
		shentsize = int(hdr.Shentsize);
		shnum = int(hdr.Shnum);
		shstrndx = int(hdr.Shstrndx);
	}

	// Read section headers
	e.Sections = make([]*Section, shnum);
	secNames := make([]uint32, shnum);
	for i := 0; i < shnum; i++ {
		off, err = r.Seek(start + shoff + int64(i*shentsize), 0);
		if err != nil {
			return nil, err;
		}

		br = newBinaryReader(r, e.data);
		switch e.class {
		case 32:
			panic("not reached");
		case 64:
			shdr := &elf64Shdr{};
			br.ReadAny(shdr);
			if err := br.Error(); err != nil {
				return nil, err;
			}

			s := &Section{
				r: r,
				offset: start + int64(shdr.Off),
				Size: shdr.Size,
				Addr: uint64(shdr.Addr),
			};
			secNames[i] = shdr.Name;
			e.Sections[i] = s;
		}
	}

	// Resolve section names
	off, err = r.Seek(start + e.Sections[shstrndx].offset, 0);
	if err != nil {
		return nil, err;
	}
	blob := make([]byte, e.Sections[shstrndx].Size);
	n, err = io.ReadFull(r, blob);
	strings := make(map[uint32] string);
	strStart := uint32(0);
	for i, c := range blob {
		if c == 0 {
			strings[strStart] = string(blob[strStart:i]);
			strStart = uint32(i+1);
		}
	}

	for i, s := range e.Sections {
		var ok bool;
		s.Name, ok = strings[secNames[i]];
		if !ok {
			return nil, &FormatError{start + shoff + int64(i*shentsize), "bad section name", secNames[i]};
		}
	}

	return e, nil;
}

// Section returns a section with the given name, or nil if no such
// section exists.
func (e *Elf) Section(name string) *Section {
	for _, s := range e.Sections {
		if s.Name == name {
			return s;
		}
	}
	return nil;
}

/*
 * Sections
 */

type subReader struct {
	r io.Reader;
	rem uint64;
}

func (r *subReader) Read(b []byte) (ret int, err os.Error) {
	if r.rem == 0 {
		return 0, os.EOF;
	}
	if uint64(len(b)) > r.rem {
		b = b[0:r.rem];
	}
	ret, err = r.r.Read(b);
	r.rem -= uint64(ret);
	if err == os.EOF {
		err = io.ErrUnexpectedEOF;
	}
	return ret, err;
}

// Open returns a reader backed by the data in this section.
// The original ELF file must still be open for this to work.
// The returned reader assumes there will be no seeks on the
// underlying file or any other opened section between the Open call
// and the last call to Read.
func (s *Section) Open() (io.Reader, os.Error) {
	_, err := s.r.Seek(s.offset, 0);
	if err != nil {
		return nil, err;
	}
	return &subReader{s.r, s.Size}, nil;
}
<commit_msg>Decode overlapping section names correctly.<commit_after>// Copyright 2009 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sym

import (
	"fmt";
	"io";
	"log";
	"os";
)

/*
 * Internal ELF representation
 */

// Elf represents a decoded ELF binary.
type Elf struct {
	class int;
	data byteOrder;
	Type ElfType;
	Machine ElfMachine;
	Sections []*Section;
}

// Section represents a single section in an ELF binary.
type Section struct {
	r io.ReadSeeker;
	Name string;
	offset int64;
	Size uint64;
	Addr uint64;
}

/*
 * ELF reader
 */

type FormatError struct {
	off int64;
	msg string;
	val interface{};
}

func (e *FormatError) String() string {
	msg := e.msg;
	if e.val != nil {
		msg += fmt.Sprintf(" '%v' ", e.val);
	}
	msg += fmt.Sprintf("in record at byte %#x", e.off);
	return msg;
}

// NewElf reads and decodes an ELF binary.  The ELF binary is expected
// to start where the reader is currently positioned.
func NewElf(r io.ReadSeeker) (*Elf, os.Error) {
	// Read ELF identifier
	var ident [eiNIdent]uint8;
	off, err := r.Seek(0, 0);
	if err != nil {
		return nil, err;
	}
	start := off;
	n, err := io.ReadFull(r, &ident);
	if err != nil {
		if err == os.EOF {
			err = io.ErrUnexpectedEOF;
		}
		return nil, err;
	}

	// Decode identifier
	if ident[eiMag0] != '\x7f' || ident[eiMag1] != 'E' || ident[eiMag2] != 'L' || ident[eiMag3] != 'F' {
		return nil, &FormatError{off, "bad magic number", string(ident[eiMag0:eiMag3])};
	}
	e := &Elf{};

	switch ident[eiClass] {
	case elfClass32:
		e.class = 32;
	case elfClass64:
		e.class = 64;
	default:
		return nil, &FormatError{off, "unknown ELF class", ident[eiClass]};
	}

	switch ident[eiData] {
	case elfData2LSB:
		e.data = lsb;
	case elfData2MSB:
		e.data = msb;
	default:
		return nil, &FormatError{off, "unknown ELF data encoding", ident[eiData]};
	}

	if ident[eiVersion] != evCurrent {
		return nil, &FormatError{off, "unknown ELF version", ident[eiVersion]};
	}

	// TODO(austin) Do something with ABI?

	// Read ELF file header
	var shoff int64;
	var shentsize, shnum, shstrndx int;

	br := newBinaryReader(r, e.data);
	switch e.class {
	case 32:
		return nil, &FormatError{off, "ELF32 not implemented", nil};
	case 64:
		hdr := &elf64Ehdr{};
		br.ReadAny(hdr);
		if err := br.Error(); err != nil {
			return nil, err;
		}

		if hdr.Type > etCore && hdr.Type < etLoOS {
			return nil, &FormatError{off, "unknown ELF file type", hdr.Type};
		}
		e.Type = ElfType(hdr.Type);
		e.Machine = ElfMachine(hdr.Machine);
		if hdr.Version != evCurrent {
			return nil, &FormatError{off, "unknown second ELF version", hdr.Version};
		}

		shoff = int64(hdr.Shoff);
		shentsize = int(hdr.Shentsize);
		shnum = int(hdr.Shnum);
		shstrndx = int(hdr.Shstrndx);
	}

	// Read section headers
	e.Sections = make([]*Section, shnum);
	secNames := make([]uint32, shnum);
	for i := 0; i < shnum; i++ {
		off, err = r.Seek(start + shoff + int64(i*shentsize), 0);
		if err != nil {
			return nil, err;
		}

		br = newBinaryReader(r, e.data);
		switch e.class {
		case 32:
			panic("not reached");
		case 64:
			shdr := &elf64Shdr{};
			br.ReadAny(shdr);
			if err := br.Error(); err != nil {
				return nil, err;
			}

			s := &Section{
				r: r,
				offset: start + int64(shdr.Off),
				Size: shdr.Size,
				Addr: uint64(shdr.Addr),
			};
			secNames[i] = shdr.Name;
			e.Sections[i] = s;
		}
	}

	// Resolve section names
	off, err = r.Seek(start + e.Sections[shstrndx].offset, 0);
	if err != nil {
		return nil, err;
	}
	blob := make([]byte, e.Sections[shstrndx].Size);
	n, err = io.ReadFull(r, blob);

	for i, s := range e.Sections {
		var ok bool;
		s.Name, ok = getString(blob, int(secNames[i]));
		if !ok {
			return nil, &FormatError{start + shoff + int64(i*shentsize), "bad section name", secNames[i]};
		}
	}

	return e, nil;
}

// getString extracts a string from an ELF string table.
func getString(section []byte, index int) (string, bool) {
	if index < 0 || index >= len(section) {
		return "", false;
	}

	for end := index; end < len(section); end++ {
		if section[end] == 0 {
			return string(section[index:end]), true;
		}
	}
	return "", false;
}

// Section returns a section with the given name, or nil if no such
// section exists.
func (e *Elf) Section(name string) *Section {
	for _, s := range e.Sections {
		if s.Name == name {
			return s;
		}
	}
	return nil;
}

/*
 * Sections
 */

type subReader struct {
	r io.Reader;
	rem uint64;
}

func (r *subReader) Read(b []byte) (ret int, err os.Error) {
	if r.rem == 0 {
		return 0, os.EOF;
	}
	if uint64(len(b)) > r.rem {
		b = b[0:r.rem];
	}
	ret, err = r.r.Read(b);
	r.rem -= uint64(ret);
	if err == os.EOF {
		err = io.ErrUnexpectedEOF;
	}
	return ret, err;
}

// Open returns a reader backed by the data in this section.
// The original ELF file must still be open for this to work.
// The returned reader assumes there will be no seeks on the
// underlying file or any other opened section between the Open call
// and the last call to Read.
func (s *Section) Open() (io.Reader, os.Error) {
	_, err := s.r.Seek(s.offset, 0);
	if err != nil {
		return nil, err;
	}
	return &subReader{s.r, s.Size}, nil;
}
<|endoftext|>


<commit_before>// Package stream encapsulates streams within streams
package stream

import (
	"context"
	"sync"

	"github.com/micro/go-micro/client"
	"github.com/micro/go-micro/codec"
	"github.com/micro/go-micro/metadata"
	"github.com/micro/go-micro/server"
)

type Stream interface {
	Context() context.Context
	SendMsg(interface{}) error
	RecvMsg(interface{}) error
	Close() error
}

type stream struct {
	Stream

	sync.RWMutex
	err     error
	request *request
}

type request struct {
	client.Request
	context context.Context
}

func (r *request) Codec() codec.Reader {
	return r.Request.Codec().(codec.Reader)
}

func (r *request) Header() map[string]string {
	md, _ := metadata.FromContext(r.context)
	return md
}

func (r *request) Read() ([]byte, error) {
	return nil, nil
}

func (s *stream) Request() server.Request {
	return s.request
}

func (s *stream) Send(v interface{}) error {
	err := s.Stream.SendMsg(v)
	if err != nil {
		s.Lock()
		s.err = err
		s.Unlock()
	}
	return err
}

func (s *stream) Recv(v interface{}) error {
	err := s.Stream.RecvMsg(v)
	if err != nil {
		s.Lock()
		s.err = err
		s.Unlock()
	}
	return err
}

func (s *stream) Error() error {
	s.RLock()
	defer s.RUnlock()
	return s.err
}

// New returns a new encapsulated stream
// Proto stream within a server.Stream
func New(service, endpoint string, req interface{}, s Stream) server.Stream {
	return &stream{
		Stream: s,
		request: &request{
			context: s.Context(),
			Request: client.DefaultClient.NewRequest(service, endpoint, req),
		},
	}
}
<commit_msg>util/stream: fix imports (#1310)<commit_after>// Package stream encapsulates streams within streams
package stream

import (
	"context"
	"sync"

	"github.com/micro/go-micro/v2/client"
	"github.com/micro/go-micro/v2/codec"
	"github.com/micro/go-micro/v2/metadata"
	"github.com/micro/go-micro/v2/server"
)

type Stream interface {
	Context() context.Context
	SendMsg(interface{}) error
	RecvMsg(interface{}) error
	Close() error
}

type stream struct {
	Stream

	sync.RWMutex
	err     error
	request *request
}

type request struct {
	client.Request
	context context.Context
}

func (r *request) Codec() codec.Reader {
	return r.Request.Codec().(codec.Reader)
}

func (r *request) Header() map[string]string {
	md, _ := metadata.FromContext(r.context)
	return md
}

func (r *request) Read() ([]byte, error) {
	return nil, nil
}

func (s *stream) Request() server.Request {
	return s.request
}

func (s *stream) Send(v interface{}) error {
	err := s.Stream.SendMsg(v)
	if err != nil {
		s.Lock()
		s.err = err
		s.Unlock()
	}
	return err
}

func (s *stream) Recv(v interface{}) error {
	err := s.Stream.RecvMsg(v)
	if err != nil {
		s.Lock()
		s.err = err
		s.Unlock()
	}
	return err
}

func (s *stream) Error() error {
	s.RLock()
	defer s.RUnlock()
	return s.err
}

// New returns a new encapsulated stream
// Proto stream within a server.Stream
func New(service, endpoint string, req interface{}, s Stream) server.Stream {
	return &stream{
		Stream: s,
		request: &request{
			context: s.Context(),
			Request: client.DefaultClient.NewRequest(service, endpoint, req),
		},
	}
}
<|endoftext|>


<commit_before>package http

import (
	"encoding/json"
	"net/http"
	"time"

	"github.com/rusenask/keel/types"

	log "github.com/Sirupsen/logrus"
)

// nativeHandler - used to trigger event directly
func (s *TriggerServer) nativeHandler(resp http.ResponseWriter, req *http.Request) {
	event := types.Event{}
	if err := json.NewDecoder(req.Body).Decode(&event); err != nil {
		log.WithFields(log.Fields{
			"error": err,
		}).Error("failed to decode request")
		resp.WriteHeader(http.StatusBadRequest)
		return
	}
	event.CreatedAt = time.Now()

	for _, p := range s.providers {
		err := p.Submit(event)
		if err != nil {
			log.WithFields(log.Fields{
				"error":    err,
				"provider": p.GetName(),
			}).Error("trigger.webhook: got error while submitting event to provider")
		}
	}

	resp.WriteHeader(http.StatusOK)
	return
}
<commit_msg>check repo name and tag<commit_after>package http

import (
	"encoding/json"
	"fmt"
	"net/http"
	"time"

	"github.com/rusenask/keel/types"

	log "github.com/Sirupsen/logrus"
)

// nativeHandler - used to trigger event directly
func (s *TriggerServer) nativeHandler(resp http.ResponseWriter, req *http.Request) {
	event := types.Event{}
	if err := json.NewDecoder(req.Body).Decode(&event); err != nil {
		log.WithFields(log.Fields{
			"error": err,
		}).Error("failed to decode request")
		resp.WriteHeader(http.StatusBadRequest)
		return
	}

	if event.Repository.Name == "" {
		resp.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(resp, "repository name cannot be empty")
		return
	}

	if event.Repository.Tag == "" {
		resp.WriteHeader(http.StatusBadRequest)
		fmt.Fprintf(resp, "repository tag cannot be empty")
		return
	}

	event.CreatedAt = time.Now()

	for _, p := range s.providers {
		err := p.Submit(event)
		if err != nil {
			log.WithFields(log.Fields{
				"error":    err,
				"provider": p.GetName(),
			}).Error("trigger.webhook: got error while submitting event to provider")
		}
	}

	resp.WriteHeader(http.StatusOK)
	return
}
<|endoftext|>


<commit_before>package rock7

type Message struct{}

func parseMessage() *Message {
	return nil
}
<commit_msg>Remove old file<commit_after><|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 nodetasks

import (
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
	"path"
	"reflect"
	"strings"
	"sync"

	"k8s.io/klog"
	"k8s.io/kops/upup/pkg/fi"
	"k8s.io/kops/upup/pkg/fi/nodeup/cloudinit"
	"k8s.io/kops/upup/pkg/fi/nodeup/local"
	"k8s.io/kops/upup/pkg/fi/nodeup/tags"
	"k8s.io/kops/util/pkg/hashing"
)

type Package struct {
	Name string

	Version      *string `json:"version,omitempty"`
	Source       *string `json:"source,omitempty"`
	Hash         *string `json:"hash,omitempty"`
	PreventStart *bool   `json:"preventStart,omitempty"`

	// Healthy is true if the package installation did not fail
	Healthy *bool `json:"healthy,omitempty"`

	// Additional dependencies that must be installed before this package.
	// These will actually be passed together with this package to rpm/dpkg,
	// which will then figure out the correct order in which to install them.
	// This means that Deps don't get installed unless this package needs to
	// get installed.
	Deps []*Package `json:"deps,omitempty"`
}

const (
	localPackageDir             = "/var/cache/nodeup/packages/"
	containerSelinuxPackageName = "container-selinux"
	containerdPackageName       = "containerd.io"
	dockerPackageName           = "docker-ce"
)

var _ fi.HasDependencies = &Package{}

// GetDependencies computes dependencies for the package task
func (e *Package) GetDependencies(tasks map[string]fi.Task) []fi.Task {
	var deps []fi.Task

	// UpdatePackages before we install any packages
	for _, v := range tasks {
		if _, ok := v.(*UpdatePackages); ok {
			deps = append(deps, v)
		}
	}

	// If this package is a bare deb, install it after OS managed packages
	if !e.isOSPackage() {
		for _, v := range tasks {
			if vp, ok := v.(*Package); ok {
				if vp.isOSPackage() {
					deps = append(deps, v)
				}
			}
		}
	}

	// containerd should wait for container-selinux to be installed
	if e.Name == containerdPackageName {
		for _, v := range tasks {
			if vp, ok := v.(*Package); ok {
				if vp.Name == containerSelinuxPackageName {
					deps = append(deps, v)
				}
			}
		}
	}

	// Docker should wait for container-selinux and containerd to be installed
	if e.Name == dockerPackageName {
		for _, v := range tasks {
			if vp, ok := v.(*Package); ok {
				if vp.Name == containerSelinuxPackageName {
					deps = append(deps, v)
				}
				if vp.Name == containerdPackageName {
					deps = append(deps, v)
				}
			}
		}
	}

	return deps
}

var _ fi.HasName = &Package{}

func (f *Package) GetName() *string {
	return &f.Name
}

func (f *Package) SetName(name string) {
	f.Name = name
}

// isOSPackage returns true if this is an OS provided package (as opposed to a bare .deb, for example)
func (p *Package) isOSPackage() bool {
	return fi.StringValue(p.Source) == ""
}

// String returns a string representation, implementing the Stringer interface
func (p *Package) String() string {
	return fmt.Sprintf("Package: %s", p.Name)
}

func NewPackage(name string, contents string, meta string) (fi.Task, error) {
	p := &Package{Name: name}
	if contents != "" {
		err := json.Unmarshal([]byte(contents), p)
		if err != nil {
			return nil, fmt.Errorf("error parsing json for package %q: %v", name, err)
		}
	}

	// Default values: we want to install a package so that it is healthy
	if p.Healthy == nil {
		p.Healthy = fi.Bool(true)
	}

	return p, nil
}

func (e *Package) Find(c *fi.Context) (*Package, error) {
	target := c.Target.(*local.LocalTarget)

	if target.HasTag(tags.TagOSFamilyDebian) {
		return e.findDpkg(c)
	}

	if target.HasTag(tags.TagOSFamilyRHEL) {
		return e.findYum(c)
	}

	return nil, fmt.Errorf("unsupported package system")
}

func (e *Package) findDpkg(c *fi.Context) (*Package, error) {
	args := []string{"dpkg-query", "-f", "${db:Status-Abbrev}${Version}\\n", "-W", e.Name}
	human := strings.Join(args, " ")

	klog.V(2).Infof("Listing installed packages: %s", human)
	cmd := exec.Command(args[0], args[1:]...)
	output, err := cmd.CombinedOutput()
	if err != nil {
		if strings.Contains(string(output), "no packages found") {
			return nil, nil
		}
		return nil, fmt.Errorf("error listing installed packages: %v: %s", err, string(output))
	}

	installed := false
	var healthy *bool
	installedVersion := ""
	for _, line := range strings.Split(string(output), "\n") {
		if line == "" {
			continue
		}

		tokens := strings.Split(line, " ")
		if len(tokens) != 2 {
			return nil, fmt.Errorf("error parsing dpkg-query line %q", line)
		}
		state := tokens[0]
		version := tokens[1]

		switch state {
		case "ii":
			installed = true
			installedVersion = version
			healthy = fi.Bool(true)
		case "iF", "iU":
			installed = true
			installedVersion = version
			healthy = fi.Bool(false)
		case "rc":
			// removed
			installed = false
		case "un":
			// unknown
			installed = false
		case "n":
			// not installed
			installed = false
		default:
			klog.Warningf("unknown package state %q for %q in line %q", state, e.Name, line)
			return nil, fmt.Errorf("unknown package state %q for %q in line %q", state, e.Name, line)
		}
	}

	target := c.Target.(*local.LocalTarget)
	updates := target.HasTag(tags.TagUpdatePolicyAuto)
	if updates || !installed {
		return nil, nil
	}

	return &Package{
		Name:    e.Name,
		Version: fi.String(installedVersion),
		Healthy: healthy,
	}, nil
}

func (e *Package) findYum(c *fi.Context) (*Package, error) {
	args := []string{"/usr/bin/rpm", "-q", e.Name, "--queryformat", "%{NAME} %{VERSION}"}
	human := strings.Join(args, " ")

	klog.V(2).Infof("Listing installed packages: %s", human)
	cmd := exec.Command(args[0], args[1:]...)
	output, err := cmd.CombinedOutput()
	if err != nil {
		if strings.Contains(string(output), "is not installed") {
			return nil, nil
		}
		return nil, fmt.Errorf("error listing installed packages: %v: %s", err, string(output))
	}

	installed := false
	var healthy *bool
	installedVersion := ""
	for _, line := range strings.Split(string(output), "\n") {
		if line == "" {
			continue
		}

		tokens := strings.Split(line, " ")
		if len(tokens) != 2 {
			return nil, fmt.Errorf("error parsing rpm line %q", line)
		}

		name := tokens[0]
		if name != e.Name {
			return nil, fmt.Errorf("error parsing rpm line %q", line)
		}
		installed = true
		installedVersion = tokens[1]
		// If we implement unhealthy; be sure to implement repair in Render
		healthy = fi.Bool(true)
	}

	target := c.Target.(*local.LocalTarget)
	updates := target.HasTag(tags.TagUpdatePolicyAuto)
	if updates || !installed {
		return nil, nil
	}

	return &Package{
		Name:    e.Name,
		Version: fi.String(installedVersion),
		Healthy: healthy,
	}, nil
}

func (e *Package) Run(c *fi.Context) error {
	return fi.DefaultDeltaRunMethod(e, c)
}

func (_ *Package) CheckChanges(a, e, changes *Package) error {
	return nil
}

// packageManagerLock is a simple lock that prevents concurrent package manager operations
// It just avoids unnecessary failures from running e.g. concurrent apt-get installs
var packageManagerLock sync.Mutex

func (_ *Package) RenderLocal(t *local.LocalTarget, a, e, changes *Package) error {
	packageManagerLock.Lock()
	defer packageManagerLock.Unlock()

	if a == nil || changes.Version != nil {
		klog.Infof("Installing package %q (dependencies: %v)", e.Name, e.Deps)
		var localPkgs []string

		if e.Source != nil {
			// Install a deb or rpm.
			err := os.MkdirAll(localPackageDir, 0755)
			if err != nil {
				return fmt.Errorf("error creating directories %q: %v", localPackageDir, err)
			}

			// Append file extension for local files
			var ext string
			if t.HasTag(tags.TagOSFamilyDebian) {
				ext = ".deb"
			} else if t.HasTag(tags.TagOSFamilyRHEL) {
				ext = ".rpm"
			} else {
				return fmt.Errorf("unsupported package system")
			}

			// Download all the debs/rpms.
			localPkgs = make([]string, 1+len(e.Deps))
			for i, pkg := range append([]*Package{e}, e.Deps...) {
				local := path.Join(localPackageDir, pkg.Name+ext)
				localPkgs[i] = local
				var hash *hashing.Hash
				if fi.StringValue(pkg.Hash) != "" {
					parsed, err := hashing.FromString(fi.StringValue(pkg.Hash))
					if err != nil {
						return fmt.Errorf("error parsing hash: %v", err)
					}
					hash = parsed
				}
				_, err = fi.DownloadURL(fi.StringValue(pkg.Source), local, hash)
				if err != nil {
					return err
				}
			}
		}

		var args []string
		env := os.Environ()
		if t.HasTag(tags.TagOSFamilyDebian) {
			args = []string{"apt-get", "install", "--yes", "--no-install-recommends"}
			env = append(env, "DEBIAN_FRONTEND=noninteractive")
		} else if t.HasTag(tags.TagOSFamilyRHEL) {
			if t.HasTag(tags.TagOSCentOS8) || t.HasTag(tags.TagOSRHEL8) {
				args = []string{"/usr/bin/dnf", "install", "-y", "--setopt=install_weak_deps=False"}
			} else {
				args = []string{"/usr/bin/yum", "install", "-y"}
			}
		} else {
			return fmt.Errorf("unsupported package system")
		}
		args = append(args, localPkgs...)

		klog.Infof("running command %s", args)
		cmd := exec.Command(args[0], args[1:]...)
		cmd.Env = env
		output, err := cmd.CombinedOutput()
		if err != nil {
			return fmt.Errorf("error installing package %q: %v: %s", e.Name, err, string(output))
		}
	} else {
		if changes.Healthy != nil {
			if t.HasTag(tags.TagOSFamilyDebian) {
				args := []string{"dpkg", "--configure", "-a"}
				klog.Infof("package is not healthy; running command %s", args)
				cmd := exec.Command(args[0], args[1:]...)
				output, err := cmd.CombinedOutput()
				if err != nil {
					return fmt.Errorf("error running `dpkg --configure -a`: %v: %s", err, string(output))
				}

				changes.Healthy = nil
			} else if t.HasTag(tags.TagOSFamilyRHEL) {
				// Not set on TagOSFamilyRHEL, we can't currently reach here anyway...
				return fmt.Errorf("package repair not supported on RHEL/CentOS")
			} else {
				return fmt.Errorf("unsupported package system")
			}
		}

		if !reflect.DeepEqual(changes, &Package{}) {
			klog.Warningf("cannot apply package changes for %q: %+v", e.Name, changes)
		}
	}

	return nil
}

func (_ *Package) RenderCloudInit(t *cloudinit.CloudInitTarget, a, e, changes *Package) error {
	packageName := e.Name
	if e.Source != nil {
		localFile := path.Join(localPackageDir, packageName)
		t.AddMkdirpCommand(localPackageDir, 0755)

		url := *e.Source
		t.AddDownloadCommand(cloudinit.Always, url, localFile)

		t.AddCommand(cloudinit.Always, "dpkg", "-i", localFile)
	} else {
		packageSpec := packageName
		if e.Version != nil {
			packageSpec += " " + *e.Version
		}
		t.Config.Packages = append(t.Config.Packages, packageSpec)
	}

	return nil
}
<commit_msg>Fix repo packages not being installed<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 nodetasks

import (
	"encoding/json"
	"fmt"
	"os"
	"os/exec"
	"path"
	"reflect"
	"strings"
	"sync"

	"k8s.io/klog"
	"k8s.io/kops/upup/pkg/fi"
	"k8s.io/kops/upup/pkg/fi/nodeup/cloudinit"
	"k8s.io/kops/upup/pkg/fi/nodeup/local"
	"k8s.io/kops/upup/pkg/fi/nodeup/tags"
	"k8s.io/kops/util/pkg/hashing"
)

type Package struct {
	Name string

	Version      *string `json:"version,omitempty"`
	Source       *string `json:"source,omitempty"`
	Hash         *string `json:"hash,omitempty"`
	PreventStart *bool   `json:"preventStart,omitempty"`

	// Healthy is true if the package installation did not fail
	Healthy *bool `json:"healthy,omitempty"`

	// Additional dependencies that must be installed before this package.
	// These will actually be passed together with this package to rpm/dpkg,
	// which will then figure out the correct order in which to install them.
	// This means that Deps don't get installed unless this package needs to
	// get installed.
	Deps []*Package `json:"deps,omitempty"`
}

const (
	localPackageDir             = "/var/cache/nodeup/packages/"
	containerSelinuxPackageName = "container-selinux"
	containerdPackageName       = "containerd.io"
	dockerPackageName           = "docker-ce"
)

var _ fi.HasDependencies = &Package{}

// GetDependencies computes dependencies for the package task
func (e *Package) GetDependencies(tasks map[string]fi.Task) []fi.Task {
	var deps []fi.Task

	// UpdatePackages before we install any packages
	for _, v := range tasks {
		if _, ok := v.(*UpdatePackages); ok {
			deps = append(deps, v)
		}
	}

	// If this package is a bare deb, install it after OS managed packages
	if !e.isOSPackage() {
		for _, v := range tasks {
			if vp, ok := v.(*Package); ok {
				if vp.isOSPackage() {
					deps = append(deps, v)
				}
			}
		}
	}

	// containerd should wait for container-selinux to be installed
	if e.Name == containerdPackageName {
		for _, v := range tasks {
			if vp, ok := v.(*Package); ok {
				if vp.Name == containerSelinuxPackageName {
					deps = append(deps, v)
				}
			}
		}
	}

	// Docker should wait for container-selinux and containerd to be installed
	if e.Name == dockerPackageName {
		for _, v := range tasks {
			if vp, ok := v.(*Package); ok {
				if vp.Name == containerSelinuxPackageName {
					deps = append(deps, v)
				}
				if vp.Name == containerdPackageName {
					deps = append(deps, v)
				}
			}
		}
	}

	return deps
}

var _ fi.HasName = &Package{}

func (f *Package) GetName() *string {
	return &f.Name
}

func (f *Package) SetName(name string) {
	f.Name = name
}

// isOSPackage returns true if this is an OS provided package (as opposed to a bare .deb, for example)
func (p *Package) isOSPackage() bool {
	return fi.StringValue(p.Source) == ""
}

// String returns a string representation, implementing the Stringer interface
func (p *Package) String() string {
	return fmt.Sprintf("Package: %s", p.Name)
}

func NewPackage(name string, contents string, meta string) (fi.Task, error) {
	p := &Package{Name: name}
	if contents != "" {
		err := json.Unmarshal([]byte(contents), p)
		if err != nil {
			return nil, fmt.Errorf("error parsing json for package %q: %v", name, err)
		}
	}

	// Default values: we want to install a package so that it is healthy
	if p.Healthy == nil {
		p.Healthy = fi.Bool(true)
	}

	return p, nil
}

func (e *Package) Find(c *fi.Context) (*Package, error) {
	target := c.Target.(*local.LocalTarget)

	if target.HasTag(tags.TagOSFamilyDebian) {
		return e.findDpkg(c)
	}

	if target.HasTag(tags.TagOSFamilyRHEL) {
		return e.findYum(c)
	}

	return nil, fmt.Errorf("unsupported package system")
}

func (e *Package) findDpkg(c *fi.Context) (*Package, error) {
	args := []string{"dpkg-query", "-f", "${db:Status-Abbrev}${Version}\\n", "-W", e.Name}
	human := strings.Join(args, " ")

	klog.V(2).Infof("Listing installed packages: %s", human)
	cmd := exec.Command(args[0], args[1:]...)
	output, err := cmd.CombinedOutput()
	if err != nil {
		if strings.Contains(string(output), "no packages found") {
			return nil, nil
		}
		return nil, fmt.Errorf("error listing installed packages: %v: %s", err, string(output))
	}

	installed := false
	var healthy *bool
	installedVersion := ""
	for _, line := range strings.Split(string(output), "\n") {
		if line == "" {
			continue
		}

		tokens := strings.Split(line, " ")
		if len(tokens) != 2 {
			return nil, fmt.Errorf("error parsing dpkg-query line %q", line)
		}
		state := tokens[0]
		version := tokens[1]

		switch state {
		case "ii":
			installed = true
			installedVersion = version
			healthy = fi.Bool(true)
		case "iF", "iU":
			installed = true
			installedVersion = version
			healthy = fi.Bool(false)
		case "rc":
			// removed
			installed = false
		case "un":
			// unknown
			installed = false
		case "n":
			// not installed
			installed = false
		default:
			klog.Warningf("unknown package state %q for %q in line %q", state, e.Name, line)
			return nil, fmt.Errorf("unknown package state %q for %q in line %q", state, e.Name, line)
		}
	}

	target := c.Target.(*local.LocalTarget)
	updates := target.HasTag(tags.TagUpdatePolicyAuto)
	if updates || !installed {
		return nil, nil
	}

	return &Package{
		Name:    e.Name,
		Version: fi.String(installedVersion),
		Healthy: healthy,
	}, nil
}

func (e *Package) findYum(c *fi.Context) (*Package, error) {
	args := []string{"/usr/bin/rpm", "-q", e.Name, "--queryformat", "%{NAME} %{VERSION}"}
	human := strings.Join(args, " ")

	klog.V(2).Infof("Listing installed packages: %s", human)
	cmd := exec.Command(args[0], args[1:]...)
	output, err := cmd.CombinedOutput()
	if err != nil {
		if strings.Contains(string(output), "is not installed") {
			return nil, nil
		}
		return nil, fmt.Errorf("error listing installed packages: %v: %s", err, string(output))
	}

	installed := false
	var healthy *bool
	installedVersion := ""
	for _, line := range strings.Split(string(output), "\n") {
		if line == "" {
			continue
		}

		tokens := strings.Split(line, " ")
		if len(tokens) != 2 {
			return nil, fmt.Errorf("error parsing rpm line %q", line)
		}

		name := tokens[0]
		if name != e.Name {
			return nil, fmt.Errorf("error parsing rpm line %q", line)
		}
		installed = true
		installedVersion = tokens[1]
		// If we implement unhealthy; be sure to implement repair in Render
		healthy = fi.Bool(true)
	}

	target := c.Target.(*local.LocalTarget)
	updates := target.HasTag(tags.TagUpdatePolicyAuto)
	if updates || !installed {
		return nil, nil
	}

	return &Package{
		Name:    e.Name,
		Version: fi.String(installedVersion),
		Healthy: healthy,
	}, nil
}

func (e *Package) Run(c *fi.Context) error {
	return fi.DefaultDeltaRunMethod(e, c)
}

func (_ *Package) CheckChanges(a, e, changes *Package) error {
	return nil
}

// packageManagerLock is a simple lock that prevents concurrent package manager operations
// It just avoids unnecessary failures from running e.g. concurrent apt-get installs
var packageManagerLock sync.Mutex

func (_ *Package) RenderLocal(t *local.LocalTarget, a, e, changes *Package) error {
	packageManagerLock.Lock()
	defer packageManagerLock.Unlock()

	if a == nil || changes.Version != nil {
		klog.Infof("Installing package %q (dependencies: %v)", e.Name, e.Deps)
		var pkgs []string

		if e.Source != nil {
			// Install a deb or rpm.
			err := os.MkdirAll(localPackageDir, 0755)
			if err != nil {
				return fmt.Errorf("error creating directories %q: %v", localPackageDir, err)
			}

			// Append file extension for local files
			var ext string
			if t.HasTag(tags.TagOSFamilyDebian) {
				ext = ".deb"
			} else if t.HasTag(tags.TagOSFamilyRHEL) {
				ext = ".rpm"
			} else {
				return fmt.Errorf("unsupported package system")
			}

			// Download all the debs/rpms.
			pkgs = make([]string, 1+len(e.Deps))
			for i, pkg := range append([]*Package{e}, e.Deps...) {
				local := path.Join(localPackageDir, pkg.Name+ext)
				pkgs[i] = local
				var hash *hashing.Hash
				if fi.StringValue(pkg.Hash) != "" {
					parsed, err := hashing.FromString(fi.StringValue(pkg.Hash))
					if err != nil {
						return fmt.Errorf("error parsing hash: %v", err)
					}
					hash = parsed
				}
				_, err = fi.DownloadURL(fi.StringValue(pkg.Source), local, hash)
				if err != nil {
					return err
				}
			}
		} else {
			pkgs = append(pkgs, e.Name)
		}

		var args []string
		env := os.Environ()
		if t.HasTag(tags.TagOSFamilyDebian) {
			args = []string{"apt-get", "install", "--yes", "--no-install-recommends"}
			env = append(env, "DEBIAN_FRONTEND=noninteractive")
		} else if t.HasTag(tags.TagOSFamilyRHEL) {
			if t.HasTag(tags.TagOSCentOS8) || t.HasTag(tags.TagOSRHEL8) {
				args = []string{"/usr/bin/dnf", "install", "-y", "--setopt=install_weak_deps=False"}
			} else {
				args = []string{"/usr/bin/yum", "install", "-y"}
			}
		} else {
			return fmt.Errorf("unsupported package system")
		}
		args = append(args, pkgs...)

		klog.Infof("running command %s", args)
		cmd := exec.Command(args[0], args[1:]...)
		cmd.Env = env
		output, err := cmd.CombinedOutput()
		if err != nil {
			return fmt.Errorf("error installing package %q: %v: %s", e.Name, err, string(output))
		}
	} else {
		if changes.Healthy != nil {
			if t.HasTag(tags.TagOSFamilyDebian) {
				args := []string{"dpkg", "--configure", "-a"}
				klog.Infof("package is not healthy; running command %s", args)
				cmd := exec.Command(args[0], args[1:]...)
				output, err := cmd.CombinedOutput()
				if err != nil {
					return fmt.Errorf("error running `dpkg --configure -a`: %v: %s", err, string(output))
				}

				changes.Healthy = nil
			} else if t.HasTag(tags.TagOSFamilyRHEL) {
				// Not set on TagOSFamilyRHEL, we can't currently reach here anyway...
				return fmt.Errorf("package repair not supported on RHEL/CentOS")
			} else {
				return fmt.Errorf("unsupported package system")
			}
		}

		if !reflect.DeepEqual(changes, &Package{}) {
			klog.Warningf("cannot apply package changes for %q: %+v", e.Name, changes)
		}
	}

	return nil
}

func (_ *Package) RenderCloudInit(t *cloudinit.CloudInitTarget, a, e, changes *Package) error {
	packageName := e.Name
	if e.Source != nil {
		localFile := path.Join(localPackageDir, packageName)
		t.AddMkdirpCommand(localPackageDir, 0755)

		url := *e.Source
		t.AddDownloadCommand(cloudinit.Always, url, localFile)

		t.AddCommand(cloudinit.Always, "dpkg", "-i", localFile)
	} else {
		packageSpec := packageName
		if e.Version != nil {
			packageSpec += " " + *e.Version
		}
		t.Config.Packages = append(t.Config.Packages, packageSpec)
	}

	return nil
}
<|endoftext|>


<commit_before>/*
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 profiling

import (
	"net/http"
	"net/http/pprof"
	"strconv"
	"sync"

	perrors "github.com/pkg/errors"
	"go.uber.org/zap"
	corev1 "k8s.io/api/core/v1"
)

const (
	// profilingPort is the port where we expose profiling information if profiling is enabled
	profilingPort = ":8008"

	// profilingKey is the name of the key in config-observability config map that indicates whether profiling
	// is enabled of disabled
	profilingKey = "profiling.enable"
)

// Handler holds the main HTTP handler and a flag indicating
// whether the handler is active
type Handler struct {
	enabled    bool
	enabledMux sync.Mutex
	handler    http.Handler
	log        *zap.SugaredLogger
}

// NewHandler create a new ProfilingHandler which serves runtime profiling data
// according to the given context path
func NewHandler(logger *zap.SugaredLogger, enableProfiling bool) *Handler {
	const pprofPrefix = "/debug/pprof/"

	mux := http.NewServeMux()
	mux.HandleFunc(pprofPrefix, pprof.Index)
	mux.HandleFunc(pprofPrefix+"cmdline", pprof.Cmdline)
	mux.HandleFunc(pprofPrefix+"profile", pprof.Profile)
	mux.HandleFunc(pprofPrefix+"symbol", pprof.Symbol)
	mux.HandleFunc(pprofPrefix+"trace", pprof.Trace)

	logger.Infof("Profiling enabled: %t", enableProfiling)

	return &Handler{
		enabled: enableProfiling,
		handler: mux,
		log:     logger,
	}
}

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h.enabledMux.Lock()
	defer h.enabledMux.Unlock()
	if h.enabled {
		h.handler.ServeHTTP(w, r)
	} else {
		http.NotFoundHandler().ServeHTTP(w, r)
	}
}

func readProfilingFlag(configMap *corev1.ConfigMap) (bool, error) {
	profiling, ok := configMap.Data[profilingKey]
	if !ok {
		return false, nil
	}
	enabled, err := strconv.ParseBool(profiling)
	if err != nil {
		return false, perrors.Wrapf(err, "failed to parse the profiling flag")
	}
	return enabled, nil
}

// UpdateFromConfigMap modifies the Enabled flag in the Handler
// according to the value in the given ConfigMap
func (h *Handler) UpdateFromConfigMap(configMap *corev1.ConfigMap) {
	enabled, err := readProfilingFlag(configMap)
	if err != nil {
		h.log.Errorw("Failed to update the profiling flag", zap.Error(err))
		return
	}
	h.enabledMux.Lock()
	defer h.enabledMux.Unlock()
	if h.enabled != enabled {
		h.enabled = enabled
		h.log.Infof("Profiling enabled: %t", h.enabled)
	}
}

// NewServer creates a new http server that exposes profiling data using the
// HTTP handler that is passed as an argument
func NewServer(handler http.Handler) *http.Server {
	return &http.Server{
		Addr:    profilingPort,
		Handler: handler,
	}
}
<commit_msg>Define ProfilingPort and make profiling server use it (#599)<commit_after>/*
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 profiling

import (
	"net/http"
	"net/http/pprof"
	"strconv"
	"sync"

	perrors "github.com/pkg/errors"
	"go.uber.org/zap"
	corev1 "k8s.io/api/core/v1"
)

const (
	// ProfilingPort specifies the port where profiling data is available when profiling is enabled
	ProfilingPort = 8008

	// profilingKey is the name of the key in config-observability config map
	// that indicates whether profiling is enabled
	profilingKey = "profiling.enable"
)

// Handler holds the main HTTP handler and a flag indicating
// whether the handler is active
type Handler struct {
	enabled    bool
	enabledMux sync.Mutex
	handler    http.Handler
	log        *zap.SugaredLogger
}

// NewHandler create a new ProfilingHandler which serves runtime profiling data
// according to the given context path
func NewHandler(logger *zap.SugaredLogger, enableProfiling bool) *Handler {
	const pprofPrefix = "/debug/pprof/"

	mux := http.NewServeMux()
	mux.HandleFunc(pprofPrefix, pprof.Index)
	mux.HandleFunc(pprofPrefix+"cmdline", pprof.Cmdline)
	mux.HandleFunc(pprofPrefix+"profile", pprof.Profile)
	mux.HandleFunc(pprofPrefix+"symbol", pprof.Symbol)
	mux.HandleFunc(pprofPrefix+"trace", pprof.Trace)

	logger.Infof("Profiling enabled: %t", enableProfiling)

	return &Handler{
		enabled: enableProfiling,
		handler: mux,
		log:     logger,
	}
}

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	h.enabledMux.Lock()
	defer h.enabledMux.Unlock()
	if h.enabled {
		h.handler.ServeHTTP(w, r)
	} else {
		http.NotFoundHandler().ServeHTTP(w, r)
	}
}

func readProfilingFlag(configMap *corev1.ConfigMap) (bool, error) {
	profiling, ok := configMap.Data[profilingKey]
	if !ok {
		return false, nil
	}
	enabled, err := strconv.ParseBool(profiling)
	if err != nil {
		return false, perrors.Wrapf(err, "failed to parse the profiling flag")
	}
	return enabled, nil
}

// UpdateFromConfigMap modifies the Enabled flag in the Handler
// according to the value in the given ConfigMap
func (h *Handler) UpdateFromConfigMap(configMap *corev1.ConfigMap) {
	enabled, err := readProfilingFlag(configMap)
	if err != nil {
		h.log.Errorw("Failed to update the profiling flag", zap.Error(err))
		return
	}
	h.enabledMux.Lock()
	defer h.enabledMux.Unlock()
	if h.enabled != enabled {
		h.enabled = enabled
		h.log.Infof("Profiling enabled: %t", h.enabled)
	}
}

// NewServer creates a new http server that exposes profiling data on the default profiling port
func NewServer(handler http.Handler) *http.Server {
	return &http.Server{
		Addr:    ":" + strconv.Itoa(ProfilingPort),
		Handler: handler,
	}
}
<|endoftext|>


<commit_before>package utils

import (
	"testing"
	"time"
)

func BenchmarkParseDate(t *testing.B) {
	var strdate = "104/04/01"
	for i := 0; i < t.N; i++ {
		ParseDate(strdate)
	}
}

func BenchmarkSumUint64(t *testing.B) {
	var sample = []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9}
	for i := 0; i < t.N; i++ {
		SumUint64(sample)
	}
}

func BenchmarkAvgUint64(t *testing.B) {
	var sample = []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9}
	for i := 0; i < t.N; i++ {
		AvgUint64(sample)
	}
}

func BenchmarkRanInt(t *testing.B) {
	for i := 0; i < t.N; i++ {
		RandInt()
	}
}

func BenchmarkSumFloat64(t *testing.B) {
	var sample = []float64{20.2, 20.3, 100.25, 100.75}
	for i := 0; i < t.N; i++ {
		SumFloat64(sample)
	}
}

func BenchmarkAvgFloat64(t *testing.B) {
	var sample = []float64{20.2, 20.3, 100.25, 100.75}
	for i := 0; i < t.N; i++ {
		AvgFloat64(sample)
	}
}

func BenchmarkThanPast(t *testing.B) {
	var sample = []float64{20.2, 20.3, 100.25, 100.75}
	for i := 0; i < t.N; i++ {
		thanPast(sample, true)
	}
}

func BenchmarkThanPast_false(t *testing.B) {
	var sample = []float64{20.2, 20.3, 100.25, 100.75}
	for i := 0; i < t.N; i++ {
		thanPast(sample, false)
	}
}

func BenchmarkThanPastFloat64(t *testing.B) {
	var sample = []float64{20.2, 20.3, 100.25, 100.75}
	for i := 0; i < t.N; i++ {
		ThanPastFloat64(sample, 3, true)
	}
}

func BenchmarkThanPastUint64(t *testing.B) {
	var sample = []uint64{20, 23, 125, 105}
	for i := 0; i < t.N; i++ {
		ThanPastUint64(sample, 3, true)
	}
}

func BenchmarkThanSumPastUint64(b *testing.B) {
	var sample = []uint64{10, 11, 12, 53}
	for i := 0; i < b.N; i++ {
		ThanSumPastUint64(sample, 3, true)
	}
}

func BenchmarkThanSumPast(b *testing.B) {
	var sample = []float64{10.1, 11.1, 12.1, 53.1}
	for i := 0; i < b.N; i++ {
		thanSumPast(sample, true)
	}
}

func TestRanInt(t *testing.T) {
	if (RandInt() - RandInt() + RandInt() - RandInt()) == 0 {
		t.Error("Should not be the same.")
	}
}

func TestParseDate(t *testing.T) {
	var sample1 = "104/2/28"
	if ParseDate(sample1) != time.Date(2015, 2, 28, 0, 0, 0, 0, TaipeiTimeZone) {
		t.Error("Should be 2015/2/28")
	}
	var sample2 = "104/2/29"
	if ParseDate(sample2) != time.Date(2015, 3, 1, 0, 0, 0, 0, TaipeiTimeZone) {
		t.Error("Should be 2015/3/1")
	}
	var sample3 = "104/4/31"
	if ParseDate(sample3) != time.Date(2015, 5, 1, 0, 0, 0, 0, TaipeiTimeZone) {
		t.Error("Should be 2015/5/1")
	}
}

func TestAvg(t *testing.T) {
	var sample1 = []float64{3.3, 6.6, 9.9}
	if AvgFloat64(sample1) != 6.59 {
		t.Error("Should be 6.59")
	}
	var sample2 = []uint64{3, 6, 9}
	if AvgUint64(sample2) != 6 {
		t.Error("Should be 6")
	}
}

func TestSum(t *testing.T) {
	var sample1 = []float64{1.1, 2.2, 3.3}
	if SumFloat64(sample1) != 6.6 {
		t.Error("Should be 6.6")
	}
	var sample2 = []uint64{1, 2, 3}
	if SumUint64(sample2) != 6 {
		t.Error("Should be 6")
	}
}

func TestThanPast(t *testing.T) {
	var sample1 = []float64{10.1, 11.1, 12.1, 13.1}
	if !ThanPastFloat64(sample1, 3, true) {
		t.Error("Should be `true`")
	}
	var sample2 = []float64{10.1, 11.1, 12.1, 9.1}
	if !ThanPastFloat64(sample2, 3, false) {
		t.Error("Should be `true`")
	}
	if ThanPastFloat64(sample2, 3, true) {
		t.Error("Should be `false`")
	}
	var sample3 = []uint64{10, 11, 12, 13}
	if !ThanPastUint64(sample3, 3, true) {
		t.Error("Should be `true`")
	}
	var sample4 = []uint64{10, 11, 12, 9}
	if !ThanPastUint64(sample4, 3, false) {
		t.Error("Should be `true`")
	}
}

func TestThanSumPast(t *testing.T) {
	var sample1 = []float64{10.1, 11.1, 12.1, 53.1}
	if !ThanSumPastFloat64(sample1, 3, true) {
		t.Error("Should be `true`")
	}
	var sample2 = []float64{10.1, 11.1, 12.1, 10.1}
	if !ThanSumPastFloat64(sample2, 3, false) {
		t.Error("Should be `true`")
	}
	var sample3 = []uint64{10, 11, 12, 53}
	if !ThanSumPastUint64(sample3, 3, true) {
		t.Error("Should be `true`")
	}
	var sample4 = []uint64{10, 11, 12, 10}
	if !ThanSumPastUint64(sample4, 3, false) {
		t.Error("Should be `true`")
	}
}

func BenchmarkCountCountine(b *testing.B) {
	var sample1 = []float64{10.1, 11.1, 12.1, 53.1}
	for i := 0; i < b.N; i++ {
		CountCountineFloat64(sample1)
	}
}

func TestCountCountine(t *testing.T) {
	var sample1 = []float64{10.1, 11.1, 12.1, 53.1}  // 4 true
	var sample2 = []float64{10.1, 11.1, -12.1, 53.1} // 1 true
	var sample3 = []float64{10.1, 11.1, 12.1, -53.1} // 1 false
	if times, max := CountCountineFloat64(sample1); times != 4 && max != true {
		t.Error("Should be `4 true`")
	}
	if times, max := CountCountineFloat64(sample2); times != 1 && max != true {
		t.Error("Should be `1 true`")
	}
	if times, max := CountCountineFloat64(sample3); times != 1 && max != false {
		t.Error("Should be `1 false`")
	}
}

func TestCalDiff(t *testing.T) {
	var sampleA = []float64{10.0, 11.1, 12.2, 13.3}
	var sampleB = []float64{12.2, 11.1, 10.0}
	var result = CalDiffFloat64(sampleA, sampleB)
	if result[2] != float64(13.3)-float64(10.0) {
		t.Error("Wrong cal.")
	}
	result = CalDiffFloat64(sampleB, sampleA)
	if result[2] != float64(10.0)-float64(13.3) {
		t.Error("Wrong cal.")
	}

	var sampleC = []int64{10, 11, 12, 13}
	var sampleD = []int64{12, 11, 10}
	var result2 = CalDiffInt64(sampleC, sampleD)
	if result2[2] != 13-10 {
		t.Error("Wrong cal.")
	}
	result2 = CalDiffInt64(sampleD, sampleC)
	if result2[2] != 10-13 {
		t.Error("Wrong cal.")
	}
}

func TestDelta(t *testing.T) {
	var sample1 = []float64{10.0, 11.0, 9.0}
	var sample2 = []float64{10, 11, 9}
	t.Log(DeltaFloat64(sample1))
	t.Log(DeltaFloat64(sample2))
}

func BenchmarkDeltafloat64(b *testing.B) {
	var sample = []float64{10.0, 11.0, 9.0}
	for i := 0; i < b.N; i++ {
		DeltaFloat64(sample)
	}
}

func BenchmarkDeltaInt64(b *testing.B) {
	var sample = []int64{10, 11, 9}
	for i := 0; i < b.N; i++ {
		DeltaInt64(sample)
	}
}

func BenchmarkCalDiff(b *testing.B) {
	var sampleA = []float64{10.0, 11.1, 12.2, 13.3}
	var sampleB = []float64{12.2, 11.1, 10.0}
	for i := 0; i < b.N; i++ {
		CalDiffFloat64(sampleA, sampleB)
	}
}

func TestSD(t *testing.T) {
	var sample = []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

	if SD(sample) != 2.8722813232690143 {
		t.Error("Should be 2.8722813232690143")
	}
}

func BenchmarkSD(b *testing.B) {
	var sample = []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	for i := 0; i < b.N; i++ {
		SD(sample)
	}
}
<commit_msg>Fixed testing.<commit_after>package utils

import (
	"testing"
	"time"
)

func BenchmarkParseDate(t *testing.B) {
	var strdate = "104/04/01"
	for i := 0; i < t.N; i++ {
		ParseDate(strdate)
	}
}

func BenchmarkSumUint64(t *testing.B) {
	var sample = []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9}
	for i := 0; i < t.N; i++ {
		SumUint64(sample)
	}
}

func BenchmarkAvgUint64(t *testing.B) {
	var sample = []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9}
	for i := 0; i < t.N; i++ {
		AvgUint64(sample)
	}
}

func BenchmarkRanInt(t *testing.B) {
	for i := 0; i < t.N; i++ {
		RandInt()
	}
}

func BenchmarkSumFloat64(t *testing.B) {
	var sample = []float64{20.2, 20.3, 100.25, 100.75}
	for i := 0; i < t.N; i++ {
		SumFloat64(sample)
	}
}

func BenchmarkAvgFloat64(t *testing.B) {
	var sample = []float64{20.2, 20.3, 100.25, 100.75}
	for i := 0; i < t.N; i++ {
		AvgFloat64(sample)
	}
}

func BenchmarkThanPast(t *testing.B) {
	var sample = []float64{20.2, 20.3, 100.25, 100.75}
	for i := 0; i < t.N; i++ {
		thanPast(sample, true)
	}
}

func BenchmarkThanPast_false(t *testing.B) {
	var sample = []float64{20.2, 20.3, 100.25, 100.75}
	for i := 0; i < t.N; i++ {
		thanPast(sample, false)
	}
}

func BenchmarkThanPastFloat64(t *testing.B) {
	var sample = []float64{20.2, 20.3, 100.25, 100.75}
	for i := 0; i < t.N; i++ {
		ThanPastFloat64(sample, 3, true)
	}
}

func BenchmarkThanPastUint64(t *testing.B) {
	var sample = []uint64{20, 23, 125, 105}
	for i := 0; i < t.N; i++ {
		ThanPastUint64(sample, 3, true)
	}
}

func BenchmarkThanSumPastUint64(b *testing.B) {
	var sample = []uint64{10, 11, 12, 53}
	for i := 0; i < b.N; i++ {
		ThanSumPastUint64(sample, 3, true)
	}
}

func BenchmarkThanSumPast(b *testing.B) {
	var sample = []float64{10.1, 11.1, 12.1, 53.1}
	for i := 0; i < b.N; i++ {
		thanSumPast(sample, true)
	}
}

func TestRanInt(t *testing.T) {
	if (RandInt() - RandInt() + RandInt() - RandInt()) == 0 {
		t.Error("Should not be the same.")
	}
}

func TestParseDate(t *testing.T) {
	var sample1 = "104/2/28"
	if ParseDate(sample1) != time.Date(2015, 2, 28, 0, 0, 0, 0, TaipeiTimeZone) {
		t.Error("Should be 2015/2/28")
	}
	var sample2 = "104/2/29"
	if ParseDate(sample2) != time.Date(2015, 3, 1, 0, 0, 0, 0, TaipeiTimeZone) {
		t.Error("Should be 2015/3/1")
	}
	var sample3 = "104/4/31"
	if ParseDate(sample3) != time.Date(2015, 5, 1, 0, 0, 0, 0, TaipeiTimeZone) {
		t.Error("Should be 2015/5/1")
	}
}

func TestAvg(t *testing.T) {
	var sample1 = []float64{3.3, 6.6, 9.9}
	if AvgFloat64(sample1) != 6.59 {
		t.Error("Should be 6.59")
	}
	var sample2 = []uint64{3, 6, 9}
	if AvgUint64(sample2) != 6 {
		t.Error("Should be 6")
	}
}

func TestSum(t *testing.T) {
	var sample1 = []float64{1.1, 2.2, 3.3}
	if SumFloat64(sample1) != 6.6 {
		t.Error("Should be 6.6")
	}
	var sample2 = []uint64{1, 2, 3}
	if SumUint64(sample2) != 6 {
		t.Error("Should be 6")
	}
}

func TestThanPast(t *testing.T) {
	var sample1 = []float64{10.1, 11.1, 12.1, 13.1}
	if !ThanPastFloat64(sample1, 3, true) {
		t.Error("Should be `true`")
	}
	var sample2 = []float64{10.1, 11.1, 12.1, 9.1}
	if !ThanPastFloat64(sample2, 3, false) {
		t.Error("Should be `true`")
	}
	if ThanPastFloat64(sample2, 3, true) {
		t.Error("Should be `false`")
	}
	var sample3 = []uint64{10, 11, 12, 13}
	if !ThanPastUint64(sample3, 3, true) {
		t.Error("Should be `true`")
	}
	var sample4 = []uint64{10, 11, 12, 9}
	if !ThanPastUint64(sample4, 3, false) {
		t.Error("Should be `true`")
	}
}

func TestThanSumPast(t *testing.T) {
	var sample1 = []float64{10.1, 11.1, 12.1, 53.1}
	if !ThanSumPastFloat64(sample1, 3, true) {
		t.Error("Should be `true`")
	}
	var sample2 = []float64{10.1, 11.1, 12.1, 10.1}
	if !ThanSumPastFloat64(sample2, 3, false) {
		t.Error("Should be `true`")
	}
	var sample3 = []uint64{10, 11, 12, 53}
	if !ThanSumPastUint64(sample3, 3, true) {
		t.Error("Should be `true`")
	}
	var sample4 = []uint64{10, 11, 12, 10}
	if !ThanSumPastUint64(sample4, 3, false) {
		t.Error("Should be `true`")
	}
}

func BenchmarkCountCountine(b *testing.B) {
	var sample1 = []float64{10.1, 11.1, 12.1, 53.1}
	for i := 0; i < b.N; i++ {
		CountCountineFloat64(sample1)
	}
}

func TestCountCountine(t *testing.T) {
	var sample1 = []float64{10.1, 11.1, 12.1, 53.1}  // 4 true
	var sample2 = []float64{10.1, 11.1, -12.1, 53.1} // 1 true
	var sample3 = []float64{10.1, 11.1, 12.1, -53.1} // 1 false
	if times, max := CountCountineFloat64(sample1); times != 4 && max != true {
		t.Error("Should be `4 true`")
	}
	if times, max := CountCountineFloat64(sample2); times != 1 && max != true {
		t.Error("Should be `1 true`")
	}
	if times, max := CountCountineFloat64(sample3); times != 1 && max != false {
		t.Error("Should be `1 false`")
	}
}

func TestCalDiff(t *testing.T) {
	var sampleA = []float64{10.0, 11.1, 12.2, 13.3}
	var sampleB = []float64{12.2, 11.1, 10.0}
	var result = CalDiffFloat64(sampleA, sampleB)
	if result[2] != float64(13.3)-float64(10.0) {
		t.Error("Wrong cal.")
	}
	result = CalDiffFloat64(sampleB, sampleA)
	if result[2] != float64(10.0)-float64(13.3) {
		t.Error("Wrong cal.")
	}

	var sampleC = []int64{10, 11, 12, 13}
	var sampleD = []int64{12, 11, 10}
	var result2 = CalDiffInt64(sampleC, sampleD)
	if result2[2] != 13-10 {
		t.Error("Wrong cal.")
	}
	result2 = CalDiffInt64(sampleD, sampleC)
	if result2[2] != 10-13 {
		t.Error("Wrong cal.")
	}
}

func TestDelta(t *testing.T) {
	var sample1 = []float64{10.0, 11.0, 9.0}
	var sample2 = []int64{10, 11, 9}
	t.Log(DeltaFloat64(sample1))
	t.Log(DeltaInt64(sample2))
}

func BenchmarkDeltafloat64(b *testing.B) {
	var sample = []float64{10.0, 11.0, 9.0}
	for i := 0; i < b.N; i++ {
		DeltaFloat64(sample)
	}
}

func BenchmarkDeltaInt64(b *testing.B) {
	var sample = []int64{10, 11, 9}
	for i := 0; i < b.N; i++ {
		DeltaInt64(sample)
	}
}

func BenchmarkCalDiff(b *testing.B) {
	var sampleA = []float64{10.0, 11.1, 12.2, 13.3}
	var sampleB = []float64{12.2, 11.1, 10.0}
	for i := 0; i < b.N; i++ {
		CalDiffFloat64(sampleA, sampleB)
	}
}

func TestSD(t *testing.T) {
	var sample = []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}

	if SD(sample) != 2.8722813232690143 {
		t.Error("Should be 2.8722813232690143")
	}
}

func BenchmarkSD(b *testing.B) {
	var sample = []uint64{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
	for i := 0; i < b.N; i++ {
		SD(sample)
	}
}
<|endoftext|>


<commit_before>package utils

import (
	"path"
	"strings"
	"testing"
)

func TestToLines(t *testing.T) {
	t.Log(strings.Join(ToLines("abc\n123\rdef\r\r\n465\r\n\n\r\r\n789\n\r\n"), "\n"))
}

func TestPathClean(t *testing.T) {
	for _, p := range []string{
		"",
		".",
		"a.",
		"/",
		"./",
		"/.",
		"./.",
		"a/c",
		"a//c",
		"a/c/.",
		"a/c/b/..",
		"/../a/c",
		"/../a/b/../././/c",
		"  /a/c/b/  ",
		"E:\\One\\Design\\Photos\\DSC_123.JPG",
	} {
		cp := PathClean(p, true)
		t.Logf("%s -> %s (%v)", p, cp, cp == path.Clean(strings.Replace(strings.ToLower(strings.TrimSpace(p)), "\\", "/", -1)))
	}
}
<commit_msg>improve testing<commit_after>package utils

import (
	"path"
	"strings"
	"testing"
)

func TestParseLines(t *testing.T) {
	t.Log(strings.Join(ParseLines("abc\n123\rdef\r\r\n465\r\n\n\r\r\n789\n\r\n", true), "|"))
}

func TestPathClean(t *testing.T) {
	for _, p := range []string{
		"",
		".",
		"a.",
		"/",
		"./",
		"/.",
		"./.",
		"a/c",
		"a//c",
		"a/c/.",
		"a/c/b/..",
		"/../a/c",
		"/../a/b/../././/c",
		"/../a/../abc/123///ccc/../b/../././/c",
		"  /a/c/b/  ",
		"E:\\One\\Design\\Photos\\DSC_123.JPG",
	} {
		cp := CleanPath(p, true)
		cp2 := path.Clean(strings.Replace(strings.ToLower(strings.TrimSpace(p)), "\\", "/", -1))
		if cp != cp2 {
			t.Fatalf("%s -> %s (%v), should be %s", p, cp, cp == cp2, cp2)
		}
	}
}

func TestGetLocalIps(t *testing.T) {
	t.Log(GetLocalIps())
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/realglobe-Inc/go-lib-rg/erro"
	"net/http"
	"strings"
)

// ブラウザからのリクエスト。
type browserRequest struct {
	sess string
}

func newBrowserRequest(r *http.Request) *browserRequest {
	var sess string
	if cook, err := r.Cookie(cookSess); err != nil {
		if err != http.ErrNoCookie {
			err = erro.Wrap(err)
			log.Err(erro.Unwrap(err))
			log.Debug(err)
		}
	} else {
		sess = cook.Value
	}
	return &browserRequest{sess: sess}
}

func (this *browserRequest) session() string {
	return this.sess
}

// スペース区切りのフォーム値を集合にして返す。
func formValueSet(r *http.Request, key string) map[string]bool {
	s := r.FormValue(key)
	set := map[string]bool{}
	for _, v := range strings.Split(s, " ") {
		set[v] = true
	}
	return set
}

// フォーム値用にスペース区切りにして返す。
func valueSetToForm(v map[string]bool) string {
	buff := ""
	for v, ok := range v {
		if !ok || v == "" {
			continue
		}

		if len(buff) > 0 {
			buff += " "
		}
		buff += v
	}
	return buff
}
<commit_msg>スペース区切りのパラメータ値のデコードにおける空文字列に対する処理を修正<commit_after>package main

import (
	"github.com/realglobe-Inc/go-lib-rg/erro"
	"net/http"
	"strings"
)

// ブラウザからのリクエスト。
type browserRequest struct {
	sess string
}

func newBrowserRequest(r *http.Request) *browserRequest {
	var sess string
	if cook, err := r.Cookie(cookSess); err != nil {
		if err != http.ErrNoCookie {
			err = erro.Wrap(err)
			log.Err(erro.Unwrap(err))
			log.Debug(err)
		}
	} else {
		sess = cook.Value
	}
	return &browserRequest{sess: sess}
}

func (this *browserRequest) session() string {
	return this.sess
}

// スペース区切りのフォーム値を集合にして返す。
func formValueSet(r *http.Request, key string) map[string]bool {
	set := map[string]bool{}
	s := r.FormValue(key)
	if s == "" {
		return set
	}
	for _, v := range strings.Split(s, " ") {
		set[v] = true
	}
	return set
}

// フォーム値用にスペース区切りにして返す。
func valueSetToForm(v map[string]bool) string {
	buff := ""
	for v, ok := range v {
		if !ok || v == "" {
			continue
		}

		if len(buff) > 0 {
			buff += " "
		}
		buff += v
	}
	return buff
}
<|endoftext|>