<commit_before>// +build !windows

package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
	"time"
	"unicode"

	"github.com/docker/docker/pkg/integration/checker"
	"github.com/go-check/check"
	"github.com/kr/pty"
)

// #5979
func (s *DockerSuite) TestEventsRedirectStdout(c *check.C) {
	since := daemonTime(c).Unix()
	dockerCmd(c, "run", "busybox", "true")

	file, err := ioutil.TempFile("", "")
	c.Assert(err, checker.IsNil, check.Commentf("could not create temp file"))
	defer os.Remove(file.Name())

	command := fmt.Sprintf("%s events --since=%d --until=%d > %s", dockerBinary, since, daemonTime(c).Unix(), file.Name())
	_, tty, err := pty.Open()
	c.Assert(err, checker.IsNil, check.Commentf("Could not open pty"))
	cmd := exec.Command("sh", "-c", command)
	cmd.Stdin = tty
	cmd.Stdout = tty
	cmd.Stderr = tty
	c.Assert(cmd.Run(), checker.IsNil, check.Commentf("run err for command %q", command))

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		for _, ch := range scanner.Text() {
			c.Assert(unicode.IsControl(ch), checker.False, check.Commentf("found control character %v", []byte(string(ch))))
		}
	}
	c.Assert(scanner.Err(), checker.IsNil, check.Commentf("Scan err for command %q", command))

}

func (s *DockerSuite) TestEventsOOMDisableFalse(c *check.C) {
	testRequires(c, DaemonIsLinux, oomControl, memoryLimitSupport, NotGCCGO)

	errChan := make(chan error)
	go func() {
		defer close(errChan)
		out, exitCode, _ := dockerCmdWithError("run", "--name", "oomFalse", "-m", "10MB", "busybox", "sh", "-c", "x=a; while true; do x=$x$x$x$x; done")
		if expected := 137; exitCode != expected {
			errChan <- fmt.Errorf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out)
		}
	}()
	select {
	case err := <-errChan:
		c.Assert(err, checker.IsNil)
	case <-time.After(30 * time.Second):
		c.Fatal("Timeout waiting for container to die on OOM")
	}

	out, _ := dockerCmd(c, "events", "--since=0", "-f", "container=oomFalse", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
	events := strings.Split(strings.TrimSuffix(out, "\n"), "\n")
	c.Assert(len(events), checker.GreaterOrEqualThan, 5) //Missing expected event

	createEvent := strings.Fields(events[len(events)-5])
	attachEvent := strings.Fields(events[len(events)-4])
	startEvent := strings.Fields(events[len(events)-3])
	oomEvent := strings.Fields(events[len(events)-2])
	dieEvent := strings.Fields(events[len(events)-1])
	c.Assert(createEvent[len(createEvent)-1], checker.Equals, "create", check.Commentf("event should be create, not %#v", createEvent))
	c.Assert(attachEvent[len(attachEvent)-1], checker.Equals, "attach", check.Commentf("event should be attach, not %#v", attachEvent))
	c.Assert(startEvent[len(startEvent)-1], checker.Equals, "start", check.Commentf("event should be start, not %#v", startEvent))
	c.Assert(oomEvent[len(oomEvent)-1], checker.Equals, "oom", check.Commentf("event should be oom, not %#v", oomEvent))
	c.Assert(dieEvent[len(dieEvent)-1], checker.Equals, "die", check.Commentf("event should be die, not %#v", dieEvent))
}

func (s *DockerSuite) TestEventsOOMDisableTrue(c *check.C) {
	testRequires(c, DaemonIsLinux, oomControl, memoryLimitSupport, NotGCCGO)

	errChan := make(chan error)
	go func() {
		defer close(errChan)
		out, exitCode, _ := dockerCmdWithError("run", "--oom-kill-disable=true", "--name", "oomTrue", "-m", "10MB", "busybox", "sh", "-c", "x=a; while true; do x=$x$x$x$x; done")
		if expected := 137; exitCode != expected {
			errChan <- fmt.Errorf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out)
		}
	}()
	select {
	case err := <-errChan:
		c.Assert(err, checker.IsNil)
	case <-time.After(20 * time.Second):
		defer dockerCmd(c, "kill", "oomTrue")

		out, _ := dockerCmd(c, "events", "--since=0", "-f", "container=oomTrue", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
		events := strings.Split(strings.TrimSuffix(out, "\n"), "\n")
		c.Assert(len(events), checker.GreaterOrEqualThan, 4) //Missing expected event

		createEvent := strings.Fields(events[len(events)-4])
		attachEvent := strings.Fields(events[len(events)-3])
		startEvent := strings.Fields(events[len(events)-2])
		oomEvent := strings.Fields(events[len(events)-1])

		c.Assert(createEvent[len(createEvent)-1], checker.Equals, "create", check.Commentf("event should be create, not %#v", createEvent))
		c.Assert(attachEvent[len(attachEvent)-1], checker.Equals, "attach", check.Commentf("event should be attach, not %#v", attachEvent))
		c.Assert(startEvent[len(startEvent)-1], checker.Equals, "start", check.Commentf("event should be start, not %#v", startEvent))
		c.Assert(oomEvent[len(oomEvent)-1], checker.Equals, "oom", check.Commentf("event should be oom, not %#v", oomEvent))

		out, _ = dockerCmd(c, "inspect", "-f", "{{.State.Status}}", "oomTrue")
		c.Assert(strings.TrimSpace(out), checker.Equals, "running", check.Commentf("container should be still running"))
	}
}
<commit_msg>Add tests for docker events -f container.<commit_after>// +build !windows

package main

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"strings"
	"time"
	"unicode"

	"github.com/docker/docker/pkg/integration/checker"
	"github.com/go-check/check"
	"github.com/kr/pty"
)

// #5979
func (s *DockerSuite) TestEventsRedirectStdout(c *check.C) {
	since := daemonTime(c).Unix()
	dockerCmd(c, "run", "busybox", "true")

	file, err := ioutil.TempFile("", "")
	c.Assert(err, checker.IsNil, check.Commentf("could not create temp file"))
	defer os.Remove(file.Name())

	command := fmt.Sprintf("%s events --since=%d --until=%d > %s", dockerBinary, since, daemonTime(c).Unix(), file.Name())
	_, tty, err := pty.Open()
	c.Assert(err, checker.IsNil, check.Commentf("Could not open pty"))
	cmd := exec.Command("sh", "-c", command)
	cmd.Stdin = tty
	cmd.Stdout = tty
	cmd.Stderr = tty
	c.Assert(cmd.Run(), checker.IsNil, check.Commentf("run err for command %q", command))

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		for _, ch := range scanner.Text() {
			c.Assert(unicode.IsControl(ch), checker.False, check.Commentf("found control character %v", []byte(string(ch))))
		}
	}
	c.Assert(scanner.Err(), checker.IsNil, check.Commentf("Scan err for command %q", command))

}

func (s *DockerSuite) TestEventsOOMDisableFalse(c *check.C) {
	testRequires(c, DaemonIsLinux, oomControl, memoryLimitSupport, NotGCCGO)

	errChan := make(chan error)
	go func() {
		defer close(errChan)
		out, exitCode, _ := dockerCmdWithError("run", "--name", "oomFalse", "-m", "10MB", "busybox", "sh", "-c", "x=a; while true; do x=$x$x$x$x; done")
		if expected := 137; exitCode != expected {
			errChan <- fmt.Errorf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out)
		}
	}()
	select {
	case err := <-errChan:
		c.Assert(err, checker.IsNil)
	case <-time.After(30 * time.Second):
		c.Fatal("Timeout waiting for container to die on OOM")
	}

	out, _ := dockerCmd(c, "events", "--since=0", "-f", "container=oomFalse", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
	events := strings.Split(strings.TrimSuffix(out, "\n"), "\n")
	c.Assert(len(events), checker.GreaterOrEqualThan, 5) //Missing expected event

	createEvent := strings.Fields(events[len(events)-5])
	attachEvent := strings.Fields(events[len(events)-4])
	startEvent := strings.Fields(events[len(events)-3])
	oomEvent := strings.Fields(events[len(events)-2])
	dieEvent := strings.Fields(events[len(events)-1])
	c.Assert(createEvent[len(createEvent)-1], checker.Equals, "create", check.Commentf("event should be create, not %#v", createEvent))
	c.Assert(attachEvent[len(attachEvent)-1], checker.Equals, "attach", check.Commentf("event should be attach, not %#v", attachEvent))
	c.Assert(startEvent[len(startEvent)-1], checker.Equals, "start", check.Commentf("event should be start, not %#v", startEvent))
	c.Assert(oomEvent[len(oomEvent)-1], checker.Equals, "oom", check.Commentf("event should be oom, not %#v", oomEvent))
	c.Assert(dieEvent[len(dieEvent)-1], checker.Equals, "die", check.Commentf("event should be die, not %#v", dieEvent))
}

func (s *DockerSuite) TestEventsOOMDisableTrue(c *check.C) {
	testRequires(c, DaemonIsLinux, oomControl, memoryLimitSupport, NotGCCGO)

	errChan := make(chan error)
	go func() {
		defer close(errChan)
		out, exitCode, _ := dockerCmdWithError("run", "--oom-kill-disable=true", "--name", "oomTrue", "-m", "10MB", "busybox", "sh", "-c", "x=a; while true; do x=$x$x$x$x; done")
		if expected := 137; exitCode != expected {
			errChan <- fmt.Errorf("wrong exit code for OOM container: expected %d, got %d (output: %q)", expected, exitCode, out)
		}
	}()
	select {
	case err := <-errChan:
		c.Assert(err, checker.IsNil)
	case <-time.After(20 * time.Second):
		defer dockerCmd(c, "kill", "oomTrue")

		out, _ := dockerCmd(c, "events", "--since=0", "-f", "container=oomTrue", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
		events := strings.Split(strings.TrimSuffix(out, "\n"), "\n")
		c.Assert(len(events), checker.GreaterOrEqualThan, 4) //Missing expected event

		createEvent := strings.Fields(events[len(events)-4])
		attachEvent := strings.Fields(events[len(events)-3])
		startEvent := strings.Fields(events[len(events)-2])
		oomEvent := strings.Fields(events[len(events)-1])

		c.Assert(createEvent[len(createEvent)-1], checker.Equals, "create", check.Commentf("event should be create, not %#v", createEvent))
		c.Assert(attachEvent[len(attachEvent)-1], checker.Equals, "attach", check.Commentf("event should be attach, not %#v", attachEvent))
		c.Assert(startEvent[len(startEvent)-1], checker.Equals, "start", check.Commentf("event should be start, not %#v", startEvent))
		c.Assert(oomEvent[len(oomEvent)-1], checker.Equals, "oom", check.Commentf("event should be oom, not %#v", oomEvent))

		out, _ = dockerCmd(c, "inspect", "-f", "{{.State.Status}}", "oomTrue")
		c.Assert(strings.TrimSpace(out), checker.Equals, "running", check.Commentf("container should be still running"))
	}
}

// #18453
func (s *DockerSuite) TestEventsContainerFilter(c *check.C) {
	testRequires(c, DaemonIsLinux)
	out, _ := dockerCmd(c, "run", "--name=foo", "-d", "busybox", "top")
	c1 := strings.TrimSpace(out)
	waitRun(c1)
	out, _ = dockerCmd(c, "run", "--name=bar", "-d", "busybox", "top")
	c2 := strings.TrimSpace(out)
	waitRun(c2)
	out, _ = dockerCmd(c, "events", "-f", "container=foo", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()))
	c.Assert(out, checker.Contains, c1, check.Commentf("Missing event of container (foo)"))
	c.Assert(out, checker.Not(checker.Contains), c2, check.Commentf("Should not contain event of container (bar)"))
}

// #18453
func (s *DockerSuite) TestEventsContainerFilterBeforeCreate(c *check.C) {
	testRequires(c, DaemonIsLinux)
	var (
		out string
		ch  chan struct{}
	)
	ch = make(chan struct{})

	// calculate the time it takes to create and start a container and sleep 2 seconds
	// this is to make sure the docker event will recevie the event of container
	since := daemonTime(c).Unix()
	id, _ := dockerCmd(c, "run", "-d", "busybox", "top")
	cID := strings.TrimSpace(id)
	waitRun(cID)
	time.Sleep(2 * time.Second)
	duration := daemonTime(c).Unix() - since

	go func() {
		out, _ = dockerCmd(c, "events", "-f", "container=foo", "--since=0", fmt.Sprintf("--until=%d", daemonTime(c).Unix()+2*duration))
		close(ch)
	}()
	// Sleep 2 second to wait docker event to start
	time.Sleep(2 * time.Second)
	id, _ = dockerCmd(c, "run", "--name=foo", "-d", "busybox", "top")
	cID = strings.TrimSpace(id)
	waitRun(cID)
	<-ch
	c.Assert(out, checker.Contains, cID, check.Commentf("Missing event of container (foo)"))
}
<|endoftext|>


<commit_before>package managed_images_test

import (
	"context"
	"fmt"
	"strings"

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

	"github.com/werf/werf/integration/pkg/suite_init"
	"github.com/werf/werf/integration/pkg/utils"
)

var _ = Describe("managed images", func() {
	BeforeEach(func() {
		SuiteData.CommitProjectWorktree(SuiteData.ProjectName, utils.FixturePath("default"), "initial commit")
	})

	for _, iName := range suite_init.ContainerRegistryImplementationListToCheck(true) {
		implementationName := iName

		Context("["+implementationName+"]", func() {
			BeforeEach(func() {
				repo := fmt.Sprintf("%s/%s", SuiteData.ContainerRegistryPerImplementation[iName].RegistryAddress, SuiteData.ProjectName)
				SuiteData.SetupRepo(context.Background(), repo, implementationName, SuiteData.StubsData)
			})

			It("ls should not return anything", func() {
				output := utils.SucceedCommandOutputString(
					SuiteData.GetProjectWorktree(SuiteData.ProjectName),
					SuiteData.WerfBinPath,
					"managed-images", "ls",
				)

				Ω(output).Should(BeEmpty())
			})

			It("add should work properly", func() {
				addManagedImage("test")
				Ω(isManagedImage("test")).Should(BeTrue())
			})

			When("managed-images test has been added", func() {
				managedImage := "test"

				BeforeEach(func() {
					addManagedImage(managedImage)
				})

				It("ls should return managed image", func() {
					Ω(isManagedImage(managedImage)).Should(BeTrue())
				})

				It("rm should remove managed-image", func() {
					rmManagedImage(managedImage)
					Ω(isManagedImage(managedImage)).Should(BeFalse())
				})
			})

			When("werf images have been built", func() {
				BeforeEach(func() {
					utils.RunSucceedCommand(
						SuiteData.GetProjectWorktree(SuiteData.ProjectName),
						SuiteData.WerfBinPath,
						"build",
					)
				})

				It("ls should return managed image", func() {
					Ω(isManagedImage("a")).Should(BeTrue())
					Ω(isManagedImage("b")).Should(BeTrue())
					Ω(isManagedImage("c")).Should(BeTrue())
					Ω(isManagedImage("d")).Should(BeFalse())
				})
			})
		})
	}
})

func addManagedImage(imageName string) {
	utils.RunSucceedCommand(
		SuiteData.GetProjectWorktree(SuiteData.ProjectName),
		SuiteData.WerfBinPath,
		"managed-images", "add", imageName,
	)
}

func rmManagedImage(imageName string) {
	utils.RunSucceedCommand(
		SuiteData.GetProjectWorktree(SuiteData.ProjectName),
		SuiteData.WerfBinPath,
		"managed-images", "rm", imageName,
	)
}

func isManagedImage(imageName string) bool {
	output := utils.SucceedCommandOutputString(
		SuiteData.GetProjectWorktree(SuiteData.ProjectName),
		SuiteData.WerfBinPath,
		"managed-images", "ls",
	)

	for _, managedImage := range strings.Fields(output) {
		if managedImage == imageName {
			return true
		}
	}

	return false
}
<commit_msg>[tests] Managed images suite: fix erroneous closure<commit_after>package managed_images_test

import (
	"context"
	"fmt"
	"strings"

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

	"github.com/werf/werf/integration/pkg/suite_init"
	"github.com/werf/werf/integration/pkg/utils"
)

var _ = Describe("managed images", func() {
	BeforeEach(func() {
		SuiteData.CommitProjectWorktree(SuiteData.ProjectName, utils.FixturePath("default"), "initial commit")
	})

	for _, iName := range suite_init.ContainerRegistryImplementationListToCheck(true) {
		implementationName := iName

		Context("["+implementationName+"]", func() {
			BeforeEach(func() {
				repo := fmt.Sprintf("%s/%s", SuiteData.ContainerRegistryPerImplementation[implementationName].RegistryAddress, SuiteData.ProjectName)
				SuiteData.SetupRepo(context.Background(), repo, implementationName, SuiteData.StubsData)
			})

			It("ls should not return anything", func() {
				output := utils.SucceedCommandOutputString(
					SuiteData.GetProjectWorktree(SuiteData.ProjectName),
					SuiteData.WerfBinPath,
					"managed-images", "ls",
				)

				Ω(output).Should(BeEmpty())
			})

			It("add should work properly", func() {
				addManagedImage("test")
				Ω(isManagedImage("test")).Should(BeTrue())
			})

			When("managed-images test has been added", func() {
				managedImage := "test"

				BeforeEach(func() {
					addManagedImage(managedImage)
				})

				It("ls should return managed image", func() {
					Ω(isManagedImage(managedImage)).Should(BeTrue())
				})

				It("rm should remove managed-image", func() {
					rmManagedImage(managedImage)
					Ω(isManagedImage(managedImage)).Should(BeFalse())
				})
			})

			When("werf images have been built", func() {
				BeforeEach(func() {
					utils.RunSucceedCommand(
						SuiteData.GetProjectWorktree(SuiteData.ProjectName),
						SuiteData.WerfBinPath,
						"build",
					)
				})

				It("ls should return managed image", func() {
					Ω(isManagedImage("a")).Should(BeTrue())
					Ω(isManagedImage("b")).Should(BeTrue())
					Ω(isManagedImage("c")).Should(BeTrue())
					Ω(isManagedImage("d")).Should(BeFalse())
				})
			})
		})
	}
})

func addManagedImage(imageName string) {
	utils.RunSucceedCommand(
		SuiteData.GetProjectWorktree(SuiteData.ProjectName),
		SuiteData.WerfBinPath,
		"managed-images", "add", imageName,
	)
}

func rmManagedImage(imageName string) {
	utils.RunSucceedCommand(
		SuiteData.GetProjectWorktree(SuiteData.ProjectName),
		SuiteData.WerfBinPath,
		"managed-images", "rm", imageName,
	)
}

func isManagedImage(imageName string) bool {
	output := utils.SucceedCommandOutputString(
		SuiteData.GetProjectWorktree(SuiteData.ProjectName),
		SuiteData.WerfBinPath,
		"managed-images", "ls",
	)

	for _, managedImage := range strings.Fields(output) {
		if managedImage == imageName {
			return true
		}
	}

	return false
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"io"
	"io/ioutil"
	"net/http"
	"os"

	"github.com/MJKWoolnough/byteio"
	"golang.org/x/net/websocket"
)

var transferFuncs = [...]func(Transfer, *byteio.StickyReader, *byteio.StickyWriter, *os.File) error{
	Transfer.server,
	Transfer.maps,
	Transfer.generate,
}

type downloadProgress struct {
	io.Reader
	*byteio.StickyWriter
}

func (d downloadProgress) Read(b []byte) (int, error) {
	n, err := d.Reader.Read(b)
	d.WriteUint8(1)
	d.WriteInt32(int32(n))
	return n, err
}

type Transfer struct {
	c *Config
}

func (t Transfer) Websocket(conn *websocket.Conn) {
	conn.PayloadType = websocket.BinaryFrame
	r := byteio.StickyReader{Reader: &byteio.LittleEndianReader{conn}}
	w := byteio.StickyWriter{Writer: &byteio.LittleEndianWriter{Writer: conn}}

	err := t.handle(&r, &w)
	if err != nil {
		writeError(&w, err)
	}
}

func (t Transfer) handle(r *byteio.StickyReader, w *byteio.StickyWriter) error {
	transferType := r.ReadUint8()

	if transferType>>1 > uint8(len(transferFuncs)) {
		return errors.New("invalid transfer type")
	}

	f, err := ioutil.TempFile("", "mineWebGen")
	if err != nil {
		return err
	}

	if transferType&1 == 0 {
		url := readString(r)
		if r.Err != nil {
			return err
		}
		resp, err := http.Get(url)
		if err != nil {
			return err
		}
		w.WriteInt32(int32(resp.ContentLength))
		_, err = io.Copy(f, downloadProgress{resp.Body, w})
		resp.Body.Close()
		if err != nil {
			return err
		}
	} else {
		length := r.ReadInt32()
		_, err := io.Copy(f, io.LimitReader(r, int64(length)))
		if err != nil {
			return err
		}
	}
	f.Seek(0, 0)
	err = transferFuncs[transferType>>1](t, r, w, f)
	if err != nil {
		return err
	}
	w.WriteUint8(255)
	return nil
}

func (Transfer) maps(*byteio.StickyReader, *byteio.StickyWriter, *os.File) error {
	return nil
}

func (Transfer) generate(*byteio.StickyReader, *byteio.StickyWriter, *os.File) error {
	return nil
}
<commit_msg>Removed method stub for Transfer.map<commit_after>package main

import (
	"errors"
	"io"
	"io/ioutil"
	"net/http"
	"os"

	"github.com/MJKWoolnough/byteio"
	"golang.org/x/net/websocket"
)

var transferFuncs = [...]func(Transfer, *byteio.StickyReader, *byteio.StickyWriter, *os.File) error{
	Transfer.server,
	Transfer.maps,
	Transfer.generate,
}

type downloadProgress struct {
	io.Reader
	*byteio.StickyWriter
}

func (d downloadProgress) Read(b []byte) (int, error) {
	n, err := d.Reader.Read(b)
	d.WriteUint8(1)
	d.WriteInt32(int32(n))
	return n, err
}

type Transfer struct {
	c *Config
}

func (t Transfer) Websocket(conn *websocket.Conn) {
	conn.PayloadType = websocket.BinaryFrame
	r := byteio.StickyReader{Reader: &byteio.LittleEndianReader{conn}}
	w := byteio.StickyWriter{Writer: &byteio.LittleEndianWriter{Writer: conn}}

	err := t.handle(&r, &w)
	if err != nil {
		writeError(&w, err)
	}
}

func (t Transfer) handle(r *byteio.StickyReader, w *byteio.StickyWriter) error {
	transferType := r.ReadUint8()

	if transferType>>1 > uint8(len(transferFuncs)) {
		return errors.New("invalid transfer type")
	}

	f, err := ioutil.TempFile("", "mineWebGen")
	if err != nil {
		return err
	}

	if transferType&1 == 0 {
		url := readString(r)
		if r.Err != nil {
			return err
		}
		resp, err := http.Get(url)
		if err != nil {
			return err
		}
		w.WriteInt32(int32(resp.ContentLength))
		_, err = io.Copy(f, downloadProgress{resp.Body, w})
		resp.Body.Close()
		if err != nil {
			return err
		}
	} else {
		length := r.ReadInt32()
		_, err := io.Copy(f, io.LimitReader(r, int64(length)))
		if err != nil {
			return err
		}
	}
	f.Seek(0, 0)
	err = transferFuncs[transferType>>1](t, r, w, f)
	if err != nil {
		return err
	}
	w.WriteUint8(255)
	return nil
}

func (Transfer) generate(*byteio.StickyReader, *byteio.StickyWriter, *os.File) error {
	return nil
}
<|endoftext|>


<commit_before>package convert

import (
	"github.com/stretchr/testify/require"
	"testing"
)

func TestToBool(t *testing.T) {
	v, err := ToBool("true")
	require.Nil(t, err)
	require.Equal(t, true, v)

	v, err = ToBool("1")
	require.Nil(t, err)
	require.Equal(t, true, v)

	v, err = ToBool("0")
	require.Nil(t, err)
	require.Equal(t, false, v)

	v, err = ToBool("false")
	require.Nil(t, err)
	require.Equal(t, false, v)

	v, err = ToBool("dsds3wr")
	require.NotNil(t, err)
}

func TestToInt(t *testing.T) {
	v, err := ToInt("1")
	require.Nil(t, err)
	require.Equal(t, 1, v)

	v, err = ToInt("-1")
	require.Nil(t, err)
	require.Equal(t, -1, v)

	v, err = ToInt("12345.12345")
	require.NotNil(t, err)

	v, err = ToInt("fgfert3")
	require.NotNil(t, err)
}

func TestToFloat(t *testing.T) {
	v, err := ToFloat("1")
	require.Nil(t, err)
	require.Equal(t, 1.0, v)

	v, err = ToFloat("-1")
	require.Nil(t, err)
	require.Equal(t, -1.0, v)

	v, err = ToFloat("12345.12345")
	require.Nil(t, err)
	require.Equal(t, 12345.12345, v)

	v, err = ToFloat("fgfert3")
	require.NotNil(t, err)
}

func TestToDate(t *testing.T) {
	v, err := ToDate("43308.7047106481")
	require.Nil(t, err)
	require.Equal(t, "2018-07-27 11:54:46 -0500 -05", v.String())

	v, err = ToDate("2018-07-27T17:40:58")
	require.Nil(t, err)
	require.Equal(t, "2018-07-27 17:40:58 +0000 UTC", v.String())

	v, err = ToDate("dsdsds")
	require.NotNil(t, err)
}
<commit_msg>fix test for dates and locale<commit_after>package convert

import (
	"github.com/stretchr/testify/require"
	"testing"
)

func TestToBool(t *testing.T) {
	v, err := ToBool("true")
	require.Nil(t, err)
	require.Equal(t, true, v)

	v, err = ToBool("1")
	require.Nil(t, err)
	require.Equal(t, true, v)

	v, err = ToBool("0")
	require.Nil(t, err)
	require.Equal(t, false, v)

	v, err = ToBool("false")
	require.Nil(t, err)
	require.Equal(t, false, v)

	v, err = ToBool("dsds3wr")
	require.NotNil(t, err)
}

func TestToInt(t *testing.T) {
	v, err := ToInt("1")
	require.Nil(t, err)
	require.Equal(t, 1, v)

	v, err = ToInt("-1")
	require.Nil(t, err)
	require.Equal(t, -1, v)

	v, err = ToInt("12345.12345")
	require.NotNil(t, err)

	v, err = ToInt("fgfert3")
	require.NotNil(t, err)
}

func TestToFloat(t *testing.T) {
	v, err := ToFloat("1")
	require.Nil(t, err)
	require.Equal(t, 1.0, v)

	v, err = ToFloat("-1")
	require.Nil(t, err)
	require.Equal(t, -1.0, v)

	v, err = ToFloat("12345.12345")
	require.Nil(t, err)
	require.Equal(t, 12345.12345, v)

	v, err = ToFloat("fgfert3")
	require.NotNil(t, err)
}

func TestToDate(t *testing.T) {
	v, err := ToDate("43308.7047106481")
	require.Nil(t, err)
	require.Equal(t, "2018-07-27T11:54:46", v.Format(ISO8601))

	v, err = ToDate("2018-07-27T17:40:58")
	require.Nil(t, err)
	require.Equal(t, "2018-07-27T17:40:58", v.Format(ISO8601))

	v, err = ToDate("dsdsds")
	require.NotNil(t, err)
}
<|endoftext|>


<commit_before>package service

import (
	"fmt"
	"strings"

	"github.com/docker/docker/api/client"
	"github.com/docker/docker/cli"
	"github.com/spf13/cobra"
	"golang.org/x/net/context"
)

func newRemoveCommand(dockerCli *client.DockerCli) *cobra.Command {

	cmd := &cobra.Command{
		Use:     "rm [OPTIONS] SERVICE",
		Aliases: []string{"remove"},
		Short:   "Remove a service",
		Args:    cli.RequiresMinArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			return runRemove(dockerCli, args)
		},
	}
	cmd.Flags()

	return cmd
}

func runRemove(dockerCli *client.DockerCli, sids []string) error {
	client := dockerCli.Client()

	ctx := context.Background()

	var errs []string
	for _, sid := range sids {
		err := client.ServiceRemove(ctx, sid)
		if err != nil {
			errs = append(errs, err.Error())
			continue
		}
		fmt.Fprintf(dockerCli.Out(), "%s\n", sid)
	}
	if len(errs) > 0 {
		return fmt.Errorf(strings.Join(errs, "\n"))
	}
	return nil
}
<commit_msg>Fix the usage for `service rm` command<commit_after>package service

import (
	"fmt"
	"strings"

	"github.com/docker/docker/api/client"
	"github.com/docker/docker/cli"
	"github.com/spf13/cobra"
	"golang.org/x/net/context"
)

func newRemoveCommand(dockerCli *client.DockerCli) *cobra.Command {

	cmd := &cobra.Command{
		Use:     "rm [OPTIONS] SERVICE [SERVICE...]",
		Aliases: []string{"remove"},
		Short:   "Remove a service",
		Args:    cli.RequiresMinArgs(1),
		RunE: func(cmd *cobra.Command, args []string) error {
			return runRemove(dockerCli, args)
		},
	}
	cmd.Flags()

	return cmd
}

func runRemove(dockerCli *client.DockerCli, sids []string) error {
	client := dockerCli.Client()

	ctx := context.Background()

	var errs []string
	for _, sid := range sids {
		err := client.ServiceRemove(ctx, sid)
		if err != nil {
			errs = append(errs, err.Error())
			continue
		}
		fmt.Fprintf(dockerCli.Out(), "%s\n", sid)
	}
	if len(errs) > 0 {
		return fmt.Errorf(strings.Join(errs, "\n"))
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2016 Circonus, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package api

import (
	"encoding/json"
	"fmt"
	"net/url"
	"regexp"
)

// CheckBundleConfig configuration specific to check type
type CheckBundleConfig struct {
	AsyncMetrics  bool   `json:"async_metrics"`
	Secret        string `json:"secret"`
	SubmissionURL string `json:"submission_url"`
	ReverseSecret string `json:"reverse:secret_key"`
	HTTPVersion   string `json:"http_version,omitempty"`
	Method        string `json:"method,omitempty"`
	Payload       string `json:"payload,omitempty"`
	Port          string `json:"port,omitempty"`
	ReadLimit     string `json:"read_limit,omitempty"`
	URL           string `json:"url,omitempty"`
}

// CheckBundleMetric individual metric configuration
type CheckBundleMetric struct {
	Name   string   `json:"name"`
	Type   string   `json:"type"`
	Units  string   `json:"units"`
	Status string   `json:"status"`
	Tags   []string `json:"tags"`
}

// CheckBundle definition
type CheckBundle struct {
	CheckUUIDs         []string            `json:"_check_uuids,omitempty"`
	Checks             []string            `json:"_checks,omitempty"`
	CID                string              `json:"_cid,omitempty"`
	Created            int                 `json:"_created,omitempty"`
	LastModified       int                 `json:"_last_modified,omitempty"`
	LastModifedBy      string              `json:"_last_modifed_by,omitempty"`
	ReverseConnectURLs []string            `json:"_reverse_connection_urls"`
	Brokers            []string            `json:"brokers"`
	Config             CheckBundleConfig   `json:"config"`
	DisplayName        string              `json:"display_name"`
	Metrics            []CheckBundleMetric `json:"metrics"`
	MetricLimit        int                 `json:"metric_limit"`
	Notes              string              `json:"notes"`
	Period             int                 `json:"period"`
	Status             string              `json:"status"`
	Tags               []string            `json:"tags"`
	Target             string              `json:"target"`
	Timeout            int                 `json:"timeout"`
	Type               string              `json:"type"`
}

var baseCheckBundlePath = "/check_bundle"

// FetchCheckBundleByID fetch a check bundle configuration by id
func (a *API) FetchCheckBundleByID(id IDType) (*CheckBundle, error) {
	cid := CIDType(fmt.Sprintf("%s/%d", baseCheckBundlePath, id))
	return a.FetchCheckBundleByCID(cid)
}

// FetchCheckBundleByCID fetch a check bundle configuration by id
func (a *API) FetchCheckBundleByCID(cid CIDType) (*CheckBundle, error) {
	if matched, err := regexp.MatchString("^"+baseCheckBundlePath+"/[0-9]+$", string(cid)); err != nil {
		return nil, err
	} else if !matched {
		return nil, fmt.Errorf("Invalid check bundle CID %v", cid)
	}

	reqURL := url.URL{
		Path: string(cid),
	}

	result, err := a.Get(reqURL.String())
	if err != nil {
		return nil, err
	}

	checkBundle := &CheckBundle{}
	if err := json.Unmarshal(result, checkBundle); err != nil {
		return nil, err
	}

	return checkBundle, nil
}

// CheckBundleSearch returns list of check bundles matching a search query
//    - a search query (see: https://login.circonus.com/resources/api#searching)
func (a *API) CheckBundleSearch(searchCriteria SearchQueryType) ([]CheckBundle, error) {
	reqURL := url.URL{
		Path: baseCheckBundlePath,
	}

	if searchCriteria != "" {
		q := url.Values{}
		q.Set("search", string(searchCriteria))
		reqURL.RawQuery = q.Encode()
	}

	resp, err := a.Get(reqURL.String())
	if err != nil {
		return nil, fmt.Errorf("[ERROR] API call error %+v", err)
	}

	var results []CheckBundle
	if err := json.Unmarshal(resp, &results); err != nil {
		return nil, err
	}

	return results, nil
}

// CheckBundleFilterSearch returns list of check bundles matching a search query and filter
//    - a search query (see: https://login.circonus.com/resources/api#searching)
//    - a filter (see: https://login.circonus.com/resources/api#filtering)
func (a *API) CheckBundleFilterSearch(searchCriteria SearchQueryType, filterCriteria map[string]string) ([]CheckBundle, error) {
	reqURL := url.URL{
		Path: baseCheckBundlePath,
	}

	if searchCriteria != "" {
		q := url.Values{}
		q.Set("search", string(searchCriteria))
		for field, val := range filterCriteria {
			q.Set(field, val)
		}
		reqURL.RawQuery = q.Encode()
	}

	resp, err := a.Get(reqURL.String())
	if err != nil {
		return nil, fmt.Errorf("[ERROR] API call error %+v", err)
	}

	var results []CheckBundle
	if err := json.Unmarshal(resp, &results); err != nil {
		return nil, err
	}

	return results, nil
}

// CreateCheckBundle create a new check bundle (check)
func (a *API) CreateCheckBundle(config *CheckBundle) (*CheckBundle, error) {
	reqURL := url.URL{
		Path: baseCheckBundlePath,
	}

	cfg, err := json.Marshal(config)
	if err != nil {
		return nil, err
	}

	resp, err := a.Post(reqURL.String(), cfg)
	if err != nil {
		return nil, err
	}

	checkBundle := &CheckBundle{}
	if err := json.Unmarshal(resp, checkBundle); err != nil {
		return nil, err
	}

	return checkBundle, nil
}

// UpdateCheckBundle updates a check bundle configuration
func (a *API) UpdateCheckBundle(config *CheckBundle) (*CheckBundle, error) {
	if matched, err := regexp.MatchString("^"+baseCheckBundlePath+"/[0-9]+$", string(config.CID)); err != nil {
		return nil, err
	} else if !matched {
		return nil, fmt.Errorf("Invalid check bundle CID %v", config.CID)
	}

	reqURL := url.URL{
		Path: config.CID,
	}

	cfg, err := json.Marshal(config)
	if err != nil {
		return nil, err
	}

	resp, err := a.Put(reqURL.String(), cfg)
	if err != nil {
		return nil, err
	}

	checkBundle := &CheckBundle{}
	if err := json.Unmarshal(resp, checkBundle); err != nil {
		return nil, err
	}

	return checkBundle, nil
}
<commit_msg>Decorate the CheckBundle object with `omitempty` where appropriate.<commit_after>// Copyright 2016 Circonus, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package api

import (
	"encoding/json"
	"fmt"
	"net/url"
	"regexp"
)

// CheckBundleConfig configuration specific to check type
type CheckBundleConfig struct {
	AsyncMetrics  bool   `json:"async_metrics"`
	Secret        string `json:"secret"`
	SubmissionURL string `json:"submission_url"`
	ReverseSecret string `json:"reverse:secret_key"`
	HTTPVersion   string `json:"http_version,omitempty"`
	Method        string `json:"method,omitempty"`
	Payload       string `json:"payload,omitempty"`
	Port          string `json:"port,omitempty"`
	ReadLimit     string `json:"read_limit,omitempty"`
	URL           string `json:"url,omitempty"`
}

// CheckBundleMetric individual metric configuration
type CheckBundleMetric struct {
	Name   string   `json:"name"`
	Type   string   `json:"type"`
	Units  string   `json:"units"`
	Status string   `json:"status"`
	Tags   []string `json:"tags"`
}

// CheckBundle definition
type CheckBundle struct {
	CheckUUIDs         []string            `json:"_check_uuids,omitempty"`
	Checks             []string            `json:"_checks,omitempty"`
	CID                string              `json:"_cid,omitempty"`
	Created            int                 `json:"_created,omitempty"`
	LastModified       int                 `json:"_last_modified,omitempty"`
	LastModifedBy      string              `json:"_last_modifed_by,omitempty"`
	ReverseConnectURLs []string            `json:"_reverse_connection_urls"`
	Brokers            []string            `json:"brokers"`
	Config             CheckBundleConfig   `json:"config"`
	DisplayName        string              `json:"display_name"`
	Metrics            []CheckBundleMetric `json:"metrics"`
	MetricLimit        int                 `json:"metric_limit,omitempty"`
	Notes              string              `json:"notes,omitempty"`
	Period             int                 `json:"period,omitempty"`
	Status             string              `json:"status,omitempty"`
	Tags               []string            `json:"tags,omitempty"`
	Target             string              `json:"target"`
	Timeout            int                 `json:"timeout,omitempty"`
	Type               string              `json:"type"`
}

var baseCheckBundlePath = "/check_bundle"

// FetchCheckBundleByID fetch a check bundle configuration by id
func (a *API) FetchCheckBundleByID(id IDType) (*CheckBundle, error) {
	cid := CIDType(fmt.Sprintf("%s/%d", baseCheckBundlePath, id))
	return a.FetchCheckBundleByCID(cid)
}

// FetchCheckBundleByCID fetch a check bundle configuration by id
func (a *API) FetchCheckBundleByCID(cid CIDType) (*CheckBundle, error) {
	if matched, err := regexp.MatchString("^"+baseCheckBundlePath+"/[0-9]+$", string(cid)); err != nil {
		return nil, err
	} else if !matched {
		return nil, fmt.Errorf("Invalid check bundle CID %v", cid)
	}

	reqURL := url.URL{
		Path: string(cid),
	}

	result, err := a.Get(reqURL.String())
	if err != nil {
		return nil, err
	}

	checkBundle := &CheckBundle{}
	if err := json.Unmarshal(result, checkBundle); err != nil {
		return nil, err
	}

	return checkBundle, nil
}

// CheckBundleSearch returns list of check bundles matching a search query
//    - a search query (see: https://login.circonus.com/resources/api#searching)
func (a *API) CheckBundleSearch(searchCriteria SearchQueryType) ([]CheckBundle, error) {
	reqURL := url.URL{
		Path: baseCheckBundlePath,
	}

	if searchCriteria != "" {
		q := url.Values{}
		q.Set("search", string(searchCriteria))
		reqURL.RawQuery = q.Encode()
	}

	resp, err := a.Get(reqURL.String())
	if err != nil {
		return nil, fmt.Errorf("[ERROR] API call error %+v", err)
	}

	var results []CheckBundle
	if err := json.Unmarshal(resp, &results); err != nil {
		return nil, err
	}

	return results, nil
}

// CheckBundleFilterSearch returns list of check bundles matching a search query and filter
//    - a search query (see: https://login.circonus.com/resources/api#searching)
//    - a filter (see: https://login.circonus.com/resources/api#filtering)
func (a *API) CheckBundleFilterSearch(searchCriteria SearchQueryType, filterCriteria map[string]string) ([]CheckBundle, error) {
	reqURL := url.URL{
		Path: baseCheckBundlePath,
	}

	if searchCriteria != "" {
		q := url.Values{}
		q.Set("search", string(searchCriteria))
		for field, val := range filterCriteria {
			q.Set(field, val)
		}
		reqURL.RawQuery = q.Encode()
	}

	resp, err := a.Get(reqURL.String())
	if err != nil {
		return nil, fmt.Errorf("[ERROR] API call error %+v", err)
	}

	var results []CheckBundle
	if err := json.Unmarshal(resp, &results); err != nil {
		return nil, err
	}

	return results, nil
}

// CreateCheckBundle create a new check bundle (check)
func (a *API) CreateCheckBundle(config *CheckBundle) (*CheckBundle, error) {
	reqURL := url.URL{
		Path: baseCheckBundlePath,
	}

	cfg, err := json.Marshal(config)
	if err != nil {
		return nil, err
	}

	resp, err := a.Post(reqURL.String(), cfg)
	if err != nil {
		return nil, err
	}

	checkBundle := &CheckBundle{}
	if err := json.Unmarshal(resp, checkBundle); err != nil {
		return nil, err
	}

	return checkBundle, nil
}

// UpdateCheckBundle updates a check bundle configuration
func (a *API) UpdateCheckBundle(config *CheckBundle) (*CheckBundle, error) {
	if matched, err := regexp.MatchString("^"+baseCheckBundlePath+"/[0-9]+$", string(config.CID)); err != nil {
		return nil, err
	} else if !matched {
		return nil, fmt.Errorf("Invalid check bundle CID %v", config.CID)
	}

	reqURL := url.URL{
		Path: config.CID,
	}

	cfg, err := json.Marshal(config)
	if err != nil {
		return nil, err
	}

	resp, err := a.Put(reqURL.String(), cfg)
	if err != nil {
		return nil, err
	}

	checkBundle := &CheckBundle{}
	if err := json.Unmarshal(resp, checkBundle); err != nil {
		return nil, err
	}

	return checkBundle, nil
}
<|endoftext|>


<commit_before>package main

import "fmt"

func main() {
	sum := 1
	for sum < 1000 {
		sum += sum
	}
	fmt.Println(sum)
}
<commit_msg>go-tour: Adding semicolons that were dropped by gofmt<commit_after>package main

import "fmt"

func main() {
	sum := 1
	for ; sum < 1000; {
		sum += sum
	}
	fmt.Println(sum)
}
<|endoftext|>


<commit_before>// Copyright 2016 The LUCI Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

package logdog

import (
	"fmt"
	"runtime"
	"time"

	"github.com/luci/luci-go/common/auth"
	"github.com/luci/luci-go/common/clock"
	"github.com/luci/luci-go/common/errors"
	ps "github.com/luci/luci-go/common/gcloud/pubsub"
	"github.com/luci/luci-go/common/lhttp"
	log "github.com/luci/luci-go/common/logging"
	"github.com/luci/luci-go/common/proto/google"
	"github.com/luci/luci-go/common/retry"
	"github.com/luci/luci-go/grpc/prpc"
	api "github.com/luci/luci-go/logdog/api/endpoints/coordinator/registration/v1"
	"github.com/luci/luci-go/logdog/client/butler/output"
	out "github.com/luci/luci-go/logdog/client/butler/output/pubsub"
	"github.com/luci/luci-go/logdog/common/types"
	"github.com/luci/luci-go/luci_config/common/cfgtypes"

	"cloud.google.com/go/pubsub"
	"golang.org/x/net/context"
	"google.golang.org/api/option"
)

// Scopes returns the set of OAuth scopes required for this Output.
func Scopes() []string {
	// E-mail scope needed for Coordinator authentication.
	scopes := []string{auth.OAuthScopeEmail}
	// Publisher scope needed to publish to Pub/Sub transport.
	scopes = append(scopes, ps.PublisherScopes...)

	return scopes
}

// Config is the set of configuration parameters for this Output instance.
type Config struct {
	// Auth is the Authenticator to use for registration and publishing. It should
	// be configured to hold the scopes returned by Scopes.
	Auth *auth.Authenticator

	// Host is the name of the LogDog Host to connect to.
	Host string

	// Project is the project that this stream belongs to.
	Project cfgtypes.ProjectName
	// Prefix is the stream prefix to register.
	Prefix types.StreamName
	// PrefixExpiration is the prefix expiration to use when registering.
	// If zero, no expiration will be expressed to the Coordinator, and it will
	// choose based on its configuration.
	PrefixExpiration time.Duration

	// SourceInfo, if not empty, is auxiliary source information to register
	// alongside the stream.
	SourceInfo []string

	// PublishContext is the special Context to use for publishing messages. If
	// nil, the Context supplied to Register will be used.
	//
	// This is useful when the Context supplied to Register responds to
	// cancellation (e.g., user sends SIGTERM), but we might not want to
	// immediately cancel pending publishes due to flushing.
	PublishContext context.Context

	// RPCTimeout, if > 0, is the timeout to apply to an individual RPC.
	RPCTimeout time.Duration

	// Track, if true, instructs this Output instance to track all log entries
	// that have been sent in-memory. This is useful for debugging.
	Track bool
}

// Register registers the supplied Prefix with the Coordinator. Upon success,
// an Output instance bound to that stream will be returned.
func (cfg *Config) Register(c context.Context) (output.Output, error) {
	// Validate our configuration parameters.
	switch {
	case cfg.Auth == nil:
		return nil, errors.New("no authenticator supplied")
	case cfg.Host == "":
		return nil, errors.New("no host supplied")
	}
	if err := cfg.Project.Validate(); err != nil {
		return nil, errors.Annotate(err).Reason("failed to validate project").
			D("project", cfg.Project).Err()
	}
	if err := cfg.Prefix.Validate(); err != nil {
		return nil, errors.Annotate(err).Reason("failed to validate prefix").
			D("prefix", cfg.Prefix).Err()
	}

	// Open a pRPC client to our Coordinator instance.
	httpClient, err := cfg.Auth.Client()
	if err != nil {
		log.WithError(err).Errorf(c, "Failed to get authenticated HTTP client.")
		return nil, err
	}

	// Configure our pRPC client.
	clientOpts := prpc.DefaultOptions()
	clientOpts.PerRPCTimeout = cfg.RPCTimeout
	client := prpc.Client{
		C:       httpClient,
		Host:    cfg.Host,
		Options: clientOpts,
	}

	// If our host begins with "localhost", set insecure option automatically.
	if lhttp.IsLocalHost(cfg.Host) {
		log.Infof(c, "Detected localhost; enabling insecure RPC connection.")
		client.Options.Insecure = true
	}

	// Register our Prefix with the Coordinator.
	log.Fields{
		"prefix": cfg.Prefix,
		"host":   cfg.Host,
	}.Debugf(c, "Registering prefix space with Coordinator service.")

	// Build our source info.
	sourceInfo := make([]string, 0, len(cfg.SourceInfo)+2)
	sourceInfo = append(sourceInfo, cfg.SourceInfo...)
	sourceInfo = append(sourceInfo,
		fmt.Sprintf("GOARCH=%s", runtime.GOARCH),
		fmt.Sprintf("GOOS=%s", runtime.GOOS),
	)

	svc := api.NewRegistrationPRPCClient(&client)
	resp, err := svc.RegisterPrefix(c, &api.RegisterPrefixRequest{
		Project:    string(cfg.Project),
		Prefix:     string(cfg.Prefix),
		SourceInfo: sourceInfo,
		Expiration: google.NewDuration(cfg.PrefixExpiration),
	})
	if err != nil {
		log.WithError(err).Errorf(c, "Failed to register prefix with Coordinator service.")
		return nil, err
	}
	log.Fields{
		"prefix":      cfg.Prefix,
		"bundleTopic": resp.LogBundleTopic,
	}.Debugf(c, "Successfully registered log stream prefix.")

	// Validate the response topic.
	fullTopic := ps.Topic(resp.LogBundleTopic)
	if err := fullTopic.Validate(); err != nil {
		log.Fields{
			log.ErrorKey: err,
			"fullTopic":  fullTopic,
		}.Errorf(c, "Coordinator returned invalid Pub/Sub topic.")
		return nil, err
	}

	// Split our topic into project and topic name. This must succeed, since we
	// just finished validating the topic.
	proj, topic := fullTopic.Split()

	// Instantiate our Pub/Sub instance.
	//
	// We will use the non-cancelling context, for all Pub/Sub calls, as we want
	// the Pub/Sub system to drain without interruption if the application is
	// otherwise canceled.
	pctx := cfg.PublishContext
	if pctx == nil {
		pctx = c
	}

	tokenSource, err := cfg.Auth.TokenSource()
	if err != nil {
		log.WithError(err).Errorf(c, "Failed to get TokenSource for Pub/Sub client.")
		return nil, err
	}

	psClient, err := pubsub.NewClient(pctx, proj, option.WithTokenSource(tokenSource))
	if err != nil {
		log.Fields{
			log.ErrorKey: err,
			"project":    proj,
		}.Errorf(c, "Failed to create Pub/Sub client.")
		return nil, errors.New("failed to get Pub/Sub client")
	}
	psTopic := psClient.Topic(topic)

	// Assert that our Topic exists.
	exists, err := retryTopicExists(c, psTopic, cfg.RPCTimeout)
	if err != nil {
		log.Fields{
			log.ErrorKey: err,
			"project":    proj,
			"topic":      topic,
		}.Errorf(c, "Failed to check for Pub/Sub topic.")
		return nil, errors.New("failed to check for Pub/Sub topic")
	}
	if !exists {
		log.Fields{
			"fullTopic": fullTopic,
		}.Errorf(c, "Pub/Sub Topic does not exist.")
		return nil, errors.New("PubSub topic does not exist")
	}

	// We own the prefix and all verifiable parameters have been validated.
	// Successfully return our Output instance.
	//
	// Note that we use our publishing context here.
	return out.New(pctx, out.Config{
		Topic:    psTopic,
		Secret:   resp.Secret,
		Compress: true,
		Track:    cfg.Track,
	}), nil
}

func retryTopicExists(ctx context.Context, t *pubsub.Topic, rpcTimeout time.Duration) (bool, error) {
	var exists bool
	err := retry.Retry(ctx, retry.Default, func() (err error) {
		if rpcTimeout > 0 {
			var cancelFunc context.CancelFunc
			ctx, cancelFunc = clock.WithTimeout(ctx, rpcTimeout)
			defer cancelFunc()
		}

		exists, err = t.Exists(ctx)
		return
	}, func(err error, d time.Duration) {
		log.Fields{
			log.ErrorKey: err,
			"delay":      d,
		}.Errorf(ctx, "Failed to check if topic exists; retrying...")
	})
	return exists, err
}
<commit_msg>LogDog/Butler: Fix Context deadline on retries.<commit_after>// Copyright 2016 The LUCI Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

package logdog

import (
	"fmt"
	"runtime"
	"time"

	"github.com/luci/luci-go/common/auth"
	"github.com/luci/luci-go/common/clock"
	"github.com/luci/luci-go/common/errors"
	ps "github.com/luci/luci-go/common/gcloud/pubsub"
	"github.com/luci/luci-go/common/lhttp"
	log "github.com/luci/luci-go/common/logging"
	"github.com/luci/luci-go/common/proto/google"
	"github.com/luci/luci-go/common/retry"
	"github.com/luci/luci-go/grpc/prpc"
	api "github.com/luci/luci-go/logdog/api/endpoints/coordinator/registration/v1"
	"github.com/luci/luci-go/logdog/client/butler/output"
	out "github.com/luci/luci-go/logdog/client/butler/output/pubsub"
	"github.com/luci/luci-go/logdog/common/types"
	"github.com/luci/luci-go/luci_config/common/cfgtypes"

	"cloud.google.com/go/pubsub"
	"golang.org/x/net/context"
	"google.golang.org/api/option"
)

// Scopes returns the set of OAuth scopes required for this Output.
func Scopes() []string {
	// E-mail scope needed for Coordinator authentication.
	scopes := []string{auth.OAuthScopeEmail}
	// Publisher scope needed to publish to Pub/Sub transport.
	scopes = append(scopes, ps.PublisherScopes...)

	return scopes
}

// Config is the set of configuration parameters for this Output instance.
type Config struct {
	// Auth is the Authenticator to use for registration and publishing. It should
	// be configured to hold the scopes returned by Scopes.
	Auth *auth.Authenticator

	// Host is the name of the LogDog Host to connect to.
	Host string

	// Project is the project that this stream belongs to.
	Project cfgtypes.ProjectName
	// Prefix is the stream prefix to register.
	Prefix types.StreamName
	// PrefixExpiration is the prefix expiration to use when registering.
	// If zero, no expiration will be expressed to the Coordinator, and it will
	// choose based on its configuration.
	PrefixExpiration time.Duration

	// SourceInfo, if not empty, is auxiliary source information to register
	// alongside the stream.
	SourceInfo []string

	// PublishContext is the special Context to use for publishing messages. If
	// nil, the Context supplied to Register will be used.
	//
	// This is useful when the Context supplied to Register responds to
	// cancellation (e.g., user sends SIGTERM), but we might not want to
	// immediately cancel pending publishes due to flushing.
	PublishContext context.Context

	// RPCTimeout, if > 0, is the timeout to apply to an individual RPC.
	RPCTimeout time.Duration

	// Track, if true, instructs this Output instance to track all log entries
	// that have been sent in-memory. This is useful for debugging.
	Track bool
}

// Register registers the supplied Prefix with the Coordinator. Upon success,
// an Output instance bound to that stream will be returned.
func (cfg *Config) Register(c context.Context) (output.Output, error) {
	// Validate our configuration parameters.
	switch {
	case cfg.Auth == nil:
		return nil, errors.New("no authenticator supplied")
	case cfg.Host == "":
		return nil, errors.New("no host supplied")
	}
	if err := cfg.Project.Validate(); err != nil {
		return nil, errors.Annotate(err).Reason("failed to validate project").
			D("project", cfg.Project).Err()
	}
	if err := cfg.Prefix.Validate(); err != nil {
		return nil, errors.Annotate(err).Reason("failed to validate prefix").
			D("prefix", cfg.Prefix).Err()
	}

	// Open a pRPC client to our Coordinator instance.
	httpClient, err := cfg.Auth.Client()
	if err != nil {
		log.WithError(err).Errorf(c, "Failed to get authenticated HTTP client.")
		return nil, err
	}

	// Configure our pRPC client.
	clientOpts := prpc.DefaultOptions()
	clientOpts.PerRPCTimeout = cfg.RPCTimeout
	client := prpc.Client{
		C:       httpClient,
		Host:    cfg.Host,
		Options: clientOpts,
	}

	// If our host begins with "localhost", set insecure option automatically.
	if lhttp.IsLocalHost(cfg.Host) {
		log.Infof(c, "Detected localhost; enabling insecure RPC connection.")
		client.Options.Insecure = true
	}

	// Register our Prefix with the Coordinator.
	log.Fields{
		"prefix": cfg.Prefix,
		"host":   cfg.Host,
	}.Debugf(c, "Registering prefix space with Coordinator service.")

	// Build our source info.
	sourceInfo := make([]string, 0, len(cfg.SourceInfo)+2)
	sourceInfo = append(sourceInfo, cfg.SourceInfo...)
	sourceInfo = append(sourceInfo,
		fmt.Sprintf("GOARCH=%s", runtime.GOARCH),
		fmt.Sprintf("GOOS=%s", runtime.GOOS),
	)

	svc := api.NewRegistrationPRPCClient(&client)
	resp, err := svc.RegisterPrefix(c, &api.RegisterPrefixRequest{
		Project:    string(cfg.Project),
		Prefix:     string(cfg.Prefix),
		SourceInfo: sourceInfo,
		Expiration: google.NewDuration(cfg.PrefixExpiration),
	})
	if err != nil {
		log.WithError(err).Errorf(c, "Failed to register prefix with Coordinator service.")
		return nil, err
	}
	log.Fields{
		"prefix":      cfg.Prefix,
		"bundleTopic": resp.LogBundleTopic,
	}.Debugf(c, "Successfully registered log stream prefix.")

	// Validate the response topic.
	fullTopic := ps.Topic(resp.LogBundleTopic)
	if err := fullTopic.Validate(); err != nil {
		log.Fields{
			log.ErrorKey: err,
			"fullTopic":  fullTopic,
		}.Errorf(c, "Coordinator returned invalid Pub/Sub topic.")
		return nil, err
	}

	// Split our topic into project and topic name. This must succeed, since we
	// just finished validating the topic.
	proj, topic := fullTopic.Split()

	// Instantiate our Pub/Sub instance.
	//
	// We will use the non-cancelling context, for all Pub/Sub calls, as we want
	// the Pub/Sub system to drain without interruption if the application is
	// otherwise canceled.
	pctx := cfg.PublishContext
	if pctx == nil {
		pctx = c
	}

	tokenSource, err := cfg.Auth.TokenSource()
	if err != nil {
		log.WithError(err).Errorf(c, "Failed to get TokenSource for Pub/Sub client.")
		return nil, err
	}

	psClient, err := pubsub.NewClient(pctx, proj, option.WithTokenSource(tokenSource))
	if err != nil {
		log.Fields{
			log.ErrorKey: err,
			"project":    proj,
		}.Errorf(c, "Failed to create Pub/Sub client.")
		return nil, errors.New("failed to get Pub/Sub client")
	}
	psTopic := psClient.Topic(topic)

	// Assert that our Topic exists.
	exists, err := retryTopicExists(c, psTopic, cfg.RPCTimeout)
	if err != nil {
		log.Fields{
			log.ErrorKey: err,
			"project":    proj,
			"topic":      topic,
		}.Errorf(c, "Failed to check for Pub/Sub topic.")
		return nil, errors.New("failed to check for Pub/Sub topic")
	}
	if !exists {
		log.Fields{
			"fullTopic": fullTopic,
		}.Errorf(c, "Pub/Sub Topic does not exist.")
		return nil, errors.New("PubSub topic does not exist")
	}

	// We own the prefix and all verifiable parameters have been validated.
	// Successfully return our Output instance.
	//
	// Note that we use our publishing context here.
	return out.New(pctx, out.Config{
		Topic:    psTopic,
		Secret:   resp.Secret,
		Compress: true,
		Track:    cfg.Track,
	}), nil
}

func retryTopicExists(ctx context.Context, t *pubsub.Topic, rpcTimeout time.Duration) (bool, error) {
	var exists bool
	err := retry.Retry(ctx, retry.Default, func() (err error) {
		ctx := ctx
		if rpcTimeout > 0 {
			var cancelFunc context.CancelFunc
			ctx, cancelFunc = clock.WithTimeout(ctx, rpcTimeout)
			defer cancelFunc()
		}

		exists, err = t.Exists(ctx)
		return
	}, func(err error, d time.Duration) {
		log.Fields{
			log.ErrorKey: err,
			"delay":      d,
		}.Errorf(ctx, "Failed to check if topic exists; retrying...")
	})
	return exists, err
}
<|endoftext|>


<commit_before>package rbt

import "fmt"

type color bool

const (
	red   color = true
	black color = false
)

type Ordered interface {
	Less(Ordered) bool
}

type node struct {
	color       color
	value       Ordered
	left, right *node
}

func newNode(c color, o Ordered, l, r *node) *node {
	return &node{
		color: c,
		value: o,
		left:  l,
		right: r,
	}
}

func (n *node) insert(o Ordered) *node {
	m := *n.insertRed(o)
	m.color = black
	return &m
}

func (n *node) insertRed(o Ordered) *node {
	if n == nil {
		return newNode(red, o, nil, nil)
	}

	m := *n

	if o.Less(n.value) {
		m.left = m.left.insertRed(o)
	} else if n.value.Less(o) {
		m.right = m.right.insertRed(o)
	} else {
		return n
	}

	return m.balance()
}

func (n *node) balance() *node {
	if n.color == red {
		return n
	}

	newN := func(
		o Ordered,
		lo Ordered, ll, lr *node,
		ro Ordered, rl, rr *node) *node {
		return newNode(red, o, newNode(black, lo, ll, lr), newNode(black, ro, rl, rr))
	}

	l := n.left
	r := n.right

	if l != nil && l.color == red {
		ll := l.left
		lr := l.right

		newLN := func(o, lo Ordered, ll, lr, rl *node) *node {
			return newN(o, lo, ll, lr, n.value, rl, r)
		}

		if ll != nil && ll.color == red {
			return newLN(l.value, ll.value, ll.left, ll.right, lr)
		} else if lr != nil && lr.color == red {
			return newLN(lr.value, l.value, ll, lr.left, lr.right)
		}
	} else if r != nil && r.color == red {
		rl := r.left
		rr := r.right

		newRN := func(o, ro Ordered, lr, rl, rr *node) *node {
			return newN(o, n.value, l, lr, ro, rl, rr)
		}

		if rr != nil && rr.color == red {
			return newRN(r.value, rr.value, rl, rr.left, rr.right)
		} else if rl != nil && rl.color == red {
			return newRN(rl.value, r.value, rl.left, rl.right, rr)
		}
	}

	return n
}

func (n *node) search(o Ordered) (Ordered, bool) {
	if n == nil {
		return nil, false
	} else if o.Less(n.value) {
		return n.left.search(o)
	} else if n.value.Less(o) {
		return n.right.search(o)
	}

	return n.value, true
}

func (n *node) remove(o Ordered) (*node, bool) {
	_, ok := n.search(o)

	if !ok {
		return n, false
	}

	n, _ = n.removeOne(o)
	m := *n
	m.color = black
	return &m, true
}

func (n *node) removeOne(o Ordered) (*node, bool) {
	if n == nil {
		return nil, true
	} else if o.Less(n.value) {
		l, balanced := n.left.removeOne(o)
		m := *n
		m.left = l

		if balanced {
			return &m, true
		}

		return m.balanceLeft()
	} else if n.value.Less(o) {
		r, balanced := n.right.removeOne(o)
		m := *n
		m.right = r

		if balanced {
			return &m, true
		}

		return m.balanceRight()
	}

	if n.left == nil {
		return n.right, n.color == red
	}

	o, l, balanced := n.takeMax()

	m := newNode(n.color, o, l, n.right)

	if balanced {
		return m, true
	}

	return m.balanceLeft()
}

func (n *node) takeMax() (Ordered, *node, bool) {
	if n.right == nil {
		return n.value, n.left, n.color == red
	}

	o, r, balanced := n.right.takeMax()

	m := *n
	m.right = r

	if balanced {
		return o, &m, true
	}

	n, balanced = m.balanceRight()
	return o, n, balanced
}

func (n *node) balanceLeft() (*node, bool) {
	if n.right.color == red {
		l, _ := newNode(red, n.value, n.left, n.right.left).balanceLeft()
		return newNode(black, n.right.value, l, n.right.right), true
	}

	if n.right.left != nil && n.right.left.color == red {
		return newNode(
			n.color,
			n.right.left.value,
			newNode(black, n.value, n.left, n.right.left.left),
			newNode(black, n.right.value, n.right.left.right, n.right.right)), true
	} else if n.right.right != nil && n.right.right.color == red {
		r := *n.right.right
		r.color = black

		return newNode(
			n.color,
			n.right.value,
			newNode(black, n.value, n.left, n.right.left),
			&r), true
	}

	r := *n.right
	r.color = red

	m := *n
	m.color = black
	m.right = &r

	return &m, n.color == black
}

func (n *node) balanceRight() (*node, bool) {
	if n.left.color == red {
		r, _ := newNode(red, n.value, n.left.right, n.right).balanceRight()
		return newNode(black, n.left.value, n.left.left, r), true
	}

	if n.left.right != nil && n.left.right.color == red {
		return newNode(
			n.color,
			n.left.right.value,
			newNode(black, n.left.value, n.left.left, n.left.right.left),
			newNode(black, n.value, n.left.right.right, n.right)), true
	} else if n.left.left != nil && n.left.left.color == red {
		l := *n.left.left
		l.color = black

		return newNode(
			n.color,
			n.left.value,
			&l,
			newNode(black, n.value, n.left.right, n.right)), true
	}

	l := *n.left
	l.color = red

	m := *n
	m.color = black
	m.left = &l

	return &m, n.color == black
}

func (n *node) dump() {
	n.dumpWithIndent(0)
}

func (n *node) dumpWithIndent(i int) {
	for j := 0; j < i; j++ {
		fmt.Printf(" ")
	}

	if n == nil {
		fmt.Println(nil)
		return
	}

	fmt.Println(n.color, n.value)

	k := i + 2
	n.right.dumpWithIndent(k)
	n.left.dumpWithIndent(k)
}
<commit_msg>Fix remove<commit_after>package rbt

import "fmt"

type color bool

const (
	red   color = true
	black color = false
)

type Ordered interface {
	Less(Ordered) bool
}

type node struct {
	color       color
	value       Ordered
	left, right *node
}

func newNode(c color, o Ordered, l, r *node) *node {
	return &node{
		color: c,
		value: o,
		left:  l,
		right: r,
	}
}

func (n *node) insert(o Ordered) *node {
	m := *n.insertRed(o)
	m.color = black
	return &m
}

func (n *node) insertRed(o Ordered) *node {
	if n == nil {
		return newNode(red, o, nil, nil)
	}

	m := *n

	if o.Less(n.value) {
		m.left = m.left.insertRed(o)
	} else if n.value.Less(o) {
		m.right = m.right.insertRed(o)
	} else {
		return n
	}

	return m.balance()
}

func (n *node) balance() *node {
	if n.color == red {
		return n
	}

	newN := func(
		o Ordered,
		lo Ordered, ll, lr *node,
		ro Ordered, rl, rr *node) *node {
		return newNode(red, o, newNode(black, lo, ll, lr), newNode(black, ro, rl, rr))
	}

	l := n.left
	r := n.right

	if l != nil && l.color == red {
		ll := l.left
		lr := l.right

		newLN := func(o, lo Ordered, ll, lr, rl *node) *node {
			return newN(o, lo, ll, lr, n.value, rl, r)
		}

		if ll != nil && ll.color == red {
			return newLN(l.value, ll.value, ll.left, ll.right, lr)
		} else if lr != nil && lr.color == red {
			return newLN(lr.value, l.value, ll, lr.left, lr.right)
		}
	} else if r != nil && r.color == red {
		rl := r.left
		rr := r.right

		newRN := func(o, ro Ordered, lr, rl, rr *node) *node {
			return newN(o, n.value, l, lr, ro, rl, rr)
		}

		if rr != nil && rr.color == red {
			return newRN(r.value, rr.value, rl, rr.left, rr.right)
		} else if rl != nil && rl.color == red {
			return newRN(rl.value, r.value, rl.left, rl.right, rr)
		}
	}

	return n
}

func (n *node) search(o Ordered) (Ordered, bool) {
	if n == nil {
		return nil, false
	} else if o.Less(n.value) {
		return n.left.search(o)
	} else if n.value.Less(o) {
		return n.right.search(o)
	}

	return n.value, true
}

func (n *node) remove(o Ordered) (*node, bool) {
	_, ok := n.search(o)

	if !ok {
		return n, false
	}

	n, _ = n.removeOne(o)

	if n == nil {
		return nil, true
	}

	m := *n
	m.color = black
	return &m, true
}

func (n *node) removeOne(o Ordered) (*node, bool) {
	if n == nil {
		return nil, true
	} else if o.Less(n.value) {
		l, balanced := n.left.removeOne(o)
		m := *n
		m.left = l

		if balanced {
			return &m, true
		}

		return m.balanceLeft()
	} else if n.value.Less(o) {
		r, balanced := n.right.removeOne(o)
		m := *n
		m.right = r

		if balanced {
			return &m, true
		}

		return m.balanceRight()
	}

	if n.left == nil {
		return n.right, n.color == red
	}

	o, l, balanced := n.takeMax()

	m := newNode(n.color, o, l, n.right)

	if balanced {
		return m, true
	}

	return m.balanceLeft()
}

func (n *node) takeMax() (Ordered, *node, bool) {
	if n.right == nil {
		return n.value, n.left, n.color == red
	}

	o, r, balanced := n.right.takeMax()

	m := *n
	m.right = r

	if balanced {
		return o, &m, true
	}

	n, balanced = m.balanceRight()
	return o, n, balanced
}

func (n *node) balanceLeft() (*node, bool) {
	if n.right.color == red {
		l, _ := newNode(red, n.value, n.left, n.right.left).balanceLeft()
		return newNode(black, n.right.value, l, n.right.right), true
	}

	if n.right.left != nil && n.right.left.color == red {
		return newNode(
			n.color,
			n.right.left.value,
			newNode(black, n.value, n.left, n.right.left.left),
			newNode(black, n.right.value, n.right.left.right, n.right.right)), true
	} else if n.right.right != nil && n.right.right.color == red {
		r := *n.right.right
		r.color = black

		return newNode(
			n.color,
			n.right.value,
			newNode(black, n.value, n.left, n.right.left),
			&r), true
	}

	r := *n.right
	r.color = red

	m := *n
	m.color = black
	m.right = &r

	return &m, n.color == black
}

func (n *node) balanceRight() (*node, bool) {
	if n.left.color == red {
		r, _ := newNode(red, n.value, n.left.right, n.right).balanceRight()
		return newNode(black, n.left.value, n.left.left, r), true
	}

	if n.left.right != nil && n.left.right.color == red {
		return newNode(
			n.color,
			n.left.right.value,
			newNode(black, n.left.value, n.left.left, n.left.right.left),
			newNode(black, n.value, n.left.right.right, n.right)), true
	} else if n.left.left != nil && n.left.left.color == red {
		l := *n.left.left
		l.color = black

		return newNode(
			n.color,
			n.left.value,
			&l,
			newNode(black, n.value, n.left.right, n.right)), true
	}

	l := *n.left
	l.color = red

	m := *n
	m.color = black
	m.left = &l

	return &m, n.color == black
}

func (n *node) dump() {
	n.dumpWithIndent(0)
}

func (n *node) dumpWithIndent(i int) {
	for j := 0; j < i; j++ {
		fmt.Printf(" ")
	}

	if n == nil {
		fmt.Println(nil)
		return
	}

	fmt.Println(n.color, n.value)

	k := i + 2
	n.right.dumpWithIndent(k)
	n.left.dumpWithIndent(k)
}
<|endoftext|>


<commit_before>package types

import (
	"fmt"
	"unicode/utf8"
)

//
// Recipe Creation Types
//

type Recipe struct {
	Title        string       `json:"title" validate:"recipetitle"`
	Notes        string       `json:"notes" validate:"recipenotes"`
	Ingredients  []Ingredient `json:"ingredients" validate:"existence"`
	CookTime     int          `json:"cooktime" validate:"time"`
	CookTimeUnit string       `json:"cooktimeunit" validate:"timeunit"`
	PrepTime     int          `json:"preptime" validate:"time"`
	PrepTimeUnit string       `json:"preptimeunit" validate:"timeunit"`
	Steps        []Step       `json:"steps" validate:"existence"`
	Tags         []Tag        `json:"tags"`
	Private      bool         `json:"private"`
}

//
// Recipe Component Types
//

type Ingredient struct {
	Name       string `json:"name" validate:"ingredient"`
	Amount     int    `json:"amount"`
	AmountUnit string `json:"amountunit"`
	URL        string `json:"url" validate:"url"`
}

type Step struct {
	Instruction string `json:"instruction" validate:"step"`
	Time        int    `json:"time" validate:"time"`
	TimeUnit    string `json:"timeunit" validate:"timeunit"`
}

//
// Recipe Tag Types
//

type Tag struct {
	Name string `json:"name" validate:"tag"`
}

//
// Recipe Validator Functions
//

func (v RicettaValidator) validateTimeUnit(i interface{}) error {
	timeUnit := i.(string)
	if timeUnit == "" {
		return fmt.Errorf("Required field")
	} else if !v.Constants.TIME_UNIT_REGEX.MatchString(timeUnit) {
		return fmt.Errorf(timeUnit + " is not a valid unit of time - [sec(s), min(s), hr(s), day(s), week(s)]")
	} else {
		return nil
	}
}

func (v RicettaValidator) validateTime(i interface{}) error {
	time, ok := i.(int)
	if !ok {
		return fmt.Errorf("Required field")
	} else if time <= 0 || time > 1000 {
		return fmt.Errorf("Invalid time unit: %d", time)
	} else {
		return nil
	}
}

func (v RicettaValidator) validateRecipeTitle(i interface{}) error {
	title := i.(string)
	titlelen := utf8.RuneCountInString(title)
	if title == "" {
		return fmt.Errorf("Required field")
	} else if titlelen > v.Constants.MAX_RECIPE_TITLE_LENGTH {
		return fmt.Errorf("Exceeds max title length of %d", v.Constants.MAX_RECIPE_TITLE_LENGTH)
	} else {
		return nil
	}
}

func (v RicettaValidator) validateRecipeNotes(i interface{}) error {
	notes := i.(string)
	noteslen := utf8.RuneCountInString(notes)
	if notes == "" {
		return fmt.Errorf("Required field")
	} else if noteslen > v.Constants.MAX_RECIPE_NOTES_LENGTH {
		return fmt.Errorf("Exceeds max notes length of %d", v.Constants.MAX_RECIPE_NOTES_LENGTH)
	} else {
		return nil
	}
}

func (v RicettaValidator) validateIngredient(i interface{}) error {
	ingredient := i.(string)
	ingredientlen := utf8.RuneCountInString(ingredient)
	if ingredient == "" {
		return fmt.Errorf("Required field")
	} else if ingredientlen > v.Constants.MAX_INGREDIENT_LENGTH {
		return fmt.Errorf("Exceeds max ingredient length of %d", v.Constants.MAX_INGREDIENT_LENGTH)
	} else {
		return nil
	}
}

func (v RicettaValidator) validateStep(i interface{}) error {
	step := i.(string)
	steplen := utf8.RuneCountInString(step)
	if step == "" {
		return fmt.Errorf("Required field")
	} else if steplen > v.Constants.MAX_STEP_LENGTH {
		return fmt.Errorf("Exceeds max step length of %d", v.Constants.MAX_STEP_LENGTH)
	} else {
		return nil
	}
}

func (v RicettaValidator) validateURL(i interface{}) error {
	url := i.(string)
	if url == "" {
		// This demonstrates how to validate an optional field
		return nil
	} else if !v.Constants.URL_REGEX.MatchString(url) {
		return fmt.Errorf("Not a valid URL string: %s", url)
	} else {
		return nil
	}
}

func (v RicettaValidator) validateTag(i interface{}) error {
	tag := i.(string)
	taglen := utf8.RuneCountInString(tag)
	if tag == "" {
		return fmt.Errorf("Required field")
	} else if taglen > v.Constants.MAX_TAG_LENGTH {
		return fmt.Errorf("Exceeds max tag length of %d", v.Constants.MAX_TAG_LENGTH)
	} else {
		return nil
	}
}
<commit_msg>Added slice types for Recipe data structures<commit_after>package types

import (
	"fmt"
	"unicode/utf8"
)

//
// Recipe Creation Types
//

type Recipe struct {
	Title        string      `json:"title" validate:"recipetitle"`
	Notes        string      `json:"notes" validate:"recipenotes"`
	Ingredients  Ingredients `json:"ingredients" validate:"existence"`
	CookTime     int         `json:"cooktime" validate:"time"`
	CookTimeUnit string      `json:"cooktimeunit" validate:"timeunit"`
	PrepTime     int         `json:"preptime" validate:"time"`
	PrepTimeUnit string      `json:"preptimeunit" validate:"timeunit"`
	Steps        Steps       `json:"steps" validate:"existence"`
	Tags         Tags        `json:"tags"`
	Private      bool        `json:"private"`
}

//
// Recipe Component Types
//

type Ingredient struct {
	Id         int    `json:"id"`
	Name       string `json:"name" validate:"ingredient"`
	Amount     int    `json:"amount"`
	AmountUnit string `json:"amountunit"`
	URL        string `json:"url" validate:"url"`
}

type Step struct {
	Id          int    `json:"id"`
	Instruction string `json:"instruction" validate:"step"`
	Time        int    `json:"time" validate:"time"`
	TimeUnit    string `json:"timeunit" validate:"timeunit"`
}

type Ingredients []Ingredient
type Steps []Steps

//
// Recipe Tag Types
//

type Tag struct {
	Name string `json:"name" validate:"tag"`
}

type Tags []Tag

//
// Recipe Validator Functions
//

func (v RicettaValidator) validateTimeUnit(i interface{}) error {
	timeUnit := i.(string)
	if timeUnit == "" {
		return fmt.Errorf("Required field")
	} else if !v.Constants.TIME_UNIT_REGEX.MatchString(timeUnit) {
		return fmt.Errorf(timeUnit + " is not a valid unit of time - [sec(s), min(s), hr(s), day(s), week(s)]")
	} else {
		return nil
	}
}

func (v RicettaValidator) validateTime(i interface{}) error {
	time, ok := i.(int)
	if !ok {
		return fmt.Errorf("Required field")
	} else if time <= 0 || time > 1000 {
		return fmt.Errorf("Invalid time unit: %d", time)
	} else {
		return nil
	}
}

func (v RicettaValidator) validateRecipeTitle(i interface{}) error {
	title := i.(string)
	titlelen := utf8.RuneCountInString(title)
	if title == "" {
		return fmt.Errorf("Required field")
	} else if titlelen > v.Constants.MAX_RECIPE_TITLE_LENGTH {
		return fmt.Errorf("Exceeds max title length of %d", v.Constants.MAX_RECIPE_TITLE_LENGTH)
	} else {
		return nil
	}
}

func (v RicettaValidator) validateRecipeNotes(i interface{}) error {
	notes := i.(string)
	noteslen := utf8.RuneCountInString(notes)
	if notes == "" {
		return fmt.Errorf("Required field")
	} else if noteslen > v.Constants.MAX_RECIPE_NOTES_LENGTH {
		return fmt.Errorf("Exceeds max notes length of %d", v.Constants.MAX_RECIPE_NOTES_LENGTH)
	} else {
		return nil
	}
}

func (v RicettaValidator) validateIngredient(i interface{}) error {
	ingredient := i.(string)
	ingredientlen := utf8.RuneCountInString(ingredient)
	if ingredient == "" {
		return fmt.Errorf("Required field")
	} else if ingredientlen > v.Constants.MAX_INGREDIENT_LENGTH {
		return fmt.Errorf("Exceeds max ingredient length of %d", v.Constants.MAX_INGREDIENT_LENGTH)
	} else {
		return nil
	}
}

func (v RicettaValidator) validateStep(i interface{}) error {
	step := i.(string)
	steplen := utf8.RuneCountInString(step)
	if step == "" {
		return fmt.Errorf("Required field")
	} else if steplen > v.Constants.MAX_STEP_LENGTH {
		return fmt.Errorf("Exceeds max step length of %d", v.Constants.MAX_STEP_LENGTH)
	} else {
		return nil
	}
}

func (v RicettaValidator) validateURL(i interface{}) error {
	url := i.(string)
	if url == "" {
		// This demonstrates how to validate an optional field
		return nil
	} else if !v.Constants.URL_REGEX.MatchString(url) {
		return fmt.Errorf("Not a valid URL string: %s", url)
	} else {
		return nil
	}
}

func (v RicettaValidator) validateTag(i interface{}) error {
	tag := i.(string)
	taglen := utf8.RuneCountInString(tag)
	if tag == "" {
		return fmt.Errorf("Required field")
	} else if taglen > v.Constants.MAX_TAG_LENGTH {
		return fmt.Errorf("Exceeds max tag length of %d", v.Constants.MAX_TAG_LENGTH)
	} else {
		return nil
	}
}
<|endoftext|>


<commit_before>package stripe

import (
	"encoding/json"
	"strconv"

	"github.com/stripe/stripe-go/v72/form"
)

// BankAccountStatus is the list of allowed values for the bank account's status.
type BankAccountStatus string

// List of values that BankAccountStatus can take.
const (
	BankAccountStatusErrored            BankAccountStatus = "errored"
	BankAccountStatusNew                BankAccountStatus = "new"
	BankAccountStatusValidated          BankAccountStatus = "validated"
	BankAccountStatusVerificationFailed BankAccountStatus = "verification_failed"
	BankAccountStatusVerified           BankAccountStatus = "verified"
)

// BankAccountAccountHolderType is the list of allowed values for the bank account holder type.
type BankAccountAccountHolderType string

// List of values that BankAccountAccountHolderType can take.
const (
	BankAccountAccountHolderTypeCompany    BankAccountAccountHolderType = "company"
	BankAccountAccountHolderTypeIndividual BankAccountAccountHolderType = "individual"
)

// BankAccountParams is the set of parameters that can be used when updating a
// bank account.
//
// Note that while form annotations are used for updates, bank accounts have
// some unusual logic on creates that necessitates manual handling of all
// parameters. See AppendToAsSourceOrExternalAccount.
type BankAccountParams struct {
	Params `form:"*"`

	// Account is the identifier of the parent account under which bank
	// accounts are nested.
	Account *string `form:"-"`

	AccountHolderName  *string `form:"account_holder_name"`
	AccountHolderType  *string `form:"account_holder_type"`
	AccountNumber      *string `form:"account_number"`
	Country            *string `form:"country"`
	Currency           *string `form:"currency"`
	Customer           *string `form:"-"`
	DefaultForCurrency *bool   `form:"default_for_currency"`
	RoutingNumber      *string `form:"routing_number"`

	// Token is a token referencing an external account like one returned from
	// Stripe.js.
	Token *string `form:"-"`

	// ID is used when tokenizing a bank account for shared customers
	ID *string `form:"*"`
}

// AppendToAsSourceOrExternalAccount appends the given BankAccountParams as
// either a source or external account.
//
// It may look like an AppendTo from the form package, but it's not, and is
// only used in the special case where we use `bankaccount.New`. It's needed
// because we have some weird encoding logic here that can't be handled by the
// form package (and it's special enough that it wouldn't be desirable to have
// it do so).
//
// This is not a pattern that we want to push forward, and this largely exists
// because the bank accounts endpoint is a little unusual. There is one other
// resource like it, which is cards.
func (a *BankAccountParams) AppendToAsSourceOrExternalAccount(body *form.Values) {
	// Rather than being called in addition to `AppendTo`, this function
	// *replaces* `AppendTo`, so we must also make sure to handle the encoding
	// of `Params` so metadata and the like is included in the encoded payload.
	form.AppendTo(body, a.Params)

	isCustomer := a.Customer != nil

	var sourceType string
	if isCustomer {
		sourceType = "source"
	} else {
		sourceType = "external_account"
	}

	// Use token (if exists) or a dictionary containing a user’s bank account details.
	if a.Token != nil {
		body.Add(sourceType, StringValue(a.Token))

		if a.DefaultForCurrency != nil {
			body.Add("default_for_currency", strconv.FormatBool(BoolValue(a.DefaultForCurrency)))
		}
	} else {
		body.Add(sourceType+"[object]", "bank_account")
		body.Add(sourceType+"[country]", StringValue(a.Country))
		body.Add(sourceType+"[account_number]", StringValue(a.AccountNumber))
		body.Add(sourceType+"[currency]", StringValue(a.Currency))

		// These are optional and the API will fail if we try to send empty
		// values in for them, so make sure to check that they're actually set
		// before encoding them.
		if a.AccountHolderName != nil {
			body.Add(sourceType+"[account_holder_name]", StringValue(a.AccountHolderName))
		}

		if a.AccountHolderType != nil {
			body.Add(sourceType+"[account_holder_type]", StringValue(a.AccountHolderType))
		}

		if a.RoutingNumber != nil {
			body.Add(sourceType+"[routing_number]", StringValue(a.RoutingNumber))
		}

		if a.DefaultForCurrency != nil {
			body.Add(sourceType+"[default_for_currency]", strconv.FormatBool(BoolValue(a.DefaultForCurrency)))
		}
	}
}

// BankAccountListParams is the set of parameters that can be used when listing bank accounts.
type BankAccountListParams struct {
	ListParams `form:"*"`

	// The identifier of the parent account under which the bank accounts are
	// nested. Either Account or Customer should be populated.
	Account *string `form:"-"`

	// The identifier of the parent customer under which the bank accounts are
	// nested. Either Account or Customer should be populated.
	Customer *string `form:"-"`
}

// AppendTo implements custom encoding logic for BankAccountListParams
// so that we can send the special required `object` field up along with the
// other specified parameters.
func (p *BankAccountListParams) AppendTo(body *form.Values, keyParts []string) {
	body.Add(form.FormatKey(append(keyParts, "object")), "bank_account")
}

// BankAccount represents a Stripe bank account.
type BankAccount struct {
	APIResource
	Account            *Account                     `json:"account"`
	AccountHolderName  string                       `json:"account_holder_name"`
	AccountHolderType  BankAccountAccountHolderType `json:"account_holder_type"`
	BankName           string                       `json:"bank_name"`
	Country            string                       `json:"country"`
	Currency           Currency                     `json:"currency"`
	Customer           *Customer                    `json:"customer"`
	DefaultForCurrency bool                         `json:"default_for_currency"`
	Deleted            bool                         `json:"deleted"`
	Fingerprint        string                       `json:"fingerprint"`
	ID                 string                       `json:"id"`
	Last4              string                       `json:"last4"`
	Metadata           map[string]string            `json:"metadata"`
	Object             string                       `json:"object"`
	RoutingNumber      string                       `json:"routing_number"`
	Status             BankAccountStatus            `json:"status"`
}

// BankAccountList is a list object for bank accounts.
type BankAccountList struct {
	APIResource
	ListMeta
	Data []*BankAccount `json:"data"`
}

// UnmarshalJSON handles deserialization of a BankAccount.
// This custom unmarshaling is needed because the resulting
// property may be an id or the full struct if it was expanded.
func (b *BankAccount) UnmarshalJSON(data []byte) error {
	if id, ok := ParseID(data); ok {
		b.ID = id
		return nil
	}

	type bankAccount BankAccount
	var v bankAccount
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}

	*b = BankAccount(v)
	return nil
}
<commit_msg>Add support for `AvailablePayoutMethods` on `BankAccount`<commit_after>package stripe

import (
	"encoding/json"
	"strconv"

	"github.com/stripe/stripe-go/v72/form"
)

// BankAccountAvailablePayoutMethod is a set of available payout methods for the card.
type BankAccountAvailablePayoutMethod string

// List of values that CardAvailablePayoutMethod can take.
const (
	BankAccountAvailablePayoutMethodAvailablePayoutMethodInstant  BankAccountAvailablePayoutMethod = "instant"
	BankAccountAvailablePayoutMethodAvailablePayoutMethodStandard BankAccountAvailablePayoutMethod = "standard"
)

// BankAccountStatus is the list of allowed values for the bank account's status.
type BankAccountStatus string

// List of values that BankAccountStatus can take.
const (
	BankAccountStatusErrored            BankAccountStatus = "errored"
	BankAccountStatusNew                BankAccountStatus = "new"
	BankAccountStatusValidated          BankAccountStatus = "validated"
	BankAccountStatusVerificationFailed BankAccountStatus = "verification_failed"
	BankAccountStatusVerified           BankAccountStatus = "verified"
)

// BankAccountAccountHolderType is the list of allowed values for the bank account holder type.
type BankAccountAccountHolderType string

// List of values that BankAccountAccountHolderType can take.
const (
	BankAccountAccountHolderTypeCompany    BankAccountAccountHolderType = "company"
	BankAccountAccountHolderTypeIndividual BankAccountAccountHolderType = "individual"
)

// BankAccountParams is the set of parameters that can be used when updating a
// bank account.
//
// Note that while form annotations are used for updates, bank accounts have
// some unusual logic on creates that necessitates manual handling of all
// parameters. See AppendToAsSourceOrExternalAccount.
type BankAccountParams struct {
	Params `form:"*"`

	// Account is the identifier of the parent account under which bank
	// accounts are nested.
	Account *string `form:"-"`

	AccountHolderName  *string `form:"account_holder_name"`
	AccountHolderType  *string `form:"account_holder_type"`
	AccountNumber      *string `form:"account_number"`
	Country            *string `form:"country"`
	Currency           *string `form:"currency"`
	Customer           *string `form:"-"`
	DefaultForCurrency *bool   `form:"default_for_currency"`
	RoutingNumber      *string `form:"routing_number"`

	// Token is a token referencing an external account like one returned from
	// Stripe.js.
	Token *string `form:"-"`

	// ID is used when tokenizing a bank account for shared customers
	ID *string `form:"*"`
}

// AppendToAsSourceOrExternalAccount appends the given BankAccountParams as
// either a source or external account.
//
// It may look like an AppendTo from the form package, but it's not, and is
// only used in the special case where we use `bankaccount.New`. It's needed
// because we have some weird encoding logic here that can't be handled by the
// form package (and it's special enough that it wouldn't be desirable to have
// it do so).
//
// This is not a pattern that we want to push forward, and this largely exists
// because the bank accounts endpoint is a little unusual. There is one other
// resource like it, which is cards.
func (a *BankAccountParams) AppendToAsSourceOrExternalAccount(body *form.Values) {
	// Rather than being called in addition to `AppendTo`, this function
	// *replaces* `AppendTo`, so we must also make sure to handle the encoding
	// of `Params` so metadata and the like is included in the encoded payload.
	form.AppendTo(body, a.Params)

	isCustomer := a.Customer != nil

	var sourceType string
	if isCustomer {
		sourceType = "source"
	} else {
		sourceType = "external_account"
	}

	// Use token (if exists) or a dictionary containing a user’s bank account details.
	if a.Token != nil {
		body.Add(sourceType, StringValue(a.Token))

		if a.DefaultForCurrency != nil {
			body.Add("default_for_currency", strconv.FormatBool(BoolValue(a.DefaultForCurrency)))
		}
	} else {
		body.Add(sourceType+"[object]", "bank_account")
		body.Add(sourceType+"[country]", StringValue(a.Country))
		body.Add(sourceType+"[account_number]", StringValue(a.AccountNumber))
		body.Add(sourceType+"[currency]", StringValue(a.Currency))

		// These are optional and the API will fail if we try to send empty
		// values in for them, so make sure to check that they're actually set
		// before encoding them.
		if a.AccountHolderName != nil {
			body.Add(sourceType+"[account_holder_name]", StringValue(a.AccountHolderName))
		}

		if a.AccountHolderType != nil {
			body.Add(sourceType+"[account_holder_type]", StringValue(a.AccountHolderType))
		}

		if a.RoutingNumber != nil {
			body.Add(sourceType+"[routing_number]", StringValue(a.RoutingNumber))
		}

		if a.DefaultForCurrency != nil {
			body.Add(sourceType+"[default_for_currency]", strconv.FormatBool(BoolValue(a.DefaultForCurrency)))
		}
	}
}

// BankAccountListParams is the set of parameters that can be used when listing bank accounts.
type BankAccountListParams struct {
	ListParams `form:"*"`

	// The identifier of the parent account under which the bank accounts are
	// nested. Either Account or Customer should be populated.
	Account *string `form:"-"`

	// The identifier of the parent customer under which the bank accounts are
	// nested. Either Account or Customer should be populated.
	Customer *string `form:"-"`
}

// AppendTo implements custom encoding logic for BankAccountListParams
// so that we can send the special required `object` field up along with the
// other specified parameters.
func (p *BankAccountListParams) AppendTo(body *form.Values, keyParts []string) {
	body.Add(form.FormatKey(append(keyParts, "object")), "bank_account")
}

// BankAccount represents a Stripe bank account.
type BankAccount struct {
	APIResource
	Account                *Account                           `json:"account"`
	AccountHolderName      string                             `json:"account_holder_name"`
	AccountHolderType      BankAccountAccountHolderType       `json:"account_holder_type"`
	AvailablePayoutMethods []BankAccountAvailablePayoutMethod `json:"available_payout_methods"`
	BankName               string                             `json:"bank_name"`
	Country                string                             `json:"country"`
	Currency               Currency                           `json:"currency"`
	Customer               *Customer                          `json:"customer"`
	DefaultForCurrency     bool                               `json:"default_for_currency"`
	Deleted                bool                               `json:"deleted"`
	Fingerprint            string                             `json:"fingerprint"`
	ID                     string                             `json:"id"`
	Last4                  string                             `json:"last4"`
	Metadata               map[string]string                  `json:"metadata"`
	Object                 string                             `json:"object"`
	RoutingNumber          string                             `json:"routing_number"`
	Status                 BankAccountStatus                  `json:"status"`
}

// BankAccountList is a list object for bank accounts.
type BankAccountList struct {
	APIResource
	ListMeta
	Data []*BankAccount `json:"data"`
}

// UnmarshalJSON handles deserialization of a BankAccount.
// This custom unmarshaling is needed because the resulting
// property may be an id or the full struct if it was expanded.
func (b *BankAccount) UnmarshalJSON(data []byte) error {
	if id, ok := ParseID(data); ok {
		b.ID = id
		return nil
	}

	type bankAccount BankAccount
	var v bankAccount
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}

	*b = BankAccount(v)
	return nil
}
<|endoftext|>


<commit_before>package db

import sq "github.com/lann/squirrel"

// CoreOfferRecordSelect is a sql fragment to help select form queries that
// select into a CoreOfferRecord
var CoreOfferRecordSelect = sq.Select(
	"co.accountid",
	"co.offerid",
).From("offers co")

// CoreOfferRecord is row of data from the `offers` table from stellar-core
type CoreOfferRecord struct {
	Accountid string
	Offerid   int64
}
<commit_msg>Add additional columns to CoreOfferRecord<commit_after>package db

import sq "github.com/lann/squirrel"

// CoreOfferRecordSelect is a sql fragment to help select form queries that
// select into a CoreOfferRecord
var CoreOfferRecordSelect = sq.Select(
	"co.accountid",
	"co.offerid",
	"co.paysalphanumcurrency",
	"co.paysissuer",
	"co.getsalphanumcurrency",
	"co.getsissuer",
	"co.amount",
	"co.pricen",
	"co.priced",
	"co.price",
).From("offers co")

// CoreOfferRecord is row of data from the `offers` table from stellar-core
type CoreOfferRecord struct {
	Accountid            string
	Offerid              int64
	Paysalphanumcurrency string
	Paysissuer           string
	Getsalphanumcurrency string
	Getsissuer           string
	Amount               int64
	Pricen               int32
	Priced               int32
	Price                int64
}
<|endoftext|>


<commit_before>// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package backups

import (
	"github.com/juju/errors"
	"github.com/juju/loggo"
	"github.com/juju/utils/filestorage"

	"github.com/juju/juju/apiserver/common"
	"github.com/juju/juju/environs"
	"github.com/juju/juju/state"
	"github.com/juju/juju/state/backups"
	"github.com/juju/juju/state/backups/files"
)

func init() {
	common.RegisterStandardFacade("Backups", 0, NewAPI)
}

var logger = loggo.GetLogger("juju.apiserver.backups")

// API serves backup-specific API methods.
type API struct {
	st      *state.State
	paths   files.Paths
	backups backups.Backups
}

// NewAPI creates a new instance of the Backups API facade.
func NewAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*API, error) {
	if !authorizer.AuthClient() {
		return nil, errors.Trace(common.ErrPerm)
	}

	dataDirRes := resources.Get("dataDir")
	dataDir, ok := dataDirRes.(common.StringResource)
	if !ok {
		return nil, errors.Errorf("invalid dataDir resource: %v", dataDirRes)
	}

	logDirRes := resources.Get("logDir")
	logDir, ok := logDirRes.(common.StringResource)
	if !ok {
		return nil, errors.Errorf("invalid logDir resource: %v", logDirRes)
	}

	var paths files.Paths
	paths.DataDir = dataDir.String()
	paths.LogsDir = logDir.String()

	stor, err := newBackupsStorage(st)
	if err != nil {
		return nil, errors.Trace(err)
	}

	b := API{
		st:      st,
		paths:   paths,
		backups: backups.NewBackups(stor),
	}
	return &b, nil
}

var newBackupsStorage = func(st *state.State) (filestorage.FileStorage, error) {
	// TODO(axw,ericsnow) 2014-09-24 #1373236
	// Migrate away from legacy provider storage.
	envStor, err := environs.LegacyStorage(st)
	if err != nil {
		return nil, errors.Trace(err)
	}

	storage := state.NewBackupsStorage(st, envStor)
	return storage, nil
}
<commit_msg>Convert nil resources to empty strings.<commit_after>// Copyright 2014 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package backups

import (
	"github.com/juju/errors"
	"github.com/juju/loggo"
	"github.com/juju/utils/filestorage"

	"github.com/juju/juju/apiserver/common"
	"github.com/juju/juju/environs"
	"github.com/juju/juju/state"
	"github.com/juju/juju/state/backups"
	"github.com/juju/juju/state/backups/files"
)

func init() {
	common.RegisterStandardFacade("Backups", 0, NewAPI)
}

var logger = loggo.GetLogger("juju.apiserver.backups")

// API serves backup-specific API methods.
type API struct {
	st      *state.State
	paths   files.Paths
	backups backups.Backups
}

// NewAPI creates a new instance of the Backups API facade.
func NewAPI(st *state.State, resources *common.Resources, authorizer common.Authorizer) (*API, error) {
	if !authorizer.AuthClient() {
		return nil, errors.Trace(common.ErrPerm)
	}

	dataDirRes := resources.Get("dataDir")
	dataDir, ok := dataDirRes.(common.StringResource)
	if !ok {
		if dataDirRes == nil {
			dataDir = ""
		} else {
			return nil, errors.Errorf("invalid dataDir resource: %v", dataDirRes)
		}
	}

	logDirRes := resources.Get("logDir")
	logDir, ok := logDirRes.(common.StringResource)
	if !ok {
		if logDirRes == nil {
			logDir = ""
		} else {
			return nil, errors.Errorf("invalid logDir resource: %v", logDirRes)
		}
	}

	var paths files.Paths
	paths.DataDir = dataDir.String()
	paths.LogsDir = logDir.String()

	stor, err := newBackupsStorage(st)
	if err != nil {
		return nil, errors.Trace(err)
	}

	b := API{
		st:      st,
		paths:   paths,
		backups: backups.NewBackups(stor),
	}
	return &b, nil
}

var newBackupsStorage = func(st *state.State) (filestorage.FileStorage, error) {
	// TODO(axw,ericsnow) 2014-09-24 #1373236
	// Migrate away from legacy provider storage.
	envStor, err := environs.LegacyStorage(st)
	if err != nil {
		return nil, errors.Trace(err)
	}

	storage := state.NewBackupsStorage(st, envStor)
	return storage, nil
}
<|endoftext|>


<commit_before>package stager_runner

import (
	"os/exec"
	"strings"
	"time"

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

type StagerRunner struct {
	stagerBin     string
	etcdCluster   []string
	natsAddresses []string

	session     *gexec.Session
	CompilerUrl string
}

func New(stagerBin string, etcdCluster []string, natsAddresses []string) *StagerRunner {
	return &StagerRunner{
		stagerBin:     stagerBin,
		etcdCluster:   etcdCluster,
		natsAddresses: natsAddresses,
	}
}

func (r *StagerRunner) Start(args ...string) {
	if r.session != nil {
		panic("starting more than one stager runner!!!")
	}

	stagerSession, err := gexec.Start(
		exec.Command(
			r.stagerBin,
			append([]string{
				"-etcdCluster", strings.Join(r.etcdCluster, ","),
				"-natsAddresses", strings.Join(r.natsAddresses, ","),
			}, args...)...,
		),
		ginkgo.GinkgoWriter,
		ginkgo.GinkgoWriter,
	)

	Ω(err).ShouldNot(HaveOccurred())
	Eventually(stagerSession).Should(gbytes.Say("Listening for staging requests!"))

	r.session = stagerSession
}

func (r *StagerRunner) Stop() {
	if r.session != nil {
		r.session.Interrupt().Wait(5 * time.Second)
		r.session = nil
	}
}

func (r *StagerRunner) KillWithFire() {
	if r.session != nil {
		r.session.Kill().Wait(5 * time.Second)
		r.session = nil
	}
}

func (r *StagerRunner) Session() *gexec.Session {
	return r.session
}
<commit_msg>Add prefix to runner output<commit_after>package stager_runner

import (
	"os/exec"
	"strings"
	"time"

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

type StagerRunner struct {
	stagerBin     string
	etcdCluster   []string
	natsAddresses []string

	session     *gexec.Session
	CompilerUrl string
}

func New(stagerBin string, etcdCluster []string, natsAddresses []string) *StagerRunner {
	return &StagerRunner{
		stagerBin:     stagerBin,
		etcdCluster:   etcdCluster,
		natsAddresses: natsAddresses,
	}
}

func (r *StagerRunner) Start(args ...string) {
	if r.session != nil {
		panic("starting more than one stager runner!!!")
	}

	stagerSession, err := gexec.Start(
		exec.Command(
			r.stagerBin,
			append([]string{
				"-etcdCluster", strings.Join(r.etcdCluster, ","),
				"-natsAddresses", strings.Join(r.natsAddresses, ","),
			}, args...)...,
		),
		gexec.NewPrefixedWriter("\x1b[32m[o]\x1b[95m[stager]\x1b[0m ", ginkgo.GinkgoWriter),
		gexec.NewPrefixedWriter("\x1b[91m[e]\x1b[95m[stager]\x1b[0m ", ginkgo.GinkgoWriter),
	)

	Ω(err).ShouldNot(HaveOccurred())
	Eventually(stagerSession).Should(gbytes.Say("Listening for staging requests!"))

	r.session = stagerSession
}

func (r *StagerRunner) Stop() {
	if r.session != nil {
		r.session.Interrupt().Wait(5 * time.Second)
		r.session = nil
	}
}

func (r *StagerRunner) KillWithFire() {
	if r.session != nil {
		r.session.Kill().Wait(5 * time.Second)
		r.session = nil
	}
}

func (r *StagerRunner) Session() *gexec.Session {
	return r.session
}
<|endoftext|>