<commit_before>package daemon

import (
	"encoding/json"
	"fmt"
	"io"
	"runtime"
	"strings"
	"time"

	"github.com/docker/docker/api/types/backend"
	containertypes "github.com/docker/docker/api/types/container"
	"github.com/docker/docker/builder/dockerfile"
	"github.com/docker/docker/container"
	"github.com/docker/docker/dockerversion"
	"github.com/docker/docker/image"
	"github.com/docker/docker/layer"
	"github.com/docker/docker/pkg/ioutils"
	"github.com/docker/docker/reference"
	"github.com/docker/go-connections/nat"
)

// merge merges two Config, the image container configuration (defaults values),
// and the user container configuration, either passed by the API or generated
// by the cli.
// It will mutate the specified user configuration (userConf) with the image
// configuration where the user configuration is incomplete.
func merge(userConf, imageConf *containertypes.Config) error {
	if userConf.User == "" {
		userConf.User = imageConf.User
	}
	if len(userConf.ExposedPorts) == 0 {
		userConf.ExposedPorts = imageConf.ExposedPorts
	} else if imageConf.ExposedPorts != nil {
		if userConf.ExposedPorts == nil {
			userConf.ExposedPorts = make(nat.PortSet)
		}
		for port := range imageConf.ExposedPorts {
			if _, exists := userConf.ExposedPorts[port]; !exists {
				userConf.ExposedPorts[port] = struct{}{}
			}
		}
	}

	if len(userConf.Env) == 0 {
		userConf.Env = imageConf.Env
	} else {
		for _, imageEnv := range imageConf.Env {
			found := false
			imageEnvKey := strings.Split(imageEnv, "=")[0]
			for _, userEnv := range userConf.Env {
				userEnvKey := strings.Split(userEnv, "=")[0]
				if imageEnvKey == userEnvKey {
					found = true
					break
				}
			}
			if !found {
				userConf.Env = append(userConf.Env, imageEnv)
			}
		}
	}

	if userConf.Labels == nil {
		userConf.Labels = map[string]string{}
	}
	if imageConf.Labels != nil {
		for l := range userConf.Labels {
			imageConf.Labels[l] = userConf.Labels[l]
		}
		userConf.Labels = imageConf.Labels
	}

	if len(userConf.Entrypoint) == 0 {
		if len(userConf.Cmd) == 0 {
			userConf.Cmd = imageConf.Cmd
			userConf.ArgsEscaped = imageConf.ArgsEscaped
		}

		if userConf.Entrypoint == nil {
			userConf.Entrypoint = imageConf.Entrypoint
		}
	}
	if imageConf.Healthcheck != nil {
		if userConf.Healthcheck == nil {
			userConf.Healthcheck = imageConf.Healthcheck
		} else {
			if len(userConf.Healthcheck.Test) == 0 {
				userConf.Healthcheck.Test = imageConf.Healthcheck.Test
			}
			if userConf.Healthcheck.Interval == 0 {
				userConf.Healthcheck.Interval = imageConf.Healthcheck.Interval
			}
			if userConf.Healthcheck.Timeout == 0 {
				userConf.Healthcheck.Timeout = imageConf.Healthcheck.Timeout
			}
			if userConf.Healthcheck.Retries == 0 {
				userConf.Healthcheck.Retries = imageConf.Healthcheck.Retries
			}
		}
	}

	if userConf.WorkingDir == "" {
		userConf.WorkingDir = imageConf.WorkingDir
	}
	if len(userConf.Volumes) == 0 {
		userConf.Volumes = imageConf.Volumes
	} else {
		for k, v := range imageConf.Volumes {
			userConf.Volumes[k] = v
		}
	}

	if userConf.StopSignal == "" {
		userConf.StopSignal = imageConf.StopSignal
	}
	return nil
}

// Commit creates a new filesystem image from the current state of a container.
// The image can optionally be tagged into a repository.
func (daemon *Daemon) Commit(name string, c *backend.ContainerCommitConfig) (string, error) {
	start := time.Now()
	container, err := daemon.GetContainer(name)
	if err != nil {
		return "", err
	}

	// It is not possible to commit a running container on Windows
	if runtime.GOOS == "windows" && container.IsRunning() {
		return "", fmt.Errorf("Windows does not support commit of a running container")
	}

	if c.Pause && !container.IsPaused() {
		daemon.containerPause(container)
		defer daemon.containerUnpause(container)
	}

	newConfig, err := dockerfile.BuildFromConfig(c.Config, c.Changes)
	if err != nil {
		return "", err
	}

	if c.MergeConfigs {
		if err := merge(newConfig, container.Config); err != nil {
			return "", err
		}
	}

	rwTar, err := daemon.exportContainerRw(container)
	if err != nil {
		return "", err
	}
	defer func() {
		if rwTar != nil {
			rwTar.Close()
		}
	}()

	var history []image.History
	rootFS := image.NewRootFS()
	osVersion := ""
	var osFeatures []string

	if container.ImageID != "" {
		img, err := daemon.imageStore.Get(container.ImageID)
		if err != nil {
			return "", err
		}
		history = img.History
		rootFS = img.RootFS
		osVersion = img.OSVersion
		osFeatures = img.OSFeatures
	}

	l, err := daemon.layerStore.Register(rwTar, rootFS.ChainID())
	if err != nil {
		return "", err
	}
	defer layer.ReleaseAndLog(daemon.layerStore, l)

	h := image.History{
		Author:     c.Author,
		Created:    time.Now().UTC(),
		CreatedBy:  strings.Join(container.Config.Cmd, " "),
		Comment:    c.Comment,
		EmptyLayer: true,
	}

	if diffID := l.DiffID(); layer.DigestSHA256EmptyTar != diffID {
		h.EmptyLayer = false
		rootFS.Append(diffID)
	}

	history = append(history, h)

	config, err := json.Marshal(&image.Image{
		V1Image: image.V1Image{
			DockerVersion:   dockerversion.Version,
			Config:          newConfig,
			Architecture:    runtime.GOARCH,
			OS:              runtime.GOOS,
			Container:       container.ID,
			ContainerConfig: *container.Config,
			Author:          c.Author,
			Created:         h.Created,
		},
		RootFS:     rootFS,
		History:    history,
		OSFeatures: osFeatures,
		OSVersion:  osVersion,
	})

	if err != nil {
		return "", err
	}

	id, err := daemon.imageStore.Create(config)
	if err != nil {
		return "", err
	}

	if container.ImageID != "" {
		if err := daemon.imageStore.SetParent(id, container.ImageID); err != nil {
			return "", err
		}
	}

	if c.Repo != "" {
		newTag, err := reference.WithName(c.Repo) // todo: should move this to API layer
		if err != nil {
			return "", err
		}
		if c.Tag != "" {
			if newTag, err = reference.WithTag(newTag, c.Tag); err != nil {
				return "", err
			}
		}
		if err := daemon.TagImageWithReference(id, newTag); err != nil {
			return "", err
		}
	}

	attributes := map[string]string{
		"comment": c.Comment,
	}
	daemon.LogContainerEventWithAttributes(container, "commit", attributes)
	containerActions.WithValues("commit").UpdateSince(start)
	return id.String(), nil
}

func (daemon *Daemon) exportContainerRw(container *container.Container) (io.ReadCloser, error) {
	if err := daemon.Mount(container); err != nil {
		return nil, err
	}

	archive, err := container.RWLayer.TarStream()
	if err != nil {
		daemon.Unmount(container) // logging is already handled in the `Unmount` function
		return nil, err
	}
	return ioutils.NewReadCloserWrapper(archive, func() error {
			archive.Close()
			return container.RWLayer.Unmount()
		}),
		nil
}
<commit_msg>Add Image ID & Ref to container commit event<commit_after>package daemon

import (
	"encoding/json"
	"fmt"
	"io"
	"runtime"
	"strings"
	"time"

	"github.com/docker/docker/api/types/backend"
	containertypes "github.com/docker/docker/api/types/container"
	"github.com/docker/docker/builder/dockerfile"
	"github.com/docker/docker/container"
	"github.com/docker/docker/dockerversion"
	"github.com/docker/docker/image"
	"github.com/docker/docker/layer"
	"github.com/docker/docker/pkg/ioutils"
	"github.com/docker/docker/reference"
	"github.com/docker/go-connections/nat"
)

// merge merges two Config, the image container configuration (defaults values),
// and the user container configuration, either passed by the API or generated
// by the cli.
// It will mutate the specified user configuration (userConf) with the image
// configuration where the user configuration is incomplete.
func merge(userConf, imageConf *containertypes.Config) error {
	if userConf.User == "" {
		userConf.User = imageConf.User
	}
	if len(userConf.ExposedPorts) == 0 {
		userConf.ExposedPorts = imageConf.ExposedPorts
	} else if imageConf.ExposedPorts != nil {
		if userConf.ExposedPorts == nil {
			userConf.ExposedPorts = make(nat.PortSet)
		}
		for port := range imageConf.ExposedPorts {
			if _, exists := userConf.ExposedPorts[port]; !exists {
				userConf.ExposedPorts[port] = struct{}{}
			}
		}
	}

	if len(userConf.Env) == 0 {
		userConf.Env = imageConf.Env
	} else {
		for _, imageEnv := range imageConf.Env {
			found := false
			imageEnvKey := strings.Split(imageEnv, "=")[0]
			for _, userEnv := range userConf.Env {
				userEnvKey := strings.Split(userEnv, "=")[0]
				if imageEnvKey == userEnvKey {
					found = true
					break
				}
			}
			if !found {
				userConf.Env = append(userConf.Env, imageEnv)
			}
		}
	}

	if userConf.Labels == nil {
		userConf.Labels = map[string]string{}
	}
	if imageConf.Labels != nil {
		for l := range userConf.Labels {
			imageConf.Labels[l] = userConf.Labels[l]
		}
		userConf.Labels = imageConf.Labels
	}

	if len(userConf.Entrypoint) == 0 {
		if len(userConf.Cmd) == 0 {
			userConf.Cmd = imageConf.Cmd
			userConf.ArgsEscaped = imageConf.ArgsEscaped
		}

		if userConf.Entrypoint == nil {
			userConf.Entrypoint = imageConf.Entrypoint
		}
	}
	if imageConf.Healthcheck != nil {
		if userConf.Healthcheck == nil {
			userConf.Healthcheck = imageConf.Healthcheck
		} else {
			if len(userConf.Healthcheck.Test) == 0 {
				userConf.Healthcheck.Test = imageConf.Healthcheck.Test
			}
			if userConf.Healthcheck.Interval == 0 {
				userConf.Healthcheck.Interval = imageConf.Healthcheck.Interval
			}
			if userConf.Healthcheck.Timeout == 0 {
				userConf.Healthcheck.Timeout = imageConf.Healthcheck.Timeout
			}
			if userConf.Healthcheck.Retries == 0 {
				userConf.Healthcheck.Retries = imageConf.Healthcheck.Retries
			}
		}
	}

	if userConf.WorkingDir == "" {
		userConf.WorkingDir = imageConf.WorkingDir
	}
	if len(userConf.Volumes) == 0 {
		userConf.Volumes = imageConf.Volumes
	} else {
		for k, v := range imageConf.Volumes {
			userConf.Volumes[k] = v
		}
	}

	if userConf.StopSignal == "" {
		userConf.StopSignal = imageConf.StopSignal
	}
	return nil
}

// Commit creates a new filesystem image from the current state of a container.
// The image can optionally be tagged into a repository.
func (daemon *Daemon) Commit(name string, c *backend.ContainerCommitConfig) (string, error) {
	start := time.Now()
	container, err := daemon.GetContainer(name)
	if err != nil {
		return "", err
	}

	// It is not possible to commit a running container on Windows
	if runtime.GOOS == "windows" && container.IsRunning() {
		return "", fmt.Errorf("Windows does not support commit of a running container")
	}

	if c.Pause && !container.IsPaused() {
		daemon.containerPause(container)
		defer daemon.containerUnpause(container)
	}

	newConfig, err := dockerfile.BuildFromConfig(c.Config, c.Changes)
	if err != nil {
		return "", err
	}

	if c.MergeConfigs {
		if err := merge(newConfig, container.Config); err != nil {
			return "", err
		}
	}

	rwTar, err := daemon.exportContainerRw(container)
	if err != nil {
		return "", err
	}
	defer func() {
		if rwTar != nil {
			rwTar.Close()
		}
	}()

	var history []image.History
	rootFS := image.NewRootFS()
	osVersion := ""
	var osFeatures []string

	if container.ImageID != "" {
		img, err := daemon.imageStore.Get(container.ImageID)
		if err != nil {
			return "", err
		}
		history = img.History
		rootFS = img.RootFS
		osVersion = img.OSVersion
		osFeatures = img.OSFeatures
	}

	l, err := daemon.layerStore.Register(rwTar, rootFS.ChainID())
	if err != nil {
		return "", err
	}
	defer layer.ReleaseAndLog(daemon.layerStore, l)

	h := image.History{
		Author:     c.Author,
		Created:    time.Now().UTC(),
		CreatedBy:  strings.Join(container.Config.Cmd, " "),
		Comment:    c.Comment,
		EmptyLayer: true,
	}

	if diffID := l.DiffID(); layer.DigestSHA256EmptyTar != diffID {
		h.EmptyLayer = false
		rootFS.Append(diffID)
	}

	history = append(history, h)

	config, err := json.Marshal(&image.Image{
		V1Image: image.V1Image{
			DockerVersion:   dockerversion.Version,
			Config:          newConfig,
			Architecture:    runtime.GOARCH,
			OS:              runtime.GOOS,
			Container:       container.ID,
			ContainerConfig: *container.Config,
			Author:          c.Author,
			Created:         h.Created,
		},
		RootFS:     rootFS,
		History:    history,
		OSFeatures: osFeatures,
		OSVersion:  osVersion,
	})

	if err != nil {
		return "", err
	}

	id, err := daemon.imageStore.Create(config)
	if err != nil {
		return "", err
	}

	if container.ImageID != "" {
		if err := daemon.imageStore.SetParent(id, container.ImageID); err != nil {
			return "", err
		}
	}

	imageRef := ""
	if c.Repo != "" {
		newTag, err := reference.WithName(c.Repo) // todo: should move this to API layer
		if err != nil {
			return "", err
		}
		if c.Tag != "" {
			if newTag, err = reference.WithTag(newTag, c.Tag); err != nil {
				return "", err
			}
		}
		if err := daemon.TagImageWithReference(id, newTag); err != nil {
			return "", err
		}
		imageRef = newTag.String()
	}

	attributes := map[string]string{
		"comment": c.Comment,
		"imageID": id.String(),
		"imageRef": imageRef,
	}
	daemon.LogContainerEventWithAttributes(container, "commit", attributes)
	containerActions.WithValues("commit").UpdateSince(start)
	return id.String(), nil
}

func (daemon *Daemon) exportContainerRw(container *container.Container) (io.ReadCloser, error) {
	if err := daemon.Mount(container); err != nil {
		return nil, err
	}

	archive, err := container.RWLayer.TarStream()
	if err != nil {
		daemon.Unmount(container) // logging is already handled in the `Unmount` function
		return nil, err
	}
	return ioutils.NewReadCloserWrapper(archive, func() error {
			archive.Close()
			return container.RWLayer.Unmount()
		}),
		nil
}
<|endoftext|>


<commit_before>package daemon

import (
    "github.com/sevlyar/go-daemon"
    "github.com/Sirupsen/logrus"
    "github.com/BluePecker/JwtAuth/server"
    "github.com/BluePecker/JwtAuth/server/router/jwt"
)

type Conf struct {
    Daemon  bool

    PidFile string
    LogFile string

    Port    int
}

type Daemon struct {

}

func (d *Daemon) Start(conf Conf) {
    if (conf.Daemon == true) {
        dCtx := daemon.Context{
            PidFileName: conf.PidFile,
            PidFilePerm: 0644,
            LogFileName: conf.LogFile,
            LogFilePerm: 0640,
            Umask:       027,
            WorkDir:     "/",
        }

        if child, err := dCtx.Reborn(); err != nil {
            logrus.Fatal(err)
        } else if child != nil {
            return
        }

        defer dCtx.Release()
    }

    api := &server.Server{}
    api.AddRouter(jwt.NewRouter(nil))

    api.Accept(server.Options{Host: "", Port: conf.Port})
}<commit_msg>fix bug<commit_after>package daemon

import (
    "github.com/sevlyar/go-daemon"
    "github.com/Sirupsen/logrus"
    "github.com/BluePecker/JwtAuth/server"
    "github.com/BluePecker/JwtAuth/server/router/jwt"
)

type Conf struct {
    Daemon  bool

    PidFile string
    LogFile string

    Port    int
}

type Daemon struct {

}

func (d *Daemon) Start(conf Conf) {
    if (conf.Daemon == true) {
        dCtx := daemon.Context{
            PidFileName: conf.PidFile,
            PidFilePerm: 0644,
            LogFileName: conf.LogFile,
            LogFilePerm: 0640,
            Umask:       027,
            WorkDir:     "/",
        }

        defer dCtx.Release()

        if child, err := dCtx.Reborn(); err != nil {
            logrus.Fatal(err)
        } else if child != nil {
            return
        }
    }

    api := &server.Server{}
    api.AddRouter(jwt.NewRouter(nil))

    api.Accept(server.Options{Host: "", Port: conf.Port})
}<|endoftext|>


<commit_before>package integration_test

import (
	"fmt"
	"net/http"
	"os"

	"code.cloudfoundry.org/garden"
	"code.cloudfoundry.org/lager"

	uuid "github.com/nu7hatch/gouuid"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	. "github.com/concourse/atc/cessna"
	"github.com/concourse/baggageclaim"

	bclient "github.com/concourse/baggageclaim/client"

	"testing"

	"archive/tar"
	"bytes"
	"io"

	"code.cloudfoundry.org/garden/gardenfakes"
	gserver "code.cloudfoundry.org/garden/server"
	"code.cloudfoundry.org/lager/lagertest"
	"github.com/concourse/atc/cessna/cessnafakes"
	"github.com/concourse/baggageclaim/baggageclaimfakes"
)

var (
	skipped bool

	testBaseResource Resource
	worker           Worker
	baseResourceType BaseResourceType
	workerIp         string
	tarPath          string
	tarURL           string

	found bool

	logger lager.Logger

	fakeWorker             *cessnafakes.FakeWorker
	fakeGardenClient       *gardenfakes.FakeClient
	fakeBaggageClaimClient *baggageclaimfakes.FakeClient
)

var _ = BeforeSuite(func() {
	_, found = os.LookupEnv("RUN_CESSNA_TESTS")
	if !found {
		skipped = true
	}
})

var _ = AfterSuite(func() {
	if skipped || workerIp == "" {
		return
	}

	worker = NewWorker(fmt.Sprintf("%s:7777", workerIp), fmt.Sprintf("http://%s:7788", workerIp))

	containers, err := worker.GardenClient().Containers(nil)
	Expect(err).NotTo(HaveOccurred())

	for _, container := range containers {
		err = worker.GardenClient().Destroy(container.Handle())
		if err != nil {
			// once garden fixes container grace timeout to be indefinite we can remove this check
			if _, ok := err.(garden.ContainerNotFoundError); !ok {
				if err != gserver.ErrConcurrentDestroy {
					Expect(err).NotTo(HaveOccurred())
				}
			}
		}
	}

	volumes, err := worker.BaggageClaimClient().ListVolumes(logger, nil)
	Expect(err).NotTo(HaveOccurred())

	for _, volume := range volumes {
		err = volume.Destroy()
		Expect(err).NotTo(HaveOccurred())
	}
})

var _ = BeforeEach(func() {
	if skipped {
		Skip("$RUN_CESSNA_TESTS not set; skipping")
	}

	fakeWorker = new(cessnafakes.FakeWorker)
	fakeGardenClient = new(gardenfakes.FakeClient)
	fakeBaggageClaimClient = new(baggageclaimfakes.FakeClient)

	fakeWorker.BaggageClaimClientReturns(fakeBaggageClaimClient)
	fakeWorker.GardenClientReturns(fakeGardenClient)

	workerIp, found = os.LookupEnv("WORKER_IP")
	Expect(found).To(BeTrue(), "Must set WORKER_IP")

	tarPath, found = os.LookupEnv("ROOTFS_TAR_PATH")
	Expect(found).To(BeTrue(), "Must set ROOTFS_TAR_PATH")

	tarURL, found = os.LookupEnv("ROOTFS_TAR_URL")
	Expect(found).To(BeTrue(), "Must set ROOTFS_TAR_URL")

	worker = NewWorker(fmt.Sprintf("%s:7777", workerIp), fmt.Sprintf("http://%s:7788", workerIp))
	logger = lagertest.NewTestLogger("logger-test")
})

func TestResource(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Cessna Integration Suite")
}

func createBaseResourceVolume(r io.Reader) (string, error) {
	baggageclaimClient := bclient.New(fmt.Sprintf("http://%s:7788", workerIp), http.DefaultTransport)

	volumeSpec := baggageclaim.VolumeSpec{
		Strategy:   baggageclaim.EmptyStrategy{},
		Privileged: true,
	}

	handle, err := uuid.NewV4()
	if err != nil {
		return "", err
	}

	volume, err := baggageclaimClient.CreateVolume(
		lager.NewLogger("create-volume-for-base-resource"),
		handle.String(),
		volumeSpec,
	)

	if err != nil {
		return "", err
	}

	err = volume.StreamIn("/", r)
	if err != nil {
		return "", err
	}

	return volume.Path(), nil
}

func NewResourceContainer(check string, in string, out string) ResourceContainer {
	return ResourceContainer{
		Check:         check,
		In:            in,
		Out:           out,
		RootFSTarPath: tarPath,
	}
}

type ResourceContainer struct {
	Check         string
	In            string
	Out           string
	RootFSTarPath string
}

func (r ResourceContainer) RootFSify() (io.Reader, error) {
	f, err := os.Open(r.RootFSTarPath)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	buffer := new(bytes.Buffer)

	t := tar.NewWriter(buffer)
	rootFS := tar.NewReader(f)

	err = t.WriteHeader(&tar.Header{
		Name: "./opt/resource/check",
		Mode: 0755,
		Size: int64(len(r.Check)),
	})
	if err != nil {
		return nil, err
	}
	_, err = t.Write([]byte(r.Check))
	if err != nil {
		return nil, err
	}

	err = t.WriteHeader(&tar.Header{
		Name: "./opt/resource/in",
		Mode: 0755,
		Size: int64(len(r.In)),
	})
	if err != nil {
		return nil, err
	}
	_, err = t.Write([]byte(r.In))
	if err != nil {
		return nil, err
	}

	err = t.WriteHeader(&tar.Header{
		Name: "./opt/resource/out",
		Mode: 0755,
		Size: int64(len(r.Out)),
	})
	if err != nil {
		return nil, err
	}
	_, err = t.Write([]byte(r.Out))
	if err != nil {
		return nil, err
	}

	for {
		header, err := rootFS.Next()
		if err != nil {
			if err == io.EOF {
				break
			}
			return nil, err
		}

		err = t.WriteHeader(header)
		if err != nil {
			return nil, err
		}

		_, err = io.Copy(t, rootFS)
		if err != nil {
			return nil, err
		}
	}

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

	return bytes.NewBuffer(buffer.Bytes()), nil
}
<commit_msg>error returned by client is not of server error type<commit_after>package integration_test

import (
	"fmt"
	"net/http"
	"os"

	"code.cloudfoundry.org/garden"
	"code.cloudfoundry.org/lager"

	uuid "github.com/nu7hatch/gouuid"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	. "github.com/concourse/atc/cessna"
	"github.com/concourse/baggageclaim"

	bclient "github.com/concourse/baggageclaim/client"

	"testing"

	"archive/tar"
	"bytes"
	"io"

	"code.cloudfoundry.org/garden/gardenfakes"
	gserver "code.cloudfoundry.org/garden/server"
	"code.cloudfoundry.org/lager/lagertest"
	"github.com/concourse/atc/cessna/cessnafakes"
	"github.com/concourse/baggageclaim/baggageclaimfakes"
)

var (
	skipped bool

	testBaseResource Resource
	worker           Worker
	baseResourceType BaseResourceType
	workerIp         string
	tarPath          string
	tarURL           string

	found bool

	logger lager.Logger

	fakeWorker             *cessnafakes.FakeWorker
	fakeGardenClient       *gardenfakes.FakeClient
	fakeBaggageClaimClient *baggageclaimfakes.FakeClient
)

var _ = BeforeSuite(func() {
	_, found = os.LookupEnv("RUN_CESSNA_TESTS")
	if !found {
		skipped = true
	}
})

var _ = AfterSuite(func() {
	if skipped || workerIp == "" {
		return
	}

	worker = NewWorker(fmt.Sprintf("%s:7777", workerIp), fmt.Sprintf("http://%s:7788", workerIp))

	containers, err := worker.GardenClient().Containers(nil)
	Expect(err).NotTo(HaveOccurred())

	for _, container := range containers {
		err = worker.GardenClient().Destroy(container.Handle())
		if err != nil {
			// once garden fixes container grace timeout to be indefinite we can remove this check
			if _, ok := err.(garden.ContainerNotFoundError); !ok {
				if err.Error() != gserver.ErrConcurrentDestroy.Error() {
					Expect(err).NotTo(HaveOccurred())
				}
			}
		}
	}

	volumes, err := worker.BaggageClaimClient().ListVolumes(logger, nil)
	Expect(err).NotTo(HaveOccurred())

	for _, volume := range volumes {
		err = volume.Destroy()
		Expect(err).NotTo(HaveOccurred())
	}
})

var _ = BeforeEach(func() {
	if skipped {
		Skip("$RUN_CESSNA_TESTS not set; skipping")
	}

	fakeWorker = new(cessnafakes.FakeWorker)
	fakeGardenClient = new(gardenfakes.FakeClient)
	fakeBaggageClaimClient = new(baggageclaimfakes.FakeClient)

	fakeWorker.BaggageClaimClientReturns(fakeBaggageClaimClient)
	fakeWorker.GardenClientReturns(fakeGardenClient)

	workerIp, found = os.LookupEnv("WORKER_IP")
	Expect(found).To(BeTrue(), "Must set WORKER_IP")

	tarPath, found = os.LookupEnv("ROOTFS_TAR_PATH")
	Expect(found).To(BeTrue(), "Must set ROOTFS_TAR_PATH")

	tarURL, found = os.LookupEnv("ROOTFS_TAR_URL")
	Expect(found).To(BeTrue(), "Must set ROOTFS_TAR_URL")

	worker = NewWorker(fmt.Sprintf("%s:7777", workerIp), fmt.Sprintf("http://%s:7788", workerIp))
	logger = lagertest.NewTestLogger("logger-test")
})

func TestResource(t *testing.T) {
	RegisterFailHandler(Fail)
	RunSpecs(t, "Cessna Integration Suite")
}

func createBaseResourceVolume(r io.Reader) (string, error) {
	baggageclaimClient := bclient.New(fmt.Sprintf("http://%s:7788", workerIp), http.DefaultTransport)

	volumeSpec := baggageclaim.VolumeSpec{
		Strategy:   baggageclaim.EmptyStrategy{},
		Privileged: true,
	}

	handle, err := uuid.NewV4()
	if err != nil {
		return "", err
	}

	volume, err := baggageclaimClient.CreateVolume(
		lager.NewLogger("create-volume-for-base-resource"),
		handle.String(),
		volumeSpec,
	)

	if err != nil {
		return "", err
	}

	err = volume.StreamIn("/", r)
	if err != nil {
		return "", err
	}

	return volume.Path(), nil
}

func NewResourceContainer(check string, in string, out string) ResourceContainer {
	return ResourceContainer{
		Check:         check,
		In:            in,
		Out:           out,
		RootFSTarPath: tarPath,
	}
}

type ResourceContainer struct {
	Check         string
	In            string
	Out           string
	RootFSTarPath string
}

func (r ResourceContainer) RootFSify() (io.Reader, error) {
	f, err := os.Open(r.RootFSTarPath)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	buffer := new(bytes.Buffer)

	t := tar.NewWriter(buffer)
	rootFS := tar.NewReader(f)

	err = t.WriteHeader(&tar.Header{
		Name: "./opt/resource/check",
		Mode: 0755,
		Size: int64(len(r.Check)),
	})
	if err != nil {
		return nil, err
	}
	_, err = t.Write([]byte(r.Check))
	if err != nil {
		return nil, err
	}

	err = t.WriteHeader(&tar.Header{
		Name: "./opt/resource/in",
		Mode: 0755,
		Size: int64(len(r.In)),
	})
	if err != nil {
		return nil, err
	}
	_, err = t.Write([]byte(r.In))
	if err != nil {
		return nil, err
	}

	err = t.WriteHeader(&tar.Header{
		Name: "./opt/resource/out",
		Mode: 0755,
		Size: int64(len(r.Out)),
	})
	if err != nil {
		return nil, err
	}
	_, err = t.Write([]byte(r.Out))
	if err != nil {
		return nil, err
	}

	for {
		header, err := rootFS.Next()
		if err != nil {
			if err == io.EOF {
				break
			}
			return nil, err
		}

		err = t.WriteHeader(header)
		if err != nil {
			return nil, err
		}

		_, err = io.Copy(t, rootFS)
		if err != nil {
			return nil, err
		}
	}

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

	return bytes.NewBuffer(buffer.Bytes()), nil
}
<|endoftext|>


<commit_before>package irc

import (
	"bufio"
	"log"
	"net"
	"strings"
)

type Socket struct {
	conn    net.Conn
	reader  *bufio.Reader
	receive chan string
	send    chan string
	writer  *bufio.Writer
}

func NewSocket(conn net.Conn) *Socket {
	socket := &Socket{
		conn:    conn,
		reader:  bufio.NewReader(conn),
		receive: make(chan string),
		send:    make(chan string),
		writer:  bufio.NewWriter(conn),
	}

	go socket.readLines()
	go socket.writeLines()

	return socket
}

func (socket *Socket) String() string {
	return socket.conn.RemoteAddr().String()
}

func (socket *Socket) Close() {
	socket.conn.Close()
}

func (socket *Socket) Read() <-chan string {
	return socket.receive
}

func (socket *Socket) Write(lines []string) {
	for _, line := range lines {
		socket.send <- line
	}
	return
}

func (socket *Socket) readLines() {
	for {
		line, err := socket.reader.ReadString('\n')
		if err != nil {
			if DEBUG_NET {
				log.Printf("%s → error: %s", socket, err)
			}
			break
		}

		line = strings.TrimSpace(line)
		if DEBUG_NET {
			log.Printf("%s → %s", socket, line)
		}

		socket.receive <- line
	}
	close(socket.receive)
}

func (socket *Socket) writeLines() {
	for line := range socket.send {
		if DEBUG_NET {
			log.Printf("%s ← %s", socket, line)
		}
		if _, err := socket.writer.WriteString(line); socket.maybeLogWriteError(err) {
			break
		}
		if _, err := socket.writer.WriteString(CRLF); socket.maybeLogWriteError(err) {
			break
		}

		if err := socket.writer.Flush(); socket.maybeLogWriteError(err) {
			break
		}
	}
}

func (socket *Socket) maybeLogWriteError(err error) bool {
	if err != nil {
		if DEBUG_NET {
			log.Printf("%s ← error: %s", socket, err)
		}
		return true
	}
	return false
}
<commit_msg>allow blank lines from the client<commit_after>package irc

import (
	"bufio"
	"log"
	"net"
	"strings"
)

type Socket struct {
	conn    net.Conn
	reader  *bufio.Reader
	receive chan string
	send    chan string
	writer  *bufio.Writer
}

func NewSocket(conn net.Conn) *Socket {
	socket := &Socket{
		conn:    conn,
		reader:  bufio.NewReader(conn),
		receive: make(chan string),
		send:    make(chan string),
		writer:  bufio.NewWriter(conn),
	}

	go socket.readLines()
	go socket.writeLines()

	return socket
}

func (socket *Socket) String() string {
	return socket.conn.RemoteAddr().String()
}

func (socket *Socket) Close() {
	socket.conn.Close()
}

func (socket *Socket) Read() <-chan string {
	return socket.receive
}

func (socket *Socket) Write(lines []string) {
	for _, line := range lines {
		socket.send <- line
	}
	return
}

func (socket *Socket) readLines() {
	for {
		line, err := socket.reader.ReadString('\n')
		if err != nil {
			if DEBUG_NET {
				log.Printf("%s → error: %s", socket, err)
			}
			break
		}

		line = strings.TrimSpace(line)
		if len(line) == 0 {
			continue
		}
		if DEBUG_NET {
			log.Printf("%s → %s", socket, line)
		}

		socket.receive <- line
	}
	close(socket.receive)
}

func (socket *Socket) writeLines() {
	for line := range socket.send {
		if DEBUG_NET {
			log.Printf("%s ← %s", socket, line)
		}
		if _, err := socket.writer.WriteString(line); socket.maybeLogWriteError(err) {
			break
		}
		if _, err := socket.writer.WriteString(CRLF); socket.maybeLogWriteError(err) {
			break
		}

		if err := socket.writer.Flush(); socket.maybeLogWriteError(err) {
			break
		}
	}
}

func (socket *Socket) maybeLogWriteError(err error) bool {
	if err != nil {
		if DEBUG_NET {
			log.Printf("%s ← error: %s", socket, err)
		}
		return true
	}
	return false
}
<|endoftext|>


<commit_before>// Copyright (c) 2014-2019 Bitmark Inc.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package util

import (
	"encoding/hex"
	"strings"
	"testing"

	"github.com/bitmark-inc/bitmarkd/fault"
	"github.com/stretchr/testify/assert"
)

// Test IP address detection
func TestCanonical(t *testing.T) {

	type item struct {
		in  string
		out string
	}

	testData := []item{
		{"127.0.0.1:1234", "127.0.0.1:1234"},
		{"127.0.0.1:1", "127.0.0.1:1"},
		{" 127.0.0.1 : 1 ", "127.0.0.1:1"},
		{"127.0.0.1:65535", "127.0.0.1:65535"},
		{"0.0.0.0:1234", "0.0.0.0:1234"},
		{"[::1]:1234", "[::1]:1234"},
		{"[::]:1234", "[::]:1234"},
		{"[0:0::0:0]:1234", "[::]:1234"},
		{"[0:0:0:0::1]:1234", "[::1]:1234"},
		{"[2404:6800:4008:c07::66]:443", "[2404:6800:4008:c07::66]:443"},
		{"[2404:6800:4008:0c07:0000:0000:0000:0066]:443", "[2404:6800:4008:c07::66]:443"},
	}

	for i, d := range testData {

		// create a connection item
		c, err := NewConnection(d.in)
		if nil != err {
			t.Fatalf("NewConnection failed on:[%d] %q  error: %s", i, d.in, err)
		}

		// convert to text
		s, v6 := c.CanonicalIPandPort("")
		if s != d.out {
			t.Fatalf("failed on:[%d] %q  actual: %q  expected: %q", i, d.in, s, d.out)
		}

		t.Logf("converted:[%d]: %q  to(%t): %q", i, d.in, v6, s)

		// check packing/unpacking
		pk := c.Pack()
		cu, n := pk.Unpack()
		if len(pk) != n {
			t.Fatalf("Unpack failed on:[%d] %q  only read: %d of: %d bytes", i, d.in, n, len(pk))
		}
		su, v6u := cu.CanonicalIPandPort("")
		if su != s {
			t.Fatalf("failed on:[%d] %x  actual: %q  expected: %q", i, pk, su, s)
		}
		if v6u != v6 {
			t.Fatalf("failed on:[%d] %x  actual v6: %t  expected v6: %t", i, pk, v6u, v6)
		}
	}
}

// Test IP address
func TestCanonicalIP(t *testing.T) {

	testData := []string{
		"256.0.0.0:1234",
		"0.256.0.0:1234",
		"0.0.256.0:1234",
		"0.0.0.256:1234",
		"0:0:1234",
		"[]:1234",
		"[as34::]:1234",
		"[1ffff::]:1234",
		"[2404:6800:4008:0c07:0000:0000:0000:0066:1234]:443",
		"*:1234",
	}

	for i, d := range testData {
		c, err := NewConnection(d)
		if nil == err {
			s, v6 := c.CanonicalIPandPort("")
			t.Fatalf("eroneoulssly converted:[%d]: %q  to(%t): %q", i, d, v6, s)
		}
		if strings.Contains(err.Error(), "no such host") {
			// expected error
		} else if fault.ErrInvalidIpAddress != err {
			t.Fatalf("NewConnection failed on:[%d] %q  error: %s", i, d, err)
		}
	}
}

// Test port range
func TestCanonicalPort(t *testing.T) {

	testData := []string{
		"127.0.0.1:0",
		"127.0.0.1:65536",
		"127.0.0.1:-1",
	}

	for i, d := range testData {
		c, err := NewConnection(d)
		if nil == err {
			s, v6 := c.CanonicalIPandPort("")
			t.Fatalf("eroneoulssly converted:[%d]: %q  to(%t): %q", i, d, v6, s)
		}
		if fault.ErrInvalidPortNumber != err {
			t.Fatalf("NewConnection failed on:[%d] %q  error: %s", i, d, err)
		}
	}
}

// helper
func makePacked(h string) PackedConnection {
	b, err := hex.DecodeString(h)
	if nil != err {
		panic(err)
	}
	return b
}

// Test of unpack
func TestCanonicalUnpack(t *testing.T) {

	type item struct {
		packed    PackedConnection
		addresses []string
		v4        string
		v6        string
	}

	testData := []item{
		{
			packed: makePacked("1304d200000000000000000000ffff7f0000011304d200000000000000000000000000000001"),
			addresses: []string{
				"127.0.0.1:1234",
				"[::1]:1234",
			},
			v4: "127.0.0.1:1234",
			v6: "[::1]:1234",
		},
		{
			packed: makePacked("1304d2000000000000000000000000000000011304d200000000000000000000ffff7f000001"),
			addresses: []string{
				"[::1]:1234",
				"127.0.0.1:1234",
			},
			v4: "127.0.0.1:1234",
			v6: "[::1]:1234",
		},
		{
			packed: makePacked("1301bb2404680040080c0700000000000000661301bb2404680040080c070000000000000066"),
			addresses: []string{
				"[2404:6800:4008:c07::66]:443",
				"[2404:6800:4008:c07::66]:443",
			},
			v4: "<nil>",
			v6: "[2404:6800:4008:c07::66]:443",
		},
		{ // extraneous data
			packed: makePacked("1301bb2404680040080c0700000000000000661301bb2404680040080c0700000000000000660000000000000000000000000000000000000000"),
			addresses: []string{
				"[2404:6800:4008:c07::66]:443",
				"[2404:6800:4008:c07::66]:443",
			},
			v4: "<nil>",
			v6: "[2404:6800:4008:c07::66]:443",
		},
		{ // bad data -> no items
			packed:    makePacked("1401bb2404680040080c0700000000000000661001bb2404680040080c0700000000000000660000000000000000000000000000000000000000"),
			addresses: []string{},
			v4:        "<nil>",
			v6:        "<nil>",
		},
		{ // bad data followed by good addresses -> consider as all bad
			packed:    makePacked("01221304d200000000000000000000ffff7f0000011304d200000000000000000000000000000001"),
			addresses: []string{},
			v4:        "<nil>",
			v6:        "<nil>",
		},
	}

	for i, data := range testData {
		p := data.packed
		a := data.addresses
		al := len(a)

		v4, v6 := p.Unpack46()
		v4s := "<nil>"
		if nil != v4 {
			v4s, _ = v4.CanonicalIPandPort("")
		}
		v6s := "<nil>"
		if nil != v6 {
			v6s, _ = v6.CanonicalIPandPort("")
		}
		if data.v4 != v4s {
			t.Errorf("unpack46:[%d]: v4 actual: %q  expected: %q", i, v4s, data.v4)
		}
		if data.v6 != v6s {
			t.Errorf("unpack66:[%d]: v6 actual: %q  expected: %q", i, v6s, data.v6)
		}

	inner:
		for k := 0; k < 10; k += 1 {
			l := len(p)
			c, n := p.Unpack()
			p = p[n:]

			if nil == c {
				// only signal error if nil was not just after last address
				if k != al {
					t.Errorf("unpack:[%d]: nil connection, n: %d", i, n)
				}

			} else {
				s, v6 := c.CanonicalIPandPort("")
				if k >= al {
					t.Errorf("unpack:[%d]: bytes: %d of %d result: (%t) %q", i, n, l, v6, s)
				} else if s != a[k] {
					t.Errorf("unpack:[%d]: bytes: %d of %d result: (%t) %q  expected: %s", i, n, l, v6, s, a[k])
				}
			}
			if n <= 0 {
				break inner
			}
		}
	}
}

func TestTruncateIPv6BracketWhenNoBracket(t *testing.T) {
	testStr := "1:2:3:4"
	actual := truncateIPv6Bracket(testStr)
	assert.Equal(t, testStr, actual, "truncate wrong string")
}

func TestTruncateIPv6BracketWithBracket(t *testing.T) {
	testStr := "[1:2:3:4]:1234"
	actual := truncateIPv6Bracket(testStr)
	assert.Equal(t, "1:2:3:4:1234", actual, "truncate wrong string")
}
<commit_msg>[util] remove obsolete test<commit_after>// Copyright (c) 2014-2019 Bitmark Inc.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package util

import (
	"encoding/hex"
	"strings"
	"testing"

	"github.com/bitmark-inc/bitmarkd/fault"
)

// Test IP address detection
func TestCanonical(t *testing.T) {

	type item struct {
		in  string
		out string
	}

	testData := []item{
		{"127.0.0.1:1234", "127.0.0.1:1234"},
		{"127.0.0.1:1", "127.0.0.1:1"},
		{" 127.0.0.1 : 1 ", "127.0.0.1:1"},
		{"127.0.0.1:65535", "127.0.0.1:65535"},
		{"0.0.0.0:1234", "0.0.0.0:1234"},
		{"[::1]:1234", "[::1]:1234"},
		{"[::]:1234", "[::]:1234"},
		{"[0:0::0:0]:1234", "[::]:1234"},
		{"[0:0:0:0::1]:1234", "[::1]:1234"},
		{"[2404:6800:4008:c07::66]:443", "[2404:6800:4008:c07::66]:443"},
		{"[2404:6800:4008:0c07:0000:0000:0000:0066]:443", "[2404:6800:4008:c07::66]:443"},
	}

	for i, d := range testData {

		// create a connection item
		c, err := NewConnection(d.in)
		if nil != err {
			t.Fatalf("NewConnection failed on:[%d] %q  error: %s", i, d.in, err)
		}

		// convert to text
		s, v6 := c.CanonicalIPandPort("")
		if s != d.out {
			t.Fatalf("failed on:[%d] %q  actual: %q  expected: %q", i, d.in, s, d.out)
		}

		t.Logf("converted:[%d]: %q  to(%t): %q", i, d.in, v6, s)

		// check packing/unpacking
		pk := c.Pack()
		cu, n := pk.Unpack()
		if len(pk) != n {
			t.Fatalf("Unpack failed on:[%d] %q  only read: %d of: %d bytes", i, d.in, n, len(pk))
		}
		su, v6u := cu.CanonicalIPandPort("")
		if su != s {
			t.Fatalf("failed on:[%d] %x  actual: %q  expected: %q", i, pk, su, s)
		}
		if v6u != v6 {
			t.Fatalf("failed on:[%d] %x  actual v6: %t  expected v6: %t", i, pk, v6u, v6)
		}
	}
}

// Test IP address
func TestCanonicalIP(t *testing.T) {

	testData := []string{
		"256.0.0.0:1234",
		"0.256.0.0:1234",
		"0.0.256.0:1234",
		"0.0.0.256:1234",
		"0:0:1234",
		"[]:1234",
		"[as34::]:1234",
		"[1ffff::]:1234",
		"[2404:6800:4008:0c07:0000:0000:0000:0066:1234]:443",
		"*:1234",
	}

	for i, d := range testData {
		c, err := NewConnection(d)
		if nil == err {
			s, v6 := c.CanonicalIPandPort("")
			t.Fatalf("eroneoulssly converted:[%d]: %q  to(%t): %q", i, d, v6, s)
		}
		if strings.Contains(err.Error(), "no such host") {
			// expected error
		} else if fault.ErrInvalidIpAddress != err {
			t.Fatalf("NewConnection failed on:[%d] %q  error: %s", i, d, err)
		}
	}
}

// Test port range
func TestCanonicalPort(t *testing.T) {

	testData := []string{
		"127.0.0.1:0",
		"127.0.0.1:65536",
		"127.0.0.1:-1",
	}

	for i, d := range testData {
		c, err := NewConnection(d)
		if nil == err {
			s, v6 := c.CanonicalIPandPort("")
			t.Fatalf("eroneoulssly converted:[%d]: %q  to(%t): %q", i, d, v6, s)
		}
		if fault.ErrInvalidPortNumber != err {
			t.Fatalf("NewConnection failed on:[%d] %q  error: %s", i, d, err)
		}
	}
}

// helper
func makePacked(h string) PackedConnection {
	b, err := hex.DecodeString(h)
	if nil != err {
		panic(err)
	}
	return b
}

// Test of unpack
func TestCanonicalUnpack(t *testing.T) {

	type item struct {
		packed    PackedConnection
		addresses []string
		v4        string
		v6        string
	}

	testData := []item{
		{
			packed: makePacked("1304d200000000000000000000ffff7f0000011304d200000000000000000000000000000001"),
			addresses: []string{
				"127.0.0.1:1234",
				"[::1]:1234",
			},
			v4: "127.0.0.1:1234",
			v6: "[::1]:1234",
		},
		{
			packed: makePacked("1304d2000000000000000000000000000000011304d200000000000000000000ffff7f000001"),
			addresses: []string{
				"[::1]:1234",
				"127.0.0.1:1234",
			},
			v4: "127.0.0.1:1234",
			v6: "[::1]:1234",
		},
		{
			packed: makePacked("1301bb2404680040080c0700000000000000661301bb2404680040080c070000000000000066"),
			addresses: []string{
				"[2404:6800:4008:c07::66]:443",
				"[2404:6800:4008:c07::66]:443",
			},
			v4: "<nil>",
			v6: "[2404:6800:4008:c07::66]:443",
		},
		{ // extraneous data
			packed: makePacked("1301bb2404680040080c0700000000000000661301bb2404680040080c0700000000000000660000000000000000000000000000000000000000"),
			addresses: []string{
				"[2404:6800:4008:c07::66]:443",
				"[2404:6800:4008:c07::66]:443",
			},
			v4: "<nil>",
			v6: "[2404:6800:4008:c07::66]:443",
		},
		{ // bad data -> no items
			packed:    makePacked("1401bb2404680040080c0700000000000000661001bb2404680040080c0700000000000000660000000000000000000000000000000000000000"),
			addresses: []string{},
			v4:        "<nil>",
			v6:        "<nil>",
		},
		{ // bad data followed by good addresses -> consider as all bad
			packed:    makePacked("01221304d200000000000000000000ffff7f0000011304d200000000000000000000000000000001"),
			addresses: []string{},
			v4:        "<nil>",
			v6:        "<nil>",
		},
	}

	for i, data := range testData {
		p := data.packed
		a := data.addresses
		al := len(a)

		v4, v6 := p.Unpack46()
		v4s := "<nil>"
		if nil != v4 {
			v4s, _ = v4.CanonicalIPandPort("")
		}
		v6s := "<nil>"
		if nil != v6 {
			v6s, _ = v6.CanonicalIPandPort("")
		}
		if data.v4 != v4s {
			t.Errorf("unpack46:[%d]: v4 actual: %q  expected: %q", i, v4s, data.v4)
		}
		if data.v6 != v6s {
			t.Errorf("unpack66:[%d]: v6 actual: %q  expected: %q", i, v6s, data.v6)
		}

	inner:
		for k := 0; k < 10; k += 1 {
			l := len(p)
			c, n := p.Unpack()
			p = p[n:]

			if nil == c {
				// only signal error if nil was not just after last address
				if k != al {
					t.Errorf("unpack:[%d]: nil connection, n: %d", i, n)
				}

			} else {
				s, v6 := c.CanonicalIPandPort("")
				if k >= al {
					t.Errorf("unpack:[%d]: bytes: %d of %d result: (%t) %q", i, n, l, v6, s)
				} else if s != a[k] {
					t.Errorf("unpack:[%d]: bytes: %d of %d result: (%t) %q  expected: %s", i, n, l, v6, s, a[k])
				}
			}
			if n <= 0 {
				break inner
			}
		}
	}
}
<|endoftext|>


<commit_before>package utils

import (
	"github.com/animenotifier/notify.moe/arn"
	"github.com/animenotifier/mal"
	"github.com/animenotifier/notify.moe/utils/animediff"
)

// MALComparison encapsulates the difference between an ARN anime and a MAL anime.
type MALComparison struct {
	Anime       *arn.Anime
	MALAnime    *mal.Anime
	Differences []animediff.Difference
}
<commit_msg>gofmt code<commit_after>package utils

import (
	"github.com/animenotifier/mal"
	"github.com/animenotifier/notify.moe/arn"
	"github.com/animenotifier/notify.moe/utils/animediff"
)

// MALComparison encapsulates the difference between an ARN anime and a MAL anime.
type MALComparison struct {
	Anime       *arn.Anime
	MALAnime    *mal.Anime
	Differences []animediff.Difference
}
<|endoftext|>


<commit_before>package gw2api

import (
	"fmt"
	"testing"
)

func ExampleItems() {
	//get list of item id's
	i, _ := Items("")
	fmt.Println(i[0:3])
	// Output:
	// [1 2 6]
}

func ExampleItemsIds() {
	//get specific items by their id's, in French
	i, _ := ItemsIds("fr", 12452)

	for _, val := range i {
		fmt.Printf("ID %d - %s - %s\n", val.ID, val.Type, val.Name)
	}
	// Output:
	// ID 12452 - Consumable - Barre aux baies d'Omnom
}

func ExampleItemsPages() {
	//get specific items by their pages
	i, _ := ItemsPages(3, 1, "") //get page 3 with page_size 1, in English

	for _, val := range i {
		fmt.Printf("%s - %s\n", val.Name, val.Icon)
	}
	// Output:
	// Undead Unarmed - https://render.guildwars2.com/file/C5B365D6105F76470106A61F4AB96F3E39D10E18/60991.png
}

func TestItems(t *testing.T) {
	//t.Skip()
	id := "Items"
	_, err := Items("es")
	if err != nil {
		t.Errorf("Failed to get %s in Spanish! Got:\n%s", id, err.Error())
	}

	i, err := Items("")
	if err != nil {
		t.Errorf("Failed to get %s with empty parameter! Got:\n%s", id, err.Error())
	} else if i == nil {
		t.Errorf("Empty output for %s with empty parameter!", id)
	}
	fmt.Printf("\t-%s\t\t\t", id)
	if !t.Failed() {
		fmt.Printf("OK\n")
	} else {
		fmt.Printf("FAILED\n")
	}
}

//DEEP OK
func TestItemsIds(t *testing.T) {
	//t.Skip()
	id := "ItemsIds"
	_, err := ItemsIds("es")
	if err == nil {
		t.Errorf("No error calling %s with only lang!", id)
	}

	_, err = ItemsIds("", 0, 0, 0, 0)
	if err == nil {
		t.Errorf("No error unmarshalled when calling %s with invalid parameters!", id)
	}

	i, err := ItemsIds("es", 162, 1002, 3, 4, 5)
	if err != nil {
		t.Errorf("Error getting %s in Spanish with multiple parameters! Got:\n%s", id, err.Error())
	} else if i[0].ID == 0 {
		t.Errorf("Empty output for %s in Spanish with multiple parameters!")
	}
	fmt.Printf("\t-%s\t\t", id)
	if !t.Failed() {
		fmt.Printf("OK\n")
	} else {
		fmt.Printf("FAILED\n")
	}
}

//DEEP OK
func TestItemsPages(t *testing.T) {
	//t.Skip()
	id := "ItemsPages"
	_, err := ItemsPages(-1, -1, "es")
	if err == nil {
		t.Errorf("No error calling %s with only lang!", id)
	}

	_, err = ItemsPages(-1, 0, "")
	if err == nil {
		t.Errorf("No error unmarshalled when calling %s with invalid parameters!", id)
	}

	i, err := ItemsPages(0, 0, "es")
	if err != nil {
		t.Errorf("Error getting %s in Spanish with multiple parameters! Got:\n%s", id, err.Error())
	} else if i == nil {
		t.Errorf("Empty output for %s in Spanish with multiple parameters!")
	}
	fmt.Printf("\t-%s\t\t", id)
	if !t.Failed() {
		fmt.Printf("OK\n")
	} else {
		fmt.Printf("FAILED\n")
	}
}

//DEEP OK
func TestItemsUnmarshalling(t *testing.T) {
	//t.Skip()
	id := "ItemsUnmarshalling"
	i, err := ItemsIds("", 162)
	if err != nil {
		t.Errorf("Error getting data for %s!", id)
	}
	if i[0].Name == "" {
		t.Errorf("%s: Empty Name!", id)
	}
	if i[0].Type == "" {
		t.Errorf("%s: Empty Type!", id)
	}
	if i[0].Level == 0 {
		t.Errorf("%s: Empty Level!", id)
	}
	if i[0].Rarity == "" {
		t.Errorf("%s: Empty Rarity!", id)
	}
	if i[0].VendorValue == 0 {
		t.Errorf("%s: Empty VendorValue!", id)
	}
	if i[0].DefaultSkin == 0 {
		t.Errorf("%s: Empty DefaultSkin!", id)
	}
	if i[0].GameTypes == nil {
		t.Errorf("%s: Empty GameTypes!", id)
	}
	if i[0].Flags == nil {
		t.Errorf("%s: Empty Flags!", id)
	}
	if i[0].ID == 0 {
		t.Errorf("%s: Empty ID!", id)
	}
	if i[0].Icon == "" {
		t.Errorf("%s: Empty Icon!", id)
	}
	if i[0].Details == nil {
		t.Errorf("%s: Empty Details!", id)
	}
	fmt.Printf("\t-%s\t", id)
	if !t.Failed() {
		fmt.Printf("OK\n")
	} else {
		fmt.Printf("FAILED\n")
	}
}
<commit_msg>Add detailed icons example<commit_after>package gw2api

import (
	"fmt"
	"testing"
	"net/http"
	"io/ioutil"
)

func ExampleItems() {
	//get list of item id's
	i, _ := Items("")
	fmt.Println(i[0:3])
	// Output:
	// [1 2 6]
}

func ExampleItemsIds() {
	//get specific items by their id's, in French
	i, _ := ItemsIds("fr", 12452)

	for _, val := range i {
		fmt.Printf("ID %d - %s - %s\n", val.ID, val.Type, val.Name)
	}
	// Output:
	// ID 12452 - Consumable - Barre aux baies d'Omnom
}

func ExampleItemsIds_icons() {
	//get a specific icon off the API
	i, _ := Items("")
	j, _ := ItemsIds("", i[0:3]...)
	resp, _ := http.Get(j[0].Icon)	//get the http response
	blob, _ := ioutil.ReadAll(resp.Body)	//read all the bytes into a blob []byte
	//do interesting things!
	blob = blob
}

func ExampleItemsPages() {
	//get specific items by their pages
	i, _ := ItemsPages(3, 1, "") //get page 3 with page_size 1, in English

	for _, val := range i {
		fmt.Printf("%s - %s\n", val.Name, val.Icon)
	}
	// Output:
	// Undead Unarmed - https://render.guildwars2.com/file/C5B365D6105F76470106A61F4AB96F3E39D10E18/60991.png
}

func TestItems(t *testing.T) {
	//t.Skip()
	id := "Items"
	_, err := Items("es")
	if err != nil {
		t.Errorf("Failed to get %s in Spanish! Got:\n%s", id, err.Error())
	}

	i, err := Items("")
	if err != nil {
		t.Errorf("Failed to get %s with empty parameter! Got:\n%s", id, err.Error())
	} else if i == nil {
		t.Errorf("Empty output for %s with empty parameter!", id)
	}
	fmt.Printf("\t-%s\t\t\t", id)
	if !t.Failed() {
		fmt.Printf("OK\n")
	} else {
		fmt.Printf("FAILED\n")
	}
}

//DEEP OK
func TestItemsIds(t *testing.T) {
	//t.Skip()
	id := "ItemsIds"
	_, err := ItemsIds("es")
	if err == nil {
		t.Errorf("No error calling %s with only lang!", id)
	}

	_, err = ItemsIds("", 0, 0, 0, 0)
	if err == nil {
		t.Errorf("No error unmarshalled when calling %s with invalid parameters!", id)
	}

	i, err := ItemsIds("es", 162, 1002, 3, 4, 5)
	if err != nil {
		t.Errorf("Error getting %s in Spanish with multiple parameters! Got:\n%s", id, err.Error())
	} else if i[0].ID == 0 {
		t.Errorf("Empty output for %s in Spanish with multiple parameters!")
	}
	fmt.Printf("\t-%s\t\t", id)
	if !t.Failed() {
		fmt.Printf("OK\n")
	} else {
		fmt.Printf("FAILED\n")
	}
}

//DEEP OK
func TestItemsPages(t *testing.T) {
	//t.Skip()
	id := "ItemsPages"
	_, err := ItemsPages(-1, -1, "es")
	if err == nil {
		t.Errorf("No error calling %s with only lang!", id)
	}

	_, err = ItemsPages(-1, 0, "")
	if err == nil {
		t.Errorf("No error unmarshalled when calling %s with invalid parameters!", id)
	}

	i, err := ItemsPages(0, 0, "es")
	if err != nil {
		t.Errorf("Error getting %s in Spanish with multiple parameters! Got:\n%s", id, err.Error())
	} else if i == nil {
		t.Errorf("Empty output for %s in Spanish with multiple parameters!")
	}
	fmt.Printf("\t-%s\t\t", id)
	if !t.Failed() {
		fmt.Printf("OK\n")
	} else {
		fmt.Printf("FAILED\n")
	}
}

//DEEP OK
func TestItemsUnmarshalling(t *testing.T) {
	//t.Skip()
	id := "ItemsUnmarshalling"
	i, err := ItemsIds("", 162)
	if err != nil {
		t.Errorf("Error getting data for %s!", id)
	}
	if i[0].Name == "" {
		t.Errorf("%s: Empty Name!", id)
	}
	if i[0].Type == "" {
		t.Errorf("%s: Empty Type!", id)
	}
	if i[0].Level == 0 {
		t.Errorf("%s: Empty Level!", id)
	}
	if i[0].Rarity == "" {
		t.Errorf("%s: Empty Rarity!", id)
	}
	if i[0].VendorValue == 0 {
		t.Errorf("%s: Empty VendorValue!", id)
	}
	if i[0].DefaultSkin == 0 {
		t.Errorf("%s: Empty DefaultSkin!", id)
	}
	if i[0].GameTypes == nil {
		t.Errorf("%s: Empty GameTypes!", id)
	}
	if i[0].Flags == nil {
		t.Errorf("%s: Empty Flags!", id)
	}
	if i[0].ID == 0 {
		t.Errorf("%s: Empty ID!", id)
	}
	if i[0].Icon == "" {
		t.Errorf("%s: Empty Icon!", id)
	}
	if i[0].Details == nil {
		t.Errorf("%s: Empty Details!", id)
	}
	fmt.Printf("\t-%s\t", id)
	if !t.Failed() {
		fmt.Printf("OK\n")
	} else {
		fmt.Printf("FAILED\n")
	}
}
<|endoftext|>


<commit_before>// +build windows

package util

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"strings"

	"golang.org/x/crypto/ssh/terminal"
)

// IsPrivileged will return true if the current process is running as the
// Administrator
func IsPrivileged() bool {
	// Running "net session" will return "Access is denied." if the terminal
	// process was not run as Administrator
	cmd := exec.Command("net", "session")
	output, err := cmd.CombinedOutput()

	// if there was an error, we'll short-circuit and return false
	if err != nil {
		return false
	}

	// return false if we find Access is denied in the output
	if bytes.Contains(output, []byte("Access is denied.")) {
		return false
	}

	// if the previous checks didn't fail, then we must be the Administrator
	return true
}

// PrivilegeExec will run the requested command in a powershell as the Administrative user
func PrivilegeExec(command string) error {

	// Windows is tricky. Unfortunately we can't just prefix the command with sudo
	// Instead, we have to use powershell to create a profile, and then create
	// a process within powershell requesting Administrative permissions.
	//
	// Generating the command is complicated.
	// The following resources were used as documentation for the logic below:
	// https://msdn.microsoft.com/en-us/powershell/scripting/core-powershell/console/powershell.exe-command-line-help
	// http://ss64.com/ps/start-process.html
	// http://www.howtogeek.com/204088/how-to-use-a-batch-file-to-make-powershell-scripts-easier-to-run/

	// The process is constructed by passing the executable as a single argument
	// and the argument list as a space-delimited string in a single argument.
	//
	// Since the command is provided as a space-delimited string containing both
	// the executable and the argument list (just like a command would be entered
	// on the command prompt), we need to pop off the executable.

	// split the command into pieces using a space delimiter
	parts := strings.Split(command, " ")

	// extract the executable (the first item)
	executable := parts[0]

	// assemble the argument list from the rest of the parts
	arguments := strings.Join(parts[1:], " ")

	// generate the powershell process
	process := fmt.Sprintf("& {Start-Process %s -ArgumentList '%s' -Verb RunAs -Wait}", executable, arguments)

	// now we can generate a command to exec
	cmd := exec.Command("PowerShell.exe", "-NoProfile", "-Command", process, "--internal")

	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	// run command
	if err := cmd.Run(); err != nil {
		return err
	}

	return nil
}

// PowerShell will run a specified command in a powershell and return the result
func PowerShell(command string) ([]byte, error) {

	process := fmt.Sprintf("& {%s}", command)

	cmd := exec.Command("PowerShell.exe", "-NoProfile", "-Command", process)

	return cmd.CombinedOutput()
}

// TODO: write a windows version that squashes the warning (tyler knows)
func ReadPassword() (string, error) {
	fmt.Print("Password: ")
	pass, err := terminal.ReadPassword(int(os.Stdin.Fd()))
	fmt.Println("")

	return string(pass), err
}
<commit_msg>Fix windows privilege exec<commit_after>// +build windows

package util

import (
	"bytes"
	"fmt"
	"os"
	"os/exec"
	"strings"

	"golang.org/x/crypto/ssh/terminal"
)

// IsPrivileged will return true if the current process is running as the
// Administrator
func IsPrivileged() bool {
	// Running "net session" will return "Access is denied." if the terminal
	// process was not run as Administrator
	cmd := exec.Command("net", "session")
	output, err := cmd.CombinedOutput()

	// if there was an error, we'll short-circuit and return false
	if err != nil {
		return false
	}

	// return false if we find Access is denied in the output
	if bytes.Contains(output, []byte("Access is denied.")) {
		return false
	}

	// if the previous checks didn't fail, then we must be the Administrator
	return true
}

// PrivilegeExec will run the requested command in a powershell as the Administrative user
func PrivilegeExec(command string) error {

	// Windows is tricky. Unfortunately we can't just prefix the command with sudo
	// Instead, we have to use powershell to create a profile, and then create
	// a process within powershell requesting Administrative permissions.
	//
	// Generating the command is complicated.
	// The following resources were used as documentation for the logic below:
	// https://msdn.microsoft.com/en-us/powershell/scripting/core-powershell/console/powershell.exe-command-line-help
	// http://ss64.com/ps/start-process.html
	// http://www.howtogeek.com/204088/how-to-use-a-batch-file-to-make-powershell-scripts-easier-to-run/

	// The process is constructed by passing the executable as a single argument
	// and the argument list as a space-delimited string in a single argument.
	//
	// Since the command is provided as a space-delimited string containing both
	// the executable and the argument list (just like a command would be entered
	// on the command prompt), we need to pop off the executable.

	executable, arguments := splitExecutableAndArgs(command)

	// generate the powershell process
	process := fmt.Sprintf("& {Start-Process '%s' -ArgumentList '%s --internal' -Verb RunAs -Wait}", executable, arguments)

	// now we can generate a command to exec
	cmd := exec.Command("PowerShell.exe", "-NoProfile", "-Command", process)

	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	// run command
	if err := cmd.Run(); err != nil {
		return err
	}

	return nil
}

// PowerShell will run a specified command in a powershell and return the result
func PowerShell(command string) ([]byte, error) {

	process := fmt.Sprintf("& {%s}", command)

	cmd := exec.Command("PowerShell.exe", "-NoProfile", "-Command", process)

	return cmd.CombinedOutput()
}

// TODO: write a windows version that squashes the warning (tyler knows)
func ReadPassword() (string, error) {
	fmt.Print("Password: ")
	pass, err := terminal.ReadPassword(int(os.Stdin.Fd()))
	fmt.Println("")

	return string(pass), err
}

// extracts the executable from the args
func splitExecutableAndArgs(cmd string) (executable, args string) {

	if strings.Contains(cmd, ".exe") {
		// split the command by the .exe extension
		parts := strings.Split(cmd, ".exe ")
		// the first item is the executable
		executable = fmt.Sprintf("%s.exe", parts[0])
		// the second item are the args
		args = parts[1]
	} else {
		// split the command by spaces
		parts := strings.Split(cmd, " ")
		// extract the executable (the first item)
		executable = parts[0]
		// the remaining are the args
		args = strings.Join(parts[1:], " ")
	}

	return
}
<|endoftext|>


<commit_before>package shared

/*
 * This file contains helpers for interacting with the database
 * which will check for database errors at the various steps,
 * as well as re-try indefinately if the db is locked.
 */

import (
	"database/sql"
	"fmt"
	"runtime"
	"time"

	"github.com/mattn/go-sqlite3"
)

func PrintStack() {
	buf := make([]byte, 1<<16)
	runtime.Stack(buf, true)
	fmt.Printf("%s", buf)
}

func IsDbLockedError(err error) bool {
	if err == nil {
		return false
	}
	if err == sqlite3.ErrLocked || err == sqlite3.ErrBusy {
		return true
	}
	if err.Error() == "database is locked" {
		return true
	}
	return false
}

func TxCommit(tx *sql.Tx) error {
	for {
		err := tx.Commit()
		if err == nil {
			return nil
		}
		if !IsDbLockedError(err) {
			Debugf("Txcommit: error %q\n", err)
			return err
		}
		Debugf("Txcommit: db was locked\n")
		PrintStack()
		time.Sleep(1 * time.Second)
	}
}

func DbQueryRowScan(db *sql.DB, q string, args []interface{}, outargs []interface{}) error {
	for {
		err := db.QueryRow(q, args...).Scan(outargs...)
		if err == nil {
			return nil
		}
		if !IsDbLockedError(err) {
			Debugf("DbQuery: query %q error %q\n", q, err)
			return err
		}
		Debugf("DbQueryRowScan: query %q args %q, DB was locked\n", q, args)
		PrintStack()
		time.Sleep(1 * time.Second)
	}
}

func DbQuery(db *sql.DB, q string, args ...interface{}) (*sql.Rows, error) {
	for {
		result, err := db.Query(q, args...)
		if err == nil {
			return result, nil
		}
		if !IsDbLockedError(err) {
			Debugf("DbQuery: query %q error %q\n", q, err)
			return nil, err
		}
		Debugf("DbQuery: query %q args %q, DB was locked\n", q, args)
		PrintStack()
		time.Sleep(1 * time.Second)
	}
}

func doDbQueryScan(db *sql.DB, q string, args []interface{}, outargs []interface{}) ([][]interface{}, error) {
	rows, err := db.Query(q, args...)
	if err != nil {
		return [][]interface{}{}, err
	}
	defer rows.Close()
	result := [][]interface{}{}
	for rows.Next() {
		ptrargs := make([]interface{}, len(outargs))
		for i, _ := range outargs {
			switch t := outargs[i].(type) {
			case string:
				str := ""
				ptrargs[i] = &str
			case int:
				integer := 0
				ptrargs[i] = &integer
			default:
				return [][]interface{}{}, fmt.Errorf("Bad interface type: %s\n", t)
			}
		}
		err = rows.Scan(ptrargs...)
		if err != nil {
			return [][]interface{}{}, err
		}
		newargs := make([]interface{}, len(outargs))
		for i, _ := range ptrargs {
			switch t := outargs[i].(type) {
			case string:
				newargs[i] = *ptrargs[i].(*string)
			case int:
				newargs[i] = *ptrargs[i].(*int)
			default:
				return [][]interface{}{}, fmt.Errorf("Bad interface type: %s\n", t)
			}
		}
		result = append(result, newargs)
	}
	err = rows.Err()
	if err != nil {
		return [][]interface{}{}, err
	}
	return result, nil
}

/*
 * . q is the database query
 * . inargs is an array of interfaces containing the query arguments
 * . outfmt is an array of interfaces containing the right types of output
 *   arguments, i.e.
 *      var arg1 string
 *      var arg2 int
 *      outfmt := {}interface{}{arg1, arg2}
 *
 * The result will be an array (one per output row) of arrays (one per output argument)
 * of interfaces, containing pointers to the actual output arguments.
 */
func DbQueryScan(db *sql.DB, q string, inargs []interface{}, outfmt []interface{}) ([][]interface{}, error) {
	for {
		result, err := doDbQueryScan(db, q, inargs, outfmt)
		if err == nil {
			return result, nil
		}
		if !IsDbLockedError(err) {
			Debugf("DbQuery: query %q error %q\n", q, err)
			return nil, err
		}
		Debugf("DbQueryscan: query %q inargs %q, DB was locked\n", q, inargs)
		PrintStack()
		time.Sleep(1 * time.Second)
	}
}

func DbExec(db *sql.DB, q string, args ...interface{}) (sql.Result, error) {
	for {
		result, err := db.Exec(q, args...)
		if err == nil {
			return result, nil
		}
		if !IsDbLockedError(err) {
			Debugf("DbExec: query %q error %q\n", q, err)
			return nil, err
		}
		Debugf("DbExec: query %q args %q, DB was locked\n", q, args)
		PrintStack()
		time.Sleep(1 * time.Second)
	}
}
<commit_msg>shared.PrintStack: only print stack in debug mode<commit_after>package shared

/*
 * This file contains helpers for interacting with the database
 * which will check for database errors at the various steps,
 * as well as re-try indefinately if the db is locked.
 */

import (
	"database/sql"
	"fmt"
	"runtime"
	"time"

	"github.com/mattn/go-sqlite3"
)

func PrintStack() {
	if ! debug || logger == nil {
		return
	}

	buf := make([]byte, 1<<16)
	runtime.Stack(buf, true)
	Debugf("%s", buf)
}

func IsDbLockedError(err error) bool {
	if err == nil {
		return false
	}
	if err == sqlite3.ErrLocked || err == sqlite3.ErrBusy {
		return true
	}
	if err.Error() == "database is locked" {
		return true
	}
	return false
}

func TxCommit(tx *sql.Tx) error {
	for {
		err := tx.Commit()
		if err == nil {
			return nil
		}
		if !IsDbLockedError(err) {
			Debugf("Txcommit: error %q\n", err)
			return err
		}
		Debugf("Txcommit: db was locked\n")
		PrintStack()
		time.Sleep(1 * time.Second)
	}
}

func DbQueryRowScan(db *sql.DB, q string, args []interface{}, outargs []interface{}) error {
	for {
		err := db.QueryRow(q, args...).Scan(outargs...)
		if err == nil {
			return nil
		}
		if !IsDbLockedError(err) {
			Debugf("DbQuery: query %q error %q\n", q, err)
			return err
		}
		Debugf("DbQueryRowScan: query %q args %q, DB was locked\n", q, args)
		PrintStack()
		time.Sleep(1 * time.Second)
	}
}

func DbQuery(db *sql.DB, q string, args ...interface{}) (*sql.Rows, error) {
	for {
		result, err := db.Query(q, args...)
		if err == nil {
			return result, nil
		}
		if !IsDbLockedError(err) {
			Debugf("DbQuery: query %q error %q\n", q, err)
			return nil, err
		}
		Debugf("DbQuery: query %q args %q, DB was locked\n", q, args)
		PrintStack()
		time.Sleep(1 * time.Second)
	}
}

func doDbQueryScan(db *sql.DB, q string, args []interface{}, outargs []interface{}) ([][]interface{}, error) {
	rows, err := db.Query(q, args...)
	if err != nil {
		return [][]interface{}{}, err
	}
	defer rows.Close()
	result := [][]interface{}{}
	for rows.Next() {
		ptrargs := make([]interface{}, len(outargs))
		for i, _ := range outargs {
			switch t := outargs[i].(type) {
			case string:
				str := ""
				ptrargs[i] = &str
			case int:
				integer := 0
				ptrargs[i] = &integer
			default:
				return [][]interface{}{}, fmt.Errorf("Bad interface type: %s\n", t)
			}
		}
		err = rows.Scan(ptrargs...)
		if err != nil {
			return [][]interface{}{}, err
		}
		newargs := make([]interface{}, len(outargs))
		for i, _ := range ptrargs {
			switch t := outargs[i].(type) {
			case string:
				newargs[i] = *ptrargs[i].(*string)
			case int:
				newargs[i] = *ptrargs[i].(*int)
			default:
				return [][]interface{}{}, fmt.Errorf("Bad interface type: %s\n", t)
			}
		}
		result = append(result, newargs)
	}
	err = rows.Err()
	if err != nil {
		return [][]interface{}{}, err
	}
	return result, nil
}

/*
 * . q is the database query
 * . inargs is an array of interfaces containing the query arguments
 * . outfmt is an array of interfaces containing the right types of output
 *   arguments, i.e.
 *      var arg1 string
 *      var arg2 int
 *      outfmt := {}interface{}{arg1, arg2}
 *
 * The result will be an array (one per output row) of arrays (one per output argument)
 * of interfaces, containing pointers to the actual output arguments.
 */
func DbQueryScan(db *sql.DB, q string, inargs []interface{}, outfmt []interface{}) ([][]interface{}, error) {
	for {
		result, err := doDbQueryScan(db, q, inargs, outfmt)
		if err == nil {
			return result, nil
		}
		if !IsDbLockedError(err) {
			Debugf("DbQuery: query %q error %q\n", q, err)
			return nil, err
		}
		Debugf("DbQueryscan: query %q inargs %q, DB was locked\n", q, inargs)
		PrintStack()
		time.Sleep(1 * time.Second)
	}
}

func DbExec(db *sql.DB, q string, args ...interface{}) (sql.Result, error) {
	for {
		result, err := db.Exec(q, args...)
		if err == nil {
			return result, nil
		}
		if !IsDbLockedError(err) {
			Debugf("DbExec: query %q error %q\n", q, err)
			return nil, err
		}
		Debugf("DbExec: query %q args %q, DB was locked\n", q, args)
		PrintStack()
		time.Sleep(1 * time.Second)
	}
}
<|endoftext|>


<commit_before>// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package perms

import (
	"os"
	"path/filepath"
)

// ChmodR sets the permissions of all directories and optionally files to [perm]
// permissions.
func ChmodR(dir string, dirOnly bool, perm os.FileMode) error {
	return filepath.Walk(dir, func(name string, info os.FileInfo, err error) error {
		if err != nil || (dirOnly && !info.IsDir()) {
			return err
		}
		return os.Chmod(name, perm)
	})
}
<commit_msg>only attempt to chownr the directory if it exists<commit_after>// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package perms

import (
	"errors"
	"os"
	"path/filepath"
)

// ChmodR sets the permissions of all directories and optionally files to [perm]
// permissions.
func ChmodR(dir string, dirOnly bool, perm os.FileMode) error {
	if _, err := os.Stat(dir); errors.Is(err, os.ErrNotExist) {
		return nil
	}
	return filepath.Walk(dir, func(name string, info os.FileInfo, err error) error {
		if err != nil || (dirOnly && !info.IsDir()) {
			return err
		}
		return os.Chmod(name, perm)
	})
}
<|endoftext|>


<commit_before>// Copyright 2015 Yoshi Yamaguchi
//
// 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 shortener

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"path"
	"regexp"
	"time"

	"appengine"
	"appengine/datastore"
)

const (
	Version            = "0.1.0"
	starttime          = int64(1437625938157481) // around 2015 Jul 23 13:34
	timestampLeftShift = 22
)

var chars []byte // used for unique id generation.

var URLpattern = regexp.MustCompile(`(https?|ftp)://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?`)

// initChars initialize chars as sequence of 0-9A-Za-z
func initChars() {
	chars = make([]byte, 62)
	for i := 0; i < 10; i++ { // 0-9
		chars[i] = byte(48 + i)
	}
	for i := 0; i < 26; i++ { // A-Z
		chars[i+10] = byte(65 + i)
	}
	for i := 0; i < 26; i++ { // a-z
		chars[i+36] = byte(97 + i)
	}
}

// init setup chars and URL routers.
func init() {
	initChars()
	router := &RegexpHandler{}
	router.HandleFunc(`/`, top)
	router.HandleFunc(`/[0-9A-Za-z_\-]{10,}`, redirect)
	router.HandleFunc(`/version`, version)
	router.HandleFunc(`/shortener/v1`, shortener)
	http.Handle("/", router)
}

// version returns application version.
func version(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, Version)
}

// top returns UI front page.
func top(w http.ResponseWriter, r *http.Request) {

	fmt.Fprintf(w, "hello")
}

// shortener
func shortener(w http.ResponseWriter, r *http.Request) {
	req := URLRequest{}
	if r.Method != "POST" {
		http.Error(w, fmt.Sprintf("Methods but for POST are not allowed"), http.StatusMethodNotAllowed)
		return
	}
	data, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, fmt.Sprintf("Unexpected payload: %v", err), http.StatusInternalServerError)
		return
	}
	err = json.Unmarshal(data, &req)
	if err != nil {
		http.Error(w, fmt.Sprintf("JSON decode error: %v", err), http.StatusInternalServerError)
		return
	}

	if !URLpattern.MatchString(req.URL) {
		http.Error(w, fmt.Sprintf("parameter must be valid web URI"), http.StatusBadRequest)
		return
	}

	c := appengine.NewContext(r)
	id := uniqueid()
	e := &URLEntity{
		ID:  id,
		URL: req.URL,
	}
	key := datastore.NewIncompleteKey(c, "URL", nil)
	_, err = datastore.Put(c, key, e)
	if err != nil {
		http.Error(w, fmt.Sprintf("datastore put error: %v", err), http.StatusInternalServerError)
		return
	}
	entry, err := json.Marshal(e)
	if err != nil {
		http.Error(w, fmt.Sprintf("JSON encode error: %v", err), http.StatusInternalServerError)
		return
	}
	fmt.Fprintf(w, string(entry))
}

// redirect find specified shortened URL path from datastore and redirect to original URL.
func redirect(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	id := path.Base(r.URL.Path)
	es := []URLEntity{}
	keys, err := datastore.NewQuery("URL").Filter("ID=", id).GetAll(c, &es)
	if err != nil {
		http.Error(w, fmt.Sprintf("datastore error: %v", err), http.StatusInternalServerError)
	}
	if len(es) == 0 {
		http.Redirect(w, r, "/", http.StatusNotFound)
		return
	}
	original := es[0].URL
	es[0].Count += 1
	_, err = datastore.Put(c, keys[0], es[0])
	if err != nil {
		http.Error(w, fmt.Sprintf("datastore error: %v", err), http.StatusInternalServerError)
	}
	http.Redirect(w, r, original, http.StatusFound)
}

// uniqueid generates unique id from unix time in microsecond and randomnumber based on it,
// then convert it to base 62 number
func uniqueid() string {
	now := time.Now().UnixNano() / 1000
	delta := now - starttime
	rand.Seed(delta)
	n := rand.Intn(2 ^ timestampLeftShift)
	id := delta<<timestampLeftShift | int64(n)

	size := int64(len(chars))
	result := make([]byte, 36)
	i := 0
	for id > 0 {
		rem := id % size
		id = id / size
		result[i] = chars[rem]
		i++
	}
	return string(result[:i])
}
<commit_msg>changed url validator<commit_after>// Copyright 2015 Yoshi Yamaguchi
//
// 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 shortener

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"net/url"
	"path"
	"time"

	"appengine"
	"appengine/datastore"
)

const (
	Version            = "0.1.0"
	starttime          = int64(1437625938157481) // around 2015 Jul 23 13:34
	timestampLeftShift = 22
)

var chars []byte // used for unique id generation.

// initChars initialize chars as sequence of 0-9A-Za-z
func initChars() {
	chars = make([]byte, 62)
	for i := 0; i < 10; i++ { // 0-9
		chars[i] = byte(48 + i)
	}
	for i := 0; i < 26; i++ { // A-Z
		chars[i+10] = byte(65 + i)
	}
	for i := 0; i < 26; i++ { // a-z
		chars[i+36] = byte(97 + i)
	}
}

// init setup chars and URL routers.
func init() {
	initChars()
	router := &RegexpHandler{}
	router.HandleFunc(`/`, top)
	router.HandleFunc(`/[0-9A-Za-z_\-]{10,}`, redirect)
	router.HandleFunc(`/version`, version)
	router.HandleFunc(`/shortener/v1`, shortener)
	http.Handle("/", router)
}

// version returns application version.
func version(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, Version)
}

// top returns UI front page.
func top(w http.ResponseWriter, r *http.Request) {

	fmt.Fprintf(w, "hello")
}

// shortener
func shortener(w http.ResponseWriter, r *http.Request) {
	req := URLRequest{}
	if r.Method != "POST" {
		http.Error(w, fmt.Sprintf("Methods but for POST are not allowed"), http.StatusMethodNotAllowed)
		return
	}
	data, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, fmt.Sprintf("Unexpected payload: %v", err), http.StatusInternalServerError)
		return
	}
	err = json.Unmarshal(data, &req)
	if err != nil {
		http.Error(w, fmt.Sprintf("JSON decode error: %v", err), http.StatusInternalServerError)
		return
	}

	url, err := url.Parse(req.URL)
	if err != nil {
		http.Error(w, fmt.Sprintf("Invalid URL: %v", req.URL), http.StatusInternalServerError)
		return
	}
	switch url.Scheme {
	case "https", "http", "ftp":
		break
	default:
		http.Error(w, fmt.Sprintf("Scheme is not supported: %v", req.URL), http.StatusInternalServerError)
		return
	}

	c := appengine.NewContext(r)
	id := uniqueid()
	e := &URLEntity{
		ID:  id,
		URL: req.URL,
	}
	key := datastore.NewIncompleteKey(c, "URL", nil)
	_, err = datastore.Put(c, key, e)
	if err != nil {
		http.Error(w, fmt.Sprintf("datastore put error: %v", err), http.StatusInternalServerError)
		return
	}
	entry, err := json.Marshal(e)
	if err != nil {
		http.Error(w, fmt.Sprintf("JSON encode error: %v", err), http.StatusInternalServerError)
		return
	}
	fmt.Fprintf(w, string(entry))
}

// redirect find specified shortened URL path from datastore and redirect to original URL.
func redirect(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	id := path.Base(r.URL.Path)
	es := []URLEntity{}
	keys, err := datastore.NewQuery("URL").Filter("ID=", id).GetAll(c, &es)
	if err != nil {
		http.Error(w, fmt.Sprintf("datastore get error: %v", err), http.StatusInternalServerError)
		return
	}
	if len(es) == 0 {
		http.Redirect(w, r, "/", http.StatusNotFound)
		return
	}
	original := es[0].URL
	es[0].Count += 1
	_, err = datastore.Put(c, keys[0], &es[0])
	if err != nil {
		http.Error(w, fmt.Sprintf("datastore put error: %v", err), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, original, http.StatusFound)
}

// uniqueid generates unique id from unix time in microsecond and randomnumber based on it,
// then convert it to base 62 number
func uniqueid() string {
	now := time.Now().UnixNano() / 1000
	delta := now - starttime
	rand.Seed(delta)
	n := rand.Intn(2 ^ timestampLeftShift)
	id := delta<<timestampLeftShift | int64(n)

	size := int64(len(chars))
	result := make([]byte, 36)
	i := 0
	for id > 0 {
		rem := id % size
		id = id / size
		result[i] = chars[rem]
		i++
	}
	return string(result[:i])
}
<|endoftext|>


<commit_before>package fastimage

import "testing"

func TestPNGImage(t *testing.T) {
	t.Parallel()

	url := "http://fc08.deviantart.net/fs71/f/2012/214/7/c/futurama__bender_by_suzura-d59kq1p.png"

	imagetype, size, err := DetectImageType(url)
	if err != nil {
		t.Error("Failed to detect image type")
	}

	if size == nil {
		t.Error("Failed to detect image size")
	}

	if imagetype != PNG {
		t.Error("Image is not PNG")
	}

	if size.Width != 988 {
		t.Error("Image width is wrong")
	}

	if size.Height != 1240 {
		t.Error("Image height is wrong")
	}
}

func TestJPEGImage(t *testing.T) {
	t.Parallel()

	url := "http://upload.wikimedia.org/wikipedia/commons/9/9a/SKA_dishes_big.jpg"

	imagetype, size, err := DetectImageType(url)
	if err != nil {
		t.Error("Failed to detect image type")
	}

	if size == nil {
		t.Error("Failed to detect image size")
	}

	if imagetype != JPEG {
		t.Error("Image is not JPEG")
	}

	if size.Width != 5000 {
		t.Error("Image width is wrong")
	}

	if size.Height != 2813 {
		t.Error("Image height is wrong")
	}
}

func TestGIFImage(t *testing.T) {
	t.Parallel()

	url := "http://media.giphy.com/media/gXcIuJBbRi2Va/giphy.gif"

	imagetype, size, err := DetectImageType(url)
	if err != nil {
		t.Error("Failed to detect image type")
	}

	if size == nil {
		t.Error("Failed to detect image size")
	}

	if imagetype != GIF {
		t.Error("Image is not GIF")
	}

	if size.Width != 500 {
		t.Error("Image width is wrong")
	}

	if size.Height != 247 {
		t.Error("Image height is wrong")
	}
}

func TestBMPImage(t *testing.T) {
	t.Parallel()

	url := "http://www.ac-grenoble.fr/ien.vienne1-2/spip/IMG/bmp_Image004.bmp"

	imagetype, size, err := DetectImageType(url)
	if err != nil {
		t.Error("Failed to detect image type")
	}

	if imagetype != BMP {
		t.Error("Image is not BMP")
	}

	if size != nil {
		t.Error("We can't detect BMP size yet")
	}
}

func TestTIFFImage(t *testing.T) {
	t.Parallel()

	url := "http://www.fileformat.info/format/tiff/sample/c44cf1326c2240d38e9fca073bd7a805/download"

	imagetype, size, err := DetectImageType(url)
	if err != nil {
		t.Error("Failed to detect image type")
	}

	if imagetype != TIFF {
		t.Error("Image is not TIFF")
	}

	if size != nil {
		t.Error("We can't detect TIFF size yet")
	}

}
<commit_msg>Fixing GIF specs.<commit_after>package fastimage

import "testing"

func TestPNGImage(t *testing.T) {
	t.Parallel()

	url := "http://fc08.deviantart.net/fs71/f/2012/214/7/c/futurama__bender_by_suzura-d59kq1p.png"

	imagetype, size, err := DetectImageType(url)
	if err != nil {
		t.Error("Failed to detect image type")
	}

	if size == nil {
		t.Error("Failed to detect image size")
	}

	if imagetype != PNG {
		t.Error("Image is not PNG")
	}

	if size.Width != 988 {
		t.Error("Image width is wrong")
	}

	if size.Height != 1240 {
		t.Error("Image height is wrong")
	}
}

func TestJPEGImage(t *testing.T) {
	t.Parallel()

	url := "http://upload.wikimedia.org/wikipedia/commons/9/9a/SKA_dishes_big.jpg"

	imagetype, size, err := DetectImageType(url)
	if err != nil {
		t.Error("Failed to detect image type")
	}

	if size == nil {
		t.Error("Failed to detect image size")
	}

	if imagetype != JPEG {
		t.Error("Image is not JPEG")
	}

	if size.Width != 5000 {
		t.Error("Image width is wrong")
	}

	if size.Height != 2813 {
		t.Error("Image height is wrong")
	}
}

func TestGIFImage(t *testing.T) {
	t.Parallel()

	url := "http://media.giphy.com/media/gXcIuJBbRi2Va/giphy.gif"

	imagetype, size, err := DetectImageType(url)
	if err != nil {
		t.Error("Failed to detect image type")
	}

	if size == nil {
		t.Error("Failed to detect image size")
	}

	if imagetype != GIF {
		t.Error("Image is not GIF")
	}

	if size.Width != 500 {
		t.Error("Image width is wrong")
	}

	if size.Height != 286 {
		t.Error("Image height is wrong")
	}
}

func TestBMPImage(t *testing.T) {
	t.Parallel()

	url := "http://www.ac-grenoble.fr/ien.vienne1-2/spip/IMG/bmp_Image004.bmp"

	imagetype, size, err := DetectImageType(url)
	if err != nil {
		t.Error("Failed to detect image type")
	}

	if imagetype != BMP {
		t.Error("Image is not BMP")
	}

	if size != nil {
		t.Error("We can't detect BMP size yet")
	}
}

func TestTIFFImage(t *testing.T) {
	t.Parallel()

	url := "http://www.fileformat.info/format/tiff/sample/c44cf1326c2240d38e9fca073bd7a805/download"

	imagetype, size, err := DetectImageType(url)
	if err != nil {
		t.Error("Failed to detect image type")
	}

	if imagetype != TIFF {
		t.Error("Image is not TIFF")
	}

	if size != nil {
		t.Error("We can't detect TIFF size yet")
	}

}
<|endoftext|>