<commit_before>package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"os"
	"sort"
)

func usage() {
	const help = `usage: ... | pct [-f] [-n] [-c]

pct calculates the distribution of lines in text.
It is similar to sort | uniq -c | sort -n -r, except
that it prints percentages as well as counts.
`

	fmt.Fprintln(os.Stderr, help)
	flag.PrintDefaults()
}

type recorder interface {
	Record([]byte)
	Top(int) []stringCount
}

type mcount map[string]uint64

func (m mcount) Record(b []byte) {
	m[string(b)]++
}

func (m mcount) Top(n int) []stringCount {
	var l []stringCount
	for k, v := range m {
		l = append(l, stringCount{n: v, s: k})
	}
	sort.Sort(stringsByCount(l))
	if n == 0 {
		return l
	}
	return l[:n]
}

func dump(w io.Writer, tot int, r recorder) error {
	f := 100 / float64(tot)
	runtot := uint64(0)
	top := r.Top(*limit)
	for _, line := range top {
		runtot += line.n
		p := f * float64(line.n)
		var err error
		if *cum {
			_, err = fmt.Fprintf(w, "% 6.2f%% % 6.2f%%% 6d %s\n", p, f*float64(runtot), line.n, line.s)
		} else {
			_, err = fmt.Fprintf(w, "% 6.2f%%% 6d %s\n", p, line.n, line.s)
		}
		if err != nil {
			return err
		}
	}
	return nil
}

func pct(r io.Reader, w io.Writer, rec recorder) error {
	s := bufio.NewScanner(r)
	n := 0
	for s.Scan() {
		rec.Record(s.Bytes())
		n++
		if *every > 0 && n%*every == 0 {
			if err := dump(w, n, rec); err != nil {
				return err
			} else {
				fmt.Fprintln(w)
			}
		}
	}
	if err := s.Err(); err != nil {
		dump(w, n, rec)
		fmt.Fprintf(w, "Stopped at line %d: %v\n", n, err)
		return err
	}
	return dump(w, n, rec)
}

var (
	every  = flag.Int("f", 0, "print running percents every f lines, requires -n")
	limit  = flag.Int("n", 0, "only print top n lines")
	cum    = flag.Bool("c", false, "print cumulative percents as well")
	approx = flag.Bool("x", false, "use a fast approximate counter, only suitable for large input, requires -n")
)

func main() {
	flag.Usage = usage
	flag.Parse()
	if *approx && *limit == 0 {
		fmt.Fprintln(os.Stderr, "-x requires -n")
		os.Exit(2)
	}
	if *every != 0 && *limit == 0 {
		fmt.Fprintln(os.Stderr, "-f requires -n")
		os.Exit(2)
	}

	var r recorder
	if *approx {
		r = newTopK(*limit, 8, 16384)
	} else {
		r = make(mcount)
	}

	pct(os.Stdin, os.Stdout, r)
}
<commit_msg>Don’t panic when more results are requested than are available<commit_after>package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"os"
	"sort"
)

func usage() {
	const help = `usage: ... | pct [-f] [-n] [-c]

pct calculates the distribution of lines in text.
It is similar to sort | uniq -c | sort -n -r, except
that it prints percentages as well as counts.
`

	fmt.Fprintln(os.Stderr, help)
	flag.PrintDefaults()
}

type recorder interface {
	Record([]byte)
	Top(int) []stringCount
}

type mcount map[string]uint64

func (m mcount) Record(b []byte) {
	m[string(b)]++
}

func (m mcount) Top(n int) []stringCount {
	var l []stringCount
	for k, v := range m {
		l = append(l, stringCount{n: v, s: k})
	}
	sort.Sort(stringsByCount(l))
	if n > len(l) {
		return l
	}
	return l[:n]
}

func dump(w io.Writer, tot int, r recorder) error {
	f := 100 / float64(tot)
	runtot := uint64(0)
	top := r.Top(*limit)
	for _, line := range top {
		runtot += line.n
		p := f * float64(line.n)
		var err error
		if *cum {
			_, err = fmt.Fprintf(w, "% 6.2f%% % 6.2f%%% 6d %s\n", p, f*float64(runtot), line.n, line.s)
		} else {
			_, err = fmt.Fprintf(w, "% 6.2f%%% 6d %s\n", p, line.n, line.s)
		}
		if err != nil {
			return err
		}
	}
	return nil
}

func pct(r io.Reader, w io.Writer, rec recorder) error {
	s := bufio.NewScanner(r)
	n := 0
	for s.Scan() {
		rec.Record(s.Bytes())
		n++
		if *every > 0 && n%*every == 0 {
			if err := dump(w, n, rec); err != nil {
				return err
			} else {
				fmt.Fprintln(w)
			}
		}
	}
	if err := s.Err(); err != nil {
		dump(w, n, rec)
		fmt.Fprintf(w, "Stopped at line %d: %v\n", n, err)
		return err
	}
	return dump(w, n, rec)
}

var (
	every  = flag.Int("f", 0, "print running percents every f lines, requires -n")
	limit  = flag.Int("n", 0, "only print top n lines")
	cum    = flag.Bool("c", false, "print cumulative percents as well")
	approx = flag.Bool("x", false, "use a fast approximate counter, only suitable for large input, requires -n")
)

func main() {
	flag.Usage = usage
	flag.Parse()
	if *approx && *limit == 0 {
		fmt.Fprintln(os.Stderr, "-x requires -n")
		os.Exit(2)
	}
	if *every != 0 && *limit == 0 {
		fmt.Fprintln(os.Stderr, "-f requires -n")
		os.Exit(2)
	}

	var r recorder
	if *approx {
		r = newTopK(*limit, 8, 16384)
	} else {
		r = make(mcount)
	}

	pct(os.Stdin, os.Stdout, r)
}
<|endoftext|>


<commit_before>package main

import (
	"net/http"
	"net/http/httptest"
	"net/http/httputil"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

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

func (s *DockerSuite) TestApiOptionsRoute(c *check.C) {
	status, _, err := sockRequest("OPTIONS", "/", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(status, checker.Equals, http.StatusOK)
}

func (s *DockerSuite) TestApiGetEnabledCors(c *check.C) {
	res, body, err := sockRequestRaw("GET", "/version", nil, "")
	c.Assert(err, checker.IsNil)
	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
	body.Close()
	// TODO: @runcom incomplete tests, why old integration tests had this headers
	// and here none of the headers below are in the response?
	//c.Log(res.Header)
	//c.Assert(res.Header.Get("Access-Control-Allow-Origin"), check.Equals, "*")
	//c.Assert(res.Header.Get("Access-Control-Allow-Headers"), check.Equals, "Origin, X-Requested-With, Content-Type, Accept, X-Registry-Auth")
}

func (s *DockerSuite) TestApiVersionStatusCode(c *check.C) {
	conn, err := sockConn(time.Duration(10 * time.Second))
	c.Assert(err, checker.IsNil)

	client := httputil.NewClientConn(conn, nil)
	defer client.Close()

	req, err := http.NewRequest("GET", "/v999.0/version", nil)
	c.Assert(err, checker.IsNil)
	req.Header.Set("User-Agent", "Docker-Client/999.0 (os)")

	res, err := client.Do(req)
	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
}

func (s *DockerSuite) TestApiClientVersionNewerThanServer(c *check.C) {
	v := strings.Split(api.DefaultVersion.String(), ".")
	vMinInt, err := strconv.Atoi(v[1])
	c.Assert(err, checker.IsNil)
	vMinInt++
	v[1] = strconv.Itoa(vMinInt)
	version := strings.Join(v, ".")

	status, body, err := sockRequest("GET", "/v"+version+"/version", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(status, checker.Equals, http.StatusBadRequest)
	c.Assert(len(string(body)), check.Not(checker.Equals), 0) // Expected not empty body
}

func (s *DockerSuite) TestApiClientVersionOldNotSupported(c *check.C) {
	v := strings.Split(api.MinVersion.String(), ".")
	vMinInt, err := strconv.Atoi(v[1])
	c.Assert(err, checker.IsNil)
	vMinInt--
	v[1] = strconv.Itoa(vMinInt)
	version := strings.Join(v, ".")

	status, body, err := sockRequest("GET", "/v"+version+"/version", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(status, checker.Equals, http.StatusBadRequest)
	c.Assert(len(string(body)), checker.Not(check.Equals), 0) // Expected not empty body
}

func (s *DockerSuite) TestApiDockerApiVersion(c *check.C) {
	var svrVersion string

	server := httptest.NewServer(http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			url := r.URL.Path
			svrVersion = url
		}))
	defer server.Close()

	// Test using the env var first
	cmd := exec.Command(dockerBinary, "-H="+server.URL[7:], "version")
	cmd.Env = append([]string{"DOCKER_API_VERSION=xxx"}, os.Environ()...)
	out, _, _ := runCommandWithOutput(cmd)

	c.Assert(svrVersion, check.Equals, "/vxxx/version")

	if !strings.Contains(out, "API version:  xxx") {
		c.Fatalf("Out didn't have 'xxx' for the API version, had:\n%s", out)
	}
}
<commit_msg>integration-cli: fix minimum and default api version test<commit_after>package main

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"net/http/httputil"
	"os"
	"os/exec"
	"strconv"
	"strings"
	"time"

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

func (s *DockerSuite) TestApiOptionsRoute(c *check.C) {
	status, _, err := sockRequest("OPTIONS", "/", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(status, checker.Equals, http.StatusOK)
}

func (s *DockerSuite) TestApiGetEnabledCors(c *check.C) {
	res, body, err := sockRequestRaw("GET", "/version", nil, "")
	c.Assert(err, checker.IsNil)
	c.Assert(res.StatusCode, checker.Equals, http.StatusOK)
	body.Close()
	// TODO: @runcom incomplete tests, why old integration tests had this headers
	// and here none of the headers below are in the response?
	//c.Log(res.Header)
	//c.Assert(res.Header.Get("Access-Control-Allow-Origin"), check.Equals, "*")
	//c.Assert(res.Header.Get("Access-Control-Allow-Headers"), check.Equals, "Origin, X-Requested-With, Content-Type, Accept, X-Registry-Auth")
}

func (s *DockerSuite) TestApiVersionStatusCode(c *check.C) {
	conn, err := sockConn(time.Duration(10 * time.Second))
	c.Assert(err, checker.IsNil)

	client := httputil.NewClientConn(conn, nil)
	defer client.Close()

	req, err := http.NewRequest("GET", "/v999.0/version", nil)
	c.Assert(err, checker.IsNil)
	req.Header.Set("User-Agent", "Docker-Client/999.0 (os)")

	res, err := client.Do(req)
	c.Assert(res.StatusCode, checker.Equals, http.StatusBadRequest)
}

func (s *DockerSuite) TestApiClientVersionNewerThanServer(c *check.C) {
	v := strings.Split(api.DefaultVersion.String(), ".")
	vMinInt, err := strconv.Atoi(v[1])
	c.Assert(err, checker.IsNil)
	vMinInt++
	v[1] = strconv.Itoa(vMinInt)
	version := strings.Join(v, ".")

	status, body, err := sockRequest("GET", "/v"+version+"/version", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(status, checker.Equals, http.StatusBadRequest)
	expected := fmt.Sprintf("client is newer than server (client API version: %s, server API version: %s)", version, api.DefaultVersion)
	c.Assert(strings.TrimSpace(string(body)), checker.Equals, expected)
}

func (s *DockerSuite) TestApiClientVersionOldNotSupported(c *check.C) {
	v := strings.Split(api.MinVersion.String(), ".")
	vMinInt, err := strconv.Atoi(v[1])
	c.Assert(err, checker.IsNil)
	vMinInt--
	v[1] = strconv.Itoa(vMinInt)
	version := strings.Join(v, ".")

	status, body, err := sockRequest("GET", "/v"+version+"/version", nil)
	c.Assert(err, checker.IsNil)
	c.Assert(status, checker.Equals, http.StatusBadRequest)
	expected := fmt.Sprintf("client version %s is too old. Minimum supported API version is %s, please upgrade your client to a newer version", version, api.MinVersion)
	c.Assert(strings.TrimSpace(string(body)), checker.Equals, expected)
}

func (s *DockerSuite) TestApiDockerApiVersion(c *check.C) {
	var svrVersion string

	server := httptest.NewServer(http.HandlerFunc(
		func(w http.ResponseWriter, r *http.Request) {
			url := r.URL.Path
			svrVersion = url
		}))
	defer server.Close()

	// Test using the env var first
	cmd := exec.Command(dockerBinary, "-H="+server.URL[7:], "version")
	cmd.Env = append([]string{"DOCKER_API_VERSION=xxx"}, os.Environ()...)
	out, _, _ := runCommandWithOutput(cmd)

	c.Assert(svrVersion, check.Equals, "/vxxx/version")

	if !strings.Contains(out, "API version:  xxx") {
		c.Fatalf("Out didn't have 'xxx' for the API version, had:\n%s", out)
	}
}
<|endoftext|>


<commit_before>package integration_test

import (
	"github.com/APTrust/exchange/models"
	"github.com/APTrust/exchange/stats"
	"github.com/APTrust/exchange/util/fileutil"
	"github.com/APTrust/exchange/util/testutil"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"path/filepath"
	"testing"
)

/*
These tests check the results of the integration tests for
the app apt_queue. See the ingest_test.rb script in
the scripts folder, which sets up an integration context, runs
apt_queue, and then runs this program to check the
stats output of apt_queue to make sure all went well.
*/

// Returns two Stats objects: the expected stats, from our test data dir,
// and the actual stats, from the JSON file that the bucket reader dumped
// out last time it ran
func getQueueOutputs(t *testing.T) (expected *stats.APTQueueStats, actual *stats.APTQueueStats) {
	configFile := filepath.Join("config", "integration.json")
	appConfig, err := models.LoadConfigFile(configFile)
	require.Nil(t, err)

	// This JSON file is part of our code repo.
	// It contains the output we expect from a success test run.
	pathToExpectedJson, err := fileutil.RelativeToAbsPath(filepath.Join("testdata",
		"integration_results", "apt_queue_stats.json"))
	require.Nil(t, err)
	expected, err = stats.APTQueueStatsLoadFromFile(pathToExpectedJson)
	require.Nil(t, err)

	// This JSON file is recreated every time we run apt_bucket_reader
	// as part of the integration tests. It contains the output of the
	// actual test run.
	pathToActualJson, err := fileutil.ExpandTilde(filepath.Join(appConfig.LogDirectory, "apt_queue_stats.json"))
	require.Nil(t, err)
	actual, err = stats.APTQueueStatsLoadFromFile(pathToActualJson)
	require.Nil(t, err)

	return expected, actual
}

func TestQueueStats(t *testing.T) {
	if !testutil.ShouldRunIntegrationTests() {
		t.Skip("Skipping integration test. Set ENV var RUN_EXCHANGE_INTEGRATION=true if you want to run them.")
	}
	expected, actual := getQueueOutputs(t)
	testItemsQueued(t, expected, actual)
	testItemsMarkedAsQueued(t, expected, actual)
	testErrors(t, expected, actual)
	testWarnings(t, expected, actual)
}

func testItemsQueued(t *testing.T, expected *stats.APTQueueStats, actual *stats.APTQueueStats) {
	for _, itemList := range expected.ItemsQueued {
		for _, item := range itemList {
			matchingItem, topic := actual.FindQueuedItemByName(item.Name)
			assert.NotNil(t, matchingItem, "WorkItem %s missing from ItemsQueued", item.Name)
			assert.Equal(t, "apt_restore_topic", topic)
		}
	}
}

func testItemsMarkedAsQueued(t *testing.T, expected *stats.APTQueueStats, actual *stats.APTQueueStats) {
	for _, item := range expected.ItemsMarkedAsQueued {
		matchingItem := actual.FindMarkedItemByName(item.Name)
		assert.NotNil(t, matchingItem, "WorkItem %s missing from ItemsMarkedAsQueued", item.Name)
	}
}

func testErrors(t *testing.T, expected *stats.APTQueueStats, actual *stats.APTQueueStats) {
	assert.Equal(t, 0, len(actual.Errors))
}

func testWarnings(t *testing.T, expected *stats.APTQueueStats, actual *stats.APTQueueStats) {
	assert.Equal(t, 0, len(actual.Warnings))
}
<commit_msg>Fixed duplicate test function declarations<commit_after>package integration_test

import (
	"github.com/APTrust/exchange/models"
	"github.com/APTrust/exchange/stats"
	"github.com/APTrust/exchange/util/fileutil"
	"github.com/APTrust/exchange/util/testutil"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"path/filepath"
	"testing"
)

/*
These tests check the results of the integration tests for
the app apt_queue. See the ingest_test.rb script in
the scripts folder, which sets up an integration context, runs
apt_queue, and then runs this program to check the
stats output of apt_queue to make sure all went well.
*/

// Returns two Stats objects: the expected stats, from our test data dir,
// and the actual stats, from the JSON file that the bucket reader dumped
// out last time it ran
func getQueueOutputs(t *testing.T) (expected *stats.APTQueueStats, actual *stats.APTQueueStats) {
	configFile := filepath.Join("config", "integration.json")
	appConfig, err := models.LoadConfigFile(configFile)
	require.Nil(t, err)

	// This JSON file is part of our code repo.
	// It contains the output we expect from a success test run.
	pathToExpectedJson, err := fileutil.RelativeToAbsPath(filepath.Join("testdata",
		"integration_results", "apt_queue_stats.json"))
	require.Nil(t, err)
	expected, err = stats.APTQueueStatsLoadFromFile(pathToExpectedJson)
	require.Nil(t, err)

	// This JSON file is recreated every time we run apt_bucket_reader
	// as part of the integration tests. It contains the output of the
	// actual test run.
	pathToActualJson, err := fileutil.ExpandTilde(filepath.Join(appConfig.LogDirectory, "apt_queue_stats.json"))
	require.Nil(t, err)
	actual, err = stats.APTQueueStatsLoadFromFile(pathToActualJson)
	require.Nil(t, err)

	return expected, actual
}

func TestQueueStats(t *testing.T) {
	if !testutil.ShouldRunIntegrationTests() {
		t.Skip("Skipping integration test. Set ENV var RUN_EXCHANGE_INTEGRATION=true if you want to run them.")
	}
	expected, actual := getQueueOutputs(t)
	testItemsQueued(t, expected, actual)
	testItemsMarkedAsQueued(t, expected, actual)
	testQueueErrors(t, expected, actual)
	testQueueWarnings(t, expected, actual)
}

func testItemsQueued(t *testing.T, expected *stats.APTQueueStats, actual *stats.APTQueueStats) {
	for _, itemList := range expected.ItemsQueued {
		for _, item := range itemList {
			matchingItem, topic := actual.FindQueuedItemByName(item.Name)
			assert.NotNil(t, matchingItem, "WorkItem %s missing from ItemsQueued", item.Name)
			assert.Equal(t, "apt_restore_topic", topic)
		}
	}
}

func testItemsMarkedAsQueued(t *testing.T, expected *stats.APTQueueStats, actual *stats.APTQueueStats) {
	for _, item := range expected.ItemsMarkedAsQueued {
		matchingItem := actual.FindMarkedItemByName(item.Name)
		assert.NotNil(t, matchingItem, "WorkItem %s missing from ItemsMarkedAsQueued", item.Name)
	}
}

func testQueueErrors(t *testing.T, expected *stats.APTQueueStats, actual *stats.APTQueueStats) {
	assert.Equal(t, 0, len(actual.Errors))
}

func testQueueWarnings(t *testing.T, expected *stats.APTQueueStats, actual *stats.APTQueueStats) {
	assert.Equal(t, 0, len(actual.Warnings))
}
<|endoftext|>


<commit_before>package web

import (
	"net/http"
	"text/template"

	"github.com/jamiefdhurst/journal/internal/app"
	"github.com/jamiefdhurst/journal/internal/app/model"
	"github.com/jamiefdhurst/journal/pkg/controller"
)

// New Handle creating a new entry
type New struct {
	controller.Super
	Error   bool
	Journal model.Journal
}

// Run New action
func (c *New) Run(response http.ResponseWriter, request *http.Request) {
	if request.Method == "GET" {
		query := request.URL.Query()
		if query["error"] != nil {
			c.Error = true
		}

		template, _ := template.ParseFiles(
			"./web/templates/_layout/default.tmpl",
			"./web/templates/new.tmpl",
			"./web/templates/_partial/form.tmpl")
		template.ExecuteTemplate(response, "layout", c)
	} else {
		if request.FormValue("title") == "" || request.FormValue("date") == "" || request.FormValue("content") == "" {
			http.Redirect(response, request, "/new?error=1", 302)
			return
		}

		js := model.Journals{Container: c.Super.Container.(*app.Container), Gs: &model.Giphys{Container: c.Super.Container.(*app.Container)}}
		journal := model.Journal{ID: 0, Slug: model.Slugify(request.FormValue("title")), Title: model.Slugify(request.FormValue("title")), Date: request.FormValue("date"), Content: request.FormValue("content")}
		js.Save(journal)

		http.Redirect(response, request, "/?saved=1", 302)
	}
}
<commit_msg>Fix title slugifying incorrectly<commit_after>package web

import (
	"net/http"
	"text/template"

	"github.com/jamiefdhurst/journal/internal/app"
	"github.com/jamiefdhurst/journal/internal/app/model"
	"github.com/jamiefdhurst/journal/pkg/controller"
)

// New Handle creating a new entry
type New struct {
	controller.Super
	Error   bool
	Journal model.Journal
}

// Run New action
func (c *New) Run(response http.ResponseWriter, request *http.Request) {
	if request.Method == "GET" {
		query := request.URL.Query()
		if query["error"] != nil {
			c.Error = true
		}

		template, _ := template.ParseFiles(
			"./web/templates/_layout/default.tmpl",
			"./web/templates/new.tmpl",
			"./web/templates/_partial/form.tmpl")
		template.ExecuteTemplate(response, "layout", c)
	} else {
		if request.FormValue("title") == "" || request.FormValue("date") == "" || request.FormValue("content") == "" {
			http.Redirect(response, request, "/new?error=1", 302)
			return
		}

		js := model.Journals{Container: c.Super.Container.(*app.Container), Gs: &model.Giphys{Container: c.Super.Container.(*app.Container)}}
		journal := model.Journal{ID: 0, Slug: model.Slugify(request.FormValue("title")), Title: request.FormValue("title"), Date: request.FormValue("date"), Content: request.FormValue("content")}
		js.Save(journal)

		http.Redirect(response, request, "/?saved=1", 302)
	}
}
<|endoftext|>


<commit_before>package datapeer

import (
	"crypto"
	"io/ioutil"
	"strings"
	"testing"

	"github.com/johnny-morrice/godless/internal/testutil"
)

func TestResidentMemoryStorage(t *testing.T) {
	const dataText = "Much data!"

	options := ResidentMemoryStorageOptions{
		Hash: crypto.SHA1,
	}

	storage := MakeResidentMemoryStorage(options)

	data, err := storage.Cat("not present")
	testutil.AssertNil(t, data)
	testutil.AssertNonNil(t, err)

	keyOne, err := storage.Add(strings.NewReader(dataText))
	testutil.AssertNil(t, err)

	data, err = storage.Cat(keyOne)
	testutil.AssertNil(t, err)
	dataBytes, err := ioutil.ReadAll(data)
	testutil.AssertNil(t, err)
	testutil.AssertBytesEqual(t, []byte(dataText), dataBytes)

	keyTwo, err := storage.Add(strings.NewReader(dataText))
	testutil.AssertNil(t, err)
	testutil.AssertEquals(t, "Unexpected hash", keyOne, keyTwo)
}

func TestResidentMemoryPubSub(t *testing.T) {
	const topicA = "Topic A"
	const topicB = "Topic B"
	const dataA = "Data A"
	const dataB = "Data B"
	expectA := []byte(dataA)
	expectB := []byte(dataB)

	pubsubber := MakeResidentMemoryPubSubBus()

	subA1, err := pubsubber.PubSubSubscribe(topicA)
	testutil.AssertNil(t, err)
	subA2, err := pubsubber.PubSubSubscribe(topicA)
	testutil.AssertNil(t, err)
	subB, err := pubsubber.PubSubSubscribe(topicB)
	testutil.AssertNil(t, err)

	pubsubber.PubSubPublish(topicA, dataA)
	pubsubber.PubSubPublish(topicB, dataB)

	recordA1, err := subA1.Next()
	testutil.AssertNil(t, err)
	recordA2, err := subA2.Next()
	testutil.AssertNil(t, err)
	recordB, err := subB.Next()
	testutil.AssertNil(t, err)

	testutil.AssertBytesEqual(t, expectA, recordA1.Data())
	testutil.AssertBytesEqual(t, expectA, recordA2.Data())
	testutil.AssertBytesEqual(t, expectB, recordB.Data())
}
<commit_msg>Benchmark for the in-memory storage<commit_after>package datapeer

import (
	"crypto"
	"io/ioutil"
	"strings"
	"testing"

	"github.com/johnny-morrice/godless/api"
	"github.com/johnny-morrice/godless/internal/testutil"
)

func TestResidentMemoryStorage(t *testing.T) {
	const dataText = "Much data!"

	options := ResidentMemoryStorageOptions{
		Hash: crypto.SHA1,
	}

	storage := MakeResidentMemoryStorage(options)

	data, err := storage.Cat("not present")
	testutil.AssertNil(t, data)
	testutil.AssertNonNil(t, err)

	keyOne, err := storage.Add(strings.NewReader(dataText))
	testutil.AssertNil(t, err)

	data, err = storage.Cat(keyOne)
	testutil.AssertNil(t, err)
	dataBytes, err := ioutil.ReadAll(data)
	testutil.AssertNil(t, err)
	testutil.AssertBytesEqual(t, []byte(dataText), dataBytes)

	keyTwo, err := storage.Add(strings.NewReader(dataText))
	testutil.AssertNil(t, err)
	testutil.AssertEquals(t, "Unexpected hash", keyOne, keyTwo)
}

func TestResidentMemoryPubSub(t *testing.T) {
	const topicA = "Topic A"
	const topicB = "Topic B"
	const dataA = "Data A"
	const dataB = "Data B"
	expectA := []byte(dataA)
	expectB := []byte(dataB)

	pubsubber := MakeResidentMemoryPubSubBus()

	subA1, err := pubsubber.PubSubSubscribe(topicA)
	testutil.AssertNil(t, err)
	subA2, err := pubsubber.PubSubSubscribe(topicA)
	testutil.AssertNil(t, err)
	subB, err := pubsubber.PubSubSubscribe(topicB)
	testutil.AssertNil(t, err)

	pubsubber.PubSubPublish(topicA, dataA)
	pubsubber.PubSubPublish(topicB, dataB)

	recordA1, err := subA1.Next()
	testutil.AssertNil(t, err)
	recordA2, err := subA2.Next()
	testutil.AssertNil(t, err)
	recordB, err := subB.Next()
	testutil.AssertNil(t, err)

	testutil.AssertBytesEqual(t, expectA, recordA1.Data())
	testutil.AssertBytesEqual(t, expectA, recordA2.Data())
	testutil.AssertBytesEqual(t, expectB, recordB.Data())
}

func BenchmarkResidentMemoryStorageAdd(b *testing.B) {
	options := ResidentMemoryStorageOptions{
		Hash: crypto.MD5,
	}

	storage := MakeResidentMemoryStorage(options)
	for i := 0; i < b.N; i++ {
		addRandomData(storage)
	}
}

func addRandomData(storage api.ContentAddressableStorage) {
	const min = 100
	const max = 1000
	dataText := testutil.RandLettersRange(testutil.Rand(), min, max)
	_, err := storage.Add(strings.NewReader(dataText))
	if err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package builtin_test

import (
	"bytes"
	"testing"

	"github.com/NeowayLabs/nash"
)

func TestPrintf(t *testing.T) {
	type printfDesc struct {
		script string
		output string
	}

	tests := map[string]printfDesc{
		"textonly": {
			script: `printf("helloworld")`,
			output: "helloworld",
		},
		"fmtstring": {
			script: `printf("%s:%s", "hello", "world")`,
			output: "hello:world",
		},
	}

	for name, desc := range tests {
		t.Run(name, func(t *testing.T) {
			var output bytes.Buffer
			shell, err := nash.New()

			if err != nil {
				t.Fatalf("unexpected err: %s", err)
			}

			shell.SetStdout(&output)
			err = shell.Exec("", desc.script)

			if err != nil {
				t.Fatalf("unexpected err: %s", err)
			}

			if output.String() != desc.output {
				t.Fatalf("got %q expected %q", output.String(), desc.output)
			}
		})
	}
}

func TestPrintfErrors(t *testing.T) {
	type printfDesc struct {
		script string
	}

	tests := map[string]printfDesc{
		"noParams": {
			script: `printf()`,
		},
	}

	for name, desc := range tests {
		t.Run(name, func(t *testing.T) {
			var output bytes.Buffer
			shell, err := nash.New()

			if err != nil {
				t.Fatalf("unexpected err: %s", err)
			}

			shell.SetStdout(&output)
			err = shell.Exec("", desc.script)

			if err == nil {
				t.Fatalf("expected err, got success, output: %s", output)
			}

			if output.Len() > 0 {
				t.Fatalf("expected empty output, got: %s", output)
			}
		})
	}
}
<commit_msg>Add final list cases<commit_after>package builtin_test

import (
	"bytes"
	"testing"

	"github.com/NeowayLabs/nash"
)

func TestPrintf(t *testing.T) {
	type printfDesc struct {
		script string
		output string
	}

	tests := map[string]printfDesc{
		"textonly": {
			script: `printf("helloworld")`,
			output: "helloworld",
		},
		"fmtstring": {
			script: `printf("%s:%s", "hello", "world")`,
			output: "hello:world",
		},
		"fmtlist": {
			script: `
				list = ("1" "2" "3")
				printf("%s:%s", "list", $list)
			`,
			output: "list:1 2 3",
		},
		"listonly": {
			script: `
				list = ("1" "2" "3")
				printf($list)
			`,
			output: "1 2 3",
		},
		"listoflists": {
			script: `
				list = (("1" "2" "3") ("4" "5" "6"))
				printf("%s:%s", "listoflists", $list)
			`,
			output: "listoflists:1 2 3 4 5 6",
		},
		"listasfmt": {
			script: `
				list = ("%s" "%s")
				printf($list, "1", "2")
			`,
			output: "1 2",
		},
	}

	for name, desc := range tests {
		t.Run(name, func(t *testing.T) {
			var output bytes.Buffer
			shell, err := nash.New()

			if err != nil {
				t.Fatalf("unexpected err: %s", err)
			}

			shell.SetStdout(&output)
			err = shell.Exec("", desc.script)

			if err != nil {
				t.Fatalf("unexpected err: %s", err)
			}

			if output.String() != desc.output {
				t.Fatalf("got %q expected %q", output.String(), desc.output)
			}
		})
	}
}

func TestPrintfErrors(t *testing.T) {
	type printfDesc struct {
		script string
	}

	tests := map[string]printfDesc{
		"noParams": {
			script: `printf()`,
		},
	}

	for name, desc := range tests {
		t.Run(name, func(t *testing.T) {
			var output bytes.Buffer
			shell, err := nash.New()

			if err != nil {
				t.Fatalf("unexpected err: %s", err)
			}

			shell.SetStdout(&output)
			err = shell.Exec("", desc.script)

			if err == nil {
				t.Fatalf("expected err, got success, output: %s", output)
			}

			if output.Len() > 0 {
				t.Fatalf("expected empty output, got: %s", output)
			}
		})
	}
}
<|endoftext|>


<commit_before>package weed_server

import (
	"bytes"
	"crypto/md5"
	"hash"
	"io"
	"io/ioutil"
	"net/http"
	"sort"
	"strings"
	"sync"
	"time"

	"github.com/chrislusf/seaweedfs/weed/filer"
	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/chrislusf/seaweedfs/weed/operation"
	"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
	"github.com/chrislusf/seaweedfs/weed/security"
	"github.com/chrislusf/seaweedfs/weed/stats"
	"github.com/chrislusf/seaweedfs/weed/util"
)

var bufPool = sync.Pool{
	New: func() interface{} {
		return new(bytes.Buffer)
	},
}

func (fs *FilerServer) uploadReaderToChunks(w http.ResponseWriter, r *http.Request, reader io.Reader, chunkSize int32, fileName, contentType string, contentLength int64, so *operation.StorageOption) ([]*filer_pb.FileChunk, hash.Hash, int64, error, []byte) {
	var fileChunks []*filer_pb.FileChunk

	md5Hash := md5.New()
	var partReader = ioutil.NopCloser(io.TeeReader(reader, md5Hash))

	chunkOffset := int64(0)
	var smallContent []byte
	var uploadErr error

	var wg sync.WaitGroup
	for {

		// need to throttle this for large files
		bytesBuffer := bufPool.Get().(*bytes.Buffer)
		defer bufPool.Put(bytesBuffer)

		limitedReader := io.LimitReader(partReader, int64(chunkSize))

		bytesBuffer.Reset()

		dataSize, err := bytesBuffer.ReadFrom(limitedReader)

		// data, err := ioutil.ReadAll(limitedReader)
		if err != nil || dataSize == 0 {
			return nil, md5Hash, 0, err, nil
		}
		if chunkOffset == 0 && !isAppend(r) {
			if dataSize < fs.option.SaveToFilerLimit || strings.HasPrefix(r.URL.Path, filer.DirectoryEtcRoot) && dataSize < 4*1024 {
				chunkOffset += dataSize
				smallContent = make([]byte, dataSize)
				bytesBuffer.Write(smallContent)
				break
			}
		}

		wg.Add(1)
		go func(offset int64) {
			defer wg.Done()

			chunk, toChunkErr := fs.dataToChunk(fileName, contentType, bytesBuffer.Bytes(), offset, so, md5Hash)
			if toChunkErr != nil {
				uploadErr = toChunkErr
			}
			if chunk != nil {
				fileChunks = append(fileChunks, chunk)
				glog.V(4).Infof("uploaded %s chunk %d to %s [%d,%d)", fileName, len(fileChunks), chunk.FileId, offset, offset+int64(chunk.Size))
			}
		}(chunkOffset)

		// reset variables for the next chunk
		chunkOffset = chunkOffset + dataSize

		// if last chunk was not at full chunk size, but already exhausted the reader
		if dataSize < int64(chunkSize) {
			break
		}
	}

	wg.Wait()

	if uploadErr != nil {
		return nil, md5Hash, 0, uploadErr, nil
	}

	sort.Slice(fileChunks, func(i, j int) bool {
		return fileChunks[i].Offset < fileChunks[j].Offset
	})

	return fileChunks, md5Hash, chunkOffset, nil, smallContent
}

func (fs *FilerServer) doUpload(urlLocation string, limitedReader io.Reader, fileName string, contentType string, pairMap map[string]string, auth security.EncodedJwt) (*operation.UploadResult, error, []byte) {

	stats.FilerRequestCounter.WithLabelValues("chunkUpload").Inc()
	start := time.Now()
	defer func() {
		stats.FilerRequestHistogram.WithLabelValues("chunkUpload").Observe(time.Since(start).Seconds())
	}()

	uploadResult, err, data := operation.Upload(urlLocation, fileName, fs.option.Cipher, limitedReader, false, contentType, pairMap, auth)
	if uploadResult != nil && uploadResult.RetryCount > 0 {
		stats.FilerRequestCounter.WithLabelValues("chunkUploadRetry").Add(float64(uploadResult.RetryCount))
	}
	return uploadResult, err, data
}

func (fs *FilerServer) dataToChunk(fileName, contentType string, data []byte, chunkOffset int64, so *operation.StorageOption, md5Hash hash.Hash) (*filer_pb.FileChunk, error) {
	dataReader := util.NewBytesReader(data)

	// retry to assign a different file id
	var fileId, urlLocation string
	var auth security.EncodedJwt
	var uploadErr error
	var uploadResult *operation.UploadResult
	for i := 0; i < 3; i++ {
		// assign one file id for one chunk
		fileId, urlLocation, auth, uploadErr = fs.assignNewFileInfo(so)
		if uploadErr != nil {
			glog.V(4).Infof("retry later due to assign error: %v", uploadErr)
			time.Sleep(time.Duration(i+1) * 251 * time.Millisecond)
			continue
		}

		// upload the chunk to the volume server
		uploadResult, uploadErr, _ = fs.doUpload(urlLocation, dataReader, fileName, contentType, nil, auth)
		if uploadErr != nil {
			glog.V(4).Infof("retry later due to upload error: %v", uploadErr)
			time.Sleep(time.Duration(i+1) * 251 * time.Millisecond)
			continue
		}
		break
	}
	if uploadErr != nil {
		glog.Errorf("upload error: %v", uploadErr)
		return nil, uploadErr
	}

	// if last chunk exhausted the reader exactly at the border
	if uploadResult.Size == 0 {
		return nil, nil
	}
	if chunkOffset == 0 {
		uploadedMd5 := util.Base64Md5ToBytes(uploadResult.ContentMd5)
		readedMd5 := md5Hash.Sum(nil)
		if !bytes.Equal(uploadedMd5, readedMd5) {
			glog.Errorf("md5 %x does not match %x uploaded chunk %s to the volume server", readedMd5, uploadedMd5, uploadResult.Name)
		}
	}

	return uploadResult.ToPbFileChunk(fileId, chunkOffset), nil
}
<commit_msg>fix writing the small file<commit_after>package weed_server

import (
	"bytes"
	"crypto/md5"
	"hash"
	"io"
	"io/ioutil"
	"net/http"
	"sort"
	"strings"
	"sync"
	"time"

	"github.com/chrislusf/seaweedfs/weed/filer"
	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/chrislusf/seaweedfs/weed/operation"
	"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
	"github.com/chrislusf/seaweedfs/weed/security"
	"github.com/chrislusf/seaweedfs/weed/stats"
	"github.com/chrislusf/seaweedfs/weed/util"
)

var bufPool = sync.Pool{
	New: func() interface{} {
		return new(bytes.Buffer)
	},
}

func (fs *FilerServer) uploadReaderToChunks(w http.ResponseWriter, r *http.Request, reader io.Reader, chunkSize int32, fileName, contentType string, contentLength int64, so *operation.StorageOption) ([]*filer_pb.FileChunk, hash.Hash, int64, error, []byte) {
	var fileChunks []*filer_pb.FileChunk

	md5Hash := md5.New()
	var partReader = ioutil.NopCloser(io.TeeReader(reader, md5Hash))

	chunkOffset := int64(0)
	var smallContent []byte
	var uploadErr error

	var wg sync.WaitGroup
	for {

		// need to throttle this for large files
		bytesBuffer := bufPool.Get().(*bytes.Buffer)
		defer bufPool.Put(bytesBuffer)

		limitedReader := io.LimitReader(partReader, int64(chunkSize))

		bytesBuffer.Reset()

		dataSize, err := bytesBuffer.ReadFrom(limitedReader)

		// data, err := ioutil.ReadAll(limitedReader)
		if err != nil || dataSize == 0 {
			return nil, md5Hash, 0, err, nil
		}
		if chunkOffset == 0 && !isAppend(r) {
			if dataSize < fs.option.SaveToFilerLimit || strings.HasPrefix(r.URL.Path, filer.DirectoryEtcRoot) && dataSize < 4*1024 {
				chunkOffset += dataSize
				smallContent = make([]byte, dataSize)
				bytesBuffer.Read(smallContent)
				break
			}
		}

		wg.Add(1)
		go func(offset int64) {
			defer wg.Done()

			chunk, toChunkErr := fs.dataToChunk(fileName, contentType, bytesBuffer.Bytes(), offset, so, md5Hash)
			if toChunkErr != nil {
				uploadErr = toChunkErr
			}
			if chunk != nil {
				fileChunks = append(fileChunks, chunk)
				glog.V(4).Infof("uploaded %s chunk %d to %s [%d,%d)", fileName, len(fileChunks), chunk.FileId, offset, offset+int64(chunk.Size))
			}
		}(chunkOffset)

		// reset variables for the next chunk
		chunkOffset = chunkOffset + dataSize

		// if last chunk was not at full chunk size, but already exhausted the reader
		if dataSize < int64(chunkSize) {
			break
		}
	}

	wg.Wait()

	if uploadErr != nil {
		return nil, md5Hash, 0, uploadErr, nil
	}

	sort.Slice(fileChunks, func(i, j int) bool {
		return fileChunks[i].Offset < fileChunks[j].Offset
	})

	return fileChunks, md5Hash, chunkOffset, nil, smallContent
}

func (fs *FilerServer) doUpload(urlLocation string, limitedReader io.Reader, fileName string, contentType string, pairMap map[string]string, auth security.EncodedJwt) (*operation.UploadResult, error, []byte) {

	stats.FilerRequestCounter.WithLabelValues("chunkUpload").Inc()
	start := time.Now()
	defer func() {
		stats.FilerRequestHistogram.WithLabelValues("chunkUpload").Observe(time.Since(start).Seconds())
	}()

	uploadResult, err, data := operation.Upload(urlLocation, fileName, fs.option.Cipher, limitedReader, false, contentType, pairMap, auth)
	if uploadResult != nil && uploadResult.RetryCount > 0 {
		stats.FilerRequestCounter.WithLabelValues("chunkUploadRetry").Add(float64(uploadResult.RetryCount))
	}
	return uploadResult, err, data
}

func (fs *FilerServer) dataToChunk(fileName, contentType string, data []byte, chunkOffset int64, so *operation.StorageOption, md5Hash hash.Hash) (*filer_pb.FileChunk, error) {
	dataReader := util.NewBytesReader(data)

	// retry to assign a different file id
	var fileId, urlLocation string
	var auth security.EncodedJwt
	var uploadErr error
	var uploadResult *operation.UploadResult
	for i := 0; i < 3; i++ {
		// assign one file id for one chunk
		fileId, urlLocation, auth, uploadErr = fs.assignNewFileInfo(so)
		if uploadErr != nil {
			glog.V(4).Infof("retry later due to assign error: %v", uploadErr)
			time.Sleep(time.Duration(i+1) * 251 * time.Millisecond)
			continue
		}

		// upload the chunk to the volume server
		uploadResult, uploadErr, _ = fs.doUpload(urlLocation, dataReader, fileName, contentType, nil, auth)
		if uploadErr != nil {
			glog.V(4).Infof("retry later due to upload error: %v", uploadErr)
			time.Sleep(time.Duration(i+1) * 251 * time.Millisecond)
			continue
		}
		break
	}
	if uploadErr != nil {
		glog.Errorf("upload error: %v", uploadErr)
		return nil, uploadErr
	}

	// if last chunk exhausted the reader exactly at the border
	if uploadResult.Size == 0 {
		return nil, nil
	}
	if chunkOffset == 0 {
		uploadedMd5 := util.Base64Md5ToBytes(uploadResult.ContentMd5)
		readedMd5 := md5Hash.Sum(nil)
		if !bytes.Equal(uploadedMd5, readedMd5) {
			glog.Errorf("md5 %x does not match %x uploaded chunk %s to the volume server", readedMd5, uploadedMd5, uploadResult.Name)
		}
	}

	return uploadResult.ToPbFileChunk(fileId, chunkOffset), nil
}
<|endoftext|>


<commit_before>package main

import (
	"sort"

	"github.com/animenotifier/arn"
	"github.com/fatih/color"
)

const (
	currentlyAiringBonus     = 4.0
	popularityThreshold      = 5
	popularityPenalty        = 4.0
	watchingPopularityWeight = 0.2
)

func main() {
	color.Yellow("Caching airing anime")

	animeList, err := arn.GetAiringAnime()

	if err != nil {
		color.Red("Failed fetching airing anime")
		color.Red(err.Error())
		return
	}

	sort.Slice(animeList, func(i, j int) bool {
		a := animeList[i]
		b := animeList[j]
		scoreA := a.Rating.Overall
		scoreB := b.Rating.Overall

		if a.Status == "current" {
			scoreA += currentlyAiringBonus
		}

		if b.Status == "current" {
			scoreB += currentlyAiringBonus
		}

		if a.Popularity.Total() < popularityThreshold {
			scoreA -= popularityPenalty
		}

		if b.Popularity.Total() < popularityThreshold {
			scoreB -= popularityPenalty
		}

		scoreA += float64(a.Popularity.Watching) * watchingPopularityWeight
		scoreB += float64(b.Popularity.Watching) * watchingPopularityWeight

		return scoreA > scoreB
	})

	// Convert to small anime list
	cache := &arn.ListOfIDs{}

	for _, anime := range animeList {
		cache.IDList = append(cache.IDList, anime.ID)
	}

	println(len(cache.IDList))

	saveErr := arn.DB.Set("Cache", "airing anime", cache)

	if saveErr != nil {
		color.Red("Error saving airing anime")
		color.Red(saveErr.Error())
		return
	}

	color.Green("Finished.")
}
<commit_msg>New weighting for the explore page<commit_after>package main

import (
	"sort"

	"github.com/animenotifier/arn"
	"github.com/fatih/color"
)

const (
	currentlyAiringBonus     = 5.0
	popularityThreshold      = 5
	popularityPenalty        = 8.0
	watchingPopularityWeight = 0.3
	plannedPopularityWeight  = 0.2
)

func main() {
	color.Yellow("Caching airing anime")

	animeList, err := arn.GetAiringAnime()

	if err != nil {
		color.Red("Failed fetching airing anime")
		color.Red(err.Error())
		return
	}

	sort.Slice(animeList, func(i, j int) bool {
		a := animeList[i]
		b := animeList[j]
		scoreA := a.Rating.Overall
		scoreB := b.Rating.Overall

		if a.Status == "current" {
			scoreA += currentlyAiringBonus
		}

		if b.Status == "current" {
			scoreB += currentlyAiringBonus
		}

		if a.Popularity.Total() < popularityThreshold {
			scoreA -= popularityPenalty
		}

		if b.Popularity.Total() < popularityThreshold {
			scoreB -= popularityPenalty
		}

		scoreA += float64(a.Popularity.Watching) * watchingPopularityWeight
		scoreB += float64(b.Popularity.Watching) * watchingPopularityWeight

		scoreA += float64(a.Popularity.Planned) * plannedPopularityWeight
		scoreB += float64(b.Popularity.Planned) * plannedPopularityWeight

		return scoreA > scoreB
	})

	// Convert to small anime list
	cache := &arn.ListOfIDs{}

	for _, anime := range animeList {
		cache.IDList = append(cache.IDList, anime.ID)
	}

	println(len(cache.IDList))

	saveErr := arn.DB.Set("Cache", "airing anime", cache)

	if saveErr != nil {
		color.Red("Error saving airing anime")
		color.Red(saveErr.Error())
		return
	}

	color.Green("Finished.")
}
<|endoftext|>


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

package memory_test

import (
	"sync"
	"testing"

	"istio.io/istio/pilot/pkg/config/memory"
	"istio.io/istio/pilot/pkg/model"
	"istio.io/istio/pilot/test/mock"
)

func TestEventConsistency(t *testing.T) {
	store := memory.Make(mock.Types)
	controller := memory.NewController(store)

	testConfig := mock.Make(TestNamespace, 0)
	var testEvent model.Event

	done := make(chan bool)

	lock := sync.Mutex{}

	controller.RegisterEventHandler(model.MockConfig.Type, func(config model.Config, event model.Event) {

		lock.Lock()
		defer lock.Unlock()

		if event != testEvent {
			t.Errorf("desired %v, but %v", testEvent, event)
		}
		if !mock.Compare(testConfig, config) {
			t.Errorf("desired %v, but %v", testConfig, config)
		}
		done <- true
	})

	stop := make(chan struct{})
	go controller.Run(stop)

	// Test Add Event
	testEvent = model.EventAdd
	var rev string
	var err error
	if rev, err = controller.Create(testConfig); err != nil {
		t.Error(err)
		return
	}

	lock.Lock()
	testConfig.ResourceVersion = rev
	lock.Unlock()

	<-done

	// Test Update Event
	testEvent = model.EventUpdate
	if _, err := controller.Update(testConfig); err != nil {
		t.Error(err)
		return
	}
	<-done

	// Test Delete Event
	testEvent = model.EventDelete
	if err := controller.Delete(model.MockConfig.Type, testConfig.Name, TestNamespace); err != nil {
		t.Error(err)
		return
	}
	<-done
	close(stop)
}
<commit_msg>Fix memory monitor test deadlock (#16224)<commit_after>// Copyright 2017 Istio Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package memory_test

import (
	"sync"
	"testing"

	"istio.io/istio/pilot/pkg/config/memory"
	"istio.io/istio/pilot/pkg/model"
	"istio.io/istio/pilot/test/mock"
)

func TestEventConsistency(t *testing.T) {
	store := memory.Make(mock.Types)
	controller := memory.NewController(store)

	testConfig := mock.Make(TestNamespace, 0)
	var testEvent model.Event

	done := make(chan bool)

	lock := sync.Mutex{}

	controller.RegisterEventHandler(model.MockConfig.Type, func(config model.Config, event model.Event) {

		lock.Lock()
		tc := testConfig
		lock.Unlock()

		if event != testEvent {
			t.Errorf("desired %v, but %v", testEvent, event)
		}
		if !mock.Compare(tc, config) {
			t.Errorf("desired %v, but %v", tc, config)
		}
		done <- true
	})

	stop := make(chan struct{})
	go controller.Run(stop)

	// Test Add Event
	testEvent = model.EventAdd
	var rev string
	var err error
	if rev, err = controller.Create(testConfig); err != nil {
		t.Error(err)
		return
	}

	lock.Lock()
	testConfig.ResourceVersion = rev
	lock.Unlock()

	<-done

	// Test Update Event
	testEvent = model.EventUpdate
	if _, err := controller.Update(testConfig); err != nil {
		t.Error(err)
		return
	}
	<-done

	// Test Delete Event
	testEvent = model.EventDelete
	if err := controller.Delete(model.MockConfig.Type, testConfig.Name, TestNamespace); err != nil {
		t.Error(err)
		return
	}
	<-done
	close(stop)
}
<|endoftext|>


<commit_before>package integration

import (
	"testing"

	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	kapi "k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/apis/autoscaling"
	"k8s.io/kubernetes/pkg/apis/batch"
	expapi "k8s.io/kubernetes/pkg/apis/extensions"

	testutil "github.com/openshift/origin/test/util"
	testserver "github.com/openshift/origin/test/util/server"
)

func TestExtensionsAPIDisabledAutoscaleBatchEnabled(t *testing.T) {
	const projName = "ext-disabled-batch-enabled-proj"

	testutil.RequireEtcd(t)
	defer testutil.DumpEtcdOnFailure(t)
	masterConfig, err := testserver.DefaultMasterOptions()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	// Disable all extensions API versions
	// Leave autoscaling/batch APIs enabled
	masterConfig.KubernetesMasterConfig.DisabledAPIGroupVersions = map[string][]string{"extensions": {"*"}}

	clusterAdminKubeConfig, err := testserver.StartConfiguredMaster(masterConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	clusterAdminKubeClient, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	// create the containing project
	if _, err := testserver.CreateNewProject(clusterAdminClient, *clusterAdminClientConfig, projName, "admin"); err != nil {
		t.Fatalf("unexpected error creating the project: %v", err)
	}
	projectAdminClient, projectAdminKubeClient, _, err := testutil.GetClientForUser(*clusterAdminClientConfig, "admin")
	if err != nil {
		t.Fatalf("unexpected error getting project admin client: %v", err)
	}
	if err := testutil.WaitForPolicyUpdate(projectAdminClient, projName, "get", expapi.Resource("horizontalpodautoscalers"), true); err != nil {
		t.Fatalf("unexpected error waiting for policy update: %v", err)
	}

	validHPA := &autoscaling.HorizontalPodAutoscaler{
		ObjectMeta: metav1.ObjectMeta{Name: "myjob"},
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "foo", Kind: "ReplicationController"},
			MaxReplicas:    1,
		},
	}
	validJob := &batch.Job{
		ObjectMeta: metav1.ObjectMeta{Name: "myjob"},
		Spec: batch.JobSpec{
			Template: kapi.PodTemplateSpec{
				Spec: kapi.PodSpec{
					Containers:    []kapi.Container{{Name: "mycontainer", Image: "myimage"}},
					RestartPolicy: kapi.RestartPolicyNever,
				},
			},
		},
	}

	legacyAutoscalers := legacyExtensionsAutoscaling{
		projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(projName),
		projectAdminKubeClient.Extensions().RESTClient(),
		projName,
	}

	// make sure extensions API objects cannot be listed or created
	if _, err := legacyAutoscalers.List(metav1.ListOptions{}); !errors.IsNotFound(err) {
		t.Fatalf("expected NotFound error listing HPA, got %v", err)
	}
	if _, err := legacyAutoscalers.Create(validHPA); !errors.IsNotFound(err) {
		t.Fatalf("expected NotFound error creating HPA, got %v", err)
	}

	// make sure autoscaling and batch API objects can be listed and created
	if _, err := projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(projName).List(metav1.ListOptions{}); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	}
	if _, err := projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(projName).Create(validHPA); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	}
	if _, err := projectAdminKubeClient.Batch().Jobs(projName).List(metav1.ListOptions{}); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	}
	if _, err := projectAdminKubeClient.Batch().Jobs(projName).Create(validJob); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	}

	// Delete the containing project
	if err := testutil.DeleteAndWaitForNamespaceTermination(clusterAdminKubeClient, projName); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	}

	// recreate the containing project
	if _, err := testserver.CreateNewProject(clusterAdminClient, *clusterAdminClientConfig, projName, "admin"); err != nil {
		t.Fatalf("unexpected error creating the project: %v", err)
	}
	projectAdminClient, projectAdminKubeClient, _, err = testutil.GetClientForUser(*clusterAdminClientConfig, "admin")
	if err != nil {
		t.Fatalf("unexpected error getting project admin client: %v", err)
	}
	if err := testutil.WaitForPolicyUpdate(projectAdminClient, projName, "get", expapi.Resource("horizontalpodautoscalers"), true); err != nil {
		t.Fatalf("unexpected error waiting for policy update: %v", err)
	}

	// make sure the created objects got cleaned up by namespace deletion
	if hpas, err := projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(projName).List(metav1.ListOptions{}); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	} else if len(hpas.Items) > 0 {
		t.Fatalf("expected 0 HPA objects, got %#v", hpas.Items)
	}
	if jobs, err := projectAdminKubeClient.Batch().Jobs(projName).List(metav1.ListOptions{}); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	} else if len(jobs.Items) > 0 {
		t.Fatalf("expected 0 Job objects, got %#v", jobs.Items)
	}
}

func TestExtensionsAPIDisabled(t *testing.T) {
	const projName = "ext-disabled-proj"

	testutil.RequireEtcd(t)
	defer testutil.DumpEtcdOnFailure(t)
	masterConfig, err := testserver.DefaultMasterOptions()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	// Disable all extensions API versions
	masterConfig.KubernetesMasterConfig.DisabledAPIGroupVersions = map[string][]string{"extensions": {"*"}, "autoscaling": {"*"}, "batch": {"*"}}

	clusterAdminKubeConfig, err := testserver.StartConfiguredMaster(masterConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	clusterAdminKubeClient, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	// create the containing project
	if _, err := testserver.CreateNewProject(clusterAdminClient, *clusterAdminClientConfig, projName, "admin"); err != nil {
		t.Fatalf("unexpected error creating the project: %v", err)
	}
	projectAdminClient, projectAdminKubeClient, _, err := testutil.GetClientForUser(*clusterAdminClientConfig, "admin")
	if err != nil {
		t.Fatalf("unexpected error getting project admin client: %v", err)
	}
	if err := testutil.WaitForPolicyUpdate(projectAdminClient, projName, "get", expapi.Resource("horizontalpodautoscalers"), true); err != nil {
		t.Fatalf("unexpected error waiting for policy update: %v", err)
	}

	legacyAutoscalers := legacyExtensionsAutoscaling{
		projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(projName),
		projectAdminKubeClient.Autoscaling().RESTClient(),
		projName,
	}

	// make sure extensions API objects cannot be listed or created
	if _, err := legacyAutoscalers.List(metav1.ListOptions{}); !errors.IsNotFound(err) {
		t.Fatalf("expected NotFound error listing HPA, got %v", err)
	}
	if _, err := legacyAutoscalers.Create(&autoscaling.HorizontalPodAutoscaler{}); !errors.IsNotFound(err) {
		t.Fatalf("expected NotFound error creating HPA, got %v", err)
	}

	// Delete the containing project
	if err := testutil.DeleteAndWaitForNamespaceTermination(clusterAdminKubeClient, projName); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	}
}
<commit_msg>fix-test: non-existing extensions/v1beta1 in TestExtensionsAPIDisabledAutoscaleBatchEnabled<commit_after>package integration

import (
	"strings"
	"testing"

	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	kapi "k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/apis/autoscaling"
	"k8s.io/kubernetes/pkg/apis/batch"
	expapi "k8s.io/kubernetes/pkg/apis/extensions"

	testutil "github.com/openshift/origin/test/util"
	testserver "github.com/openshift/origin/test/util/server"
)

func TestExtensionsAPIDisabledAutoscaleBatchEnabled(t *testing.T) {
	const projName = "ext-disabled-batch-enabled-proj"

	testutil.RequireEtcd(t)
	defer testutil.DumpEtcdOnFailure(t)
	masterConfig, err := testserver.DefaultMasterOptions()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	// Disable all extensions API versions
	// Leave autoscaling/batch APIs enabled
	masterConfig.KubernetesMasterConfig.DisabledAPIGroupVersions = map[string][]string{"extensions": {"*"}}

	clusterAdminKubeConfig, err := testserver.StartConfiguredMaster(masterConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	clusterAdminKubeClient, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	// create the containing project
	if _, err := testserver.CreateNewProject(clusterAdminClient, *clusterAdminClientConfig, projName, "admin"); err != nil {
		t.Fatalf("unexpected error creating the project: %v", err)
	}
	projectAdminClient, projectAdminKubeClient, _, err := testutil.GetClientForUser(*clusterAdminClientConfig, "admin")
	if err != nil {
		t.Fatalf("unexpected error getting project admin client: %v", err)
	}
	if err := testutil.WaitForPolicyUpdate(projectAdminClient, projName, "get", expapi.Resource("horizontalpodautoscalers"), true); err != nil {
		t.Fatalf("unexpected error waiting for policy update: %v", err)
	}

	validHPA := &autoscaling.HorizontalPodAutoscaler{
		ObjectMeta: metav1.ObjectMeta{Name: "myjob"},
		Spec: autoscaling.HorizontalPodAutoscalerSpec{
			ScaleTargetRef: autoscaling.CrossVersionObjectReference{Name: "foo", Kind: "ReplicationController"},
			MaxReplicas:    1,
		},
	}
	validJob := &batch.Job{
		ObjectMeta: metav1.ObjectMeta{Name: "myjob"},
		Spec: batch.JobSpec{
			Template: kapi.PodTemplateSpec{
				Spec: kapi.PodSpec{
					Containers:    []kapi.Container{{Name: "mycontainer", Image: "myimage"}},
					RestartPolicy: kapi.RestartPolicyNever,
				},
			},
		},
	}

	legacyAutoscalers := legacyExtensionsAutoscaling{
		projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(projName),
		projectAdminKubeClient.Extensions().RESTClient(),
		projName,
	}

	// make sure extensions API objects cannot be listed or created
	if _, err := legacyAutoscalers.List(metav1.ListOptions{}); !errors.IsNotFound(err) {
		t.Fatalf("expected NotFound error listing HPA, got %v", err)
	}
	if _, err := legacyAutoscalers.Create(validHPA); !strings.Contains(err.Error(), `not suitable for converting to "extensions/v1beta1"`) {
		t.Fatalf("expected conversion error creating extensions/v1beta1 HPA, got %v", err)
	}

	// make sure autoscaling and batch API objects can be listed and created
	if _, err := projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(projName).List(metav1.ListOptions{}); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	}
	if _, err := projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(projName).Create(validHPA); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	}
	if _, err := projectAdminKubeClient.Batch().Jobs(projName).List(metav1.ListOptions{}); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	}
	if _, err := projectAdminKubeClient.Batch().Jobs(projName).Create(validJob); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	}

	// Delete the containing project
	if err := testutil.DeleteAndWaitForNamespaceTermination(clusterAdminKubeClient, projName); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	}

	// recreate the containing project
	if _, err := testserver.CreateNewProject(clusterAdminClient, *clusterAdminClientConfig, projName, "admin"); err != nil {
		t.Fatalf("unexpected error creating the project: %v", err)
	}
	projectAdminClient, projectAdminKubeClient, _, err = testutil.GetClientForUser(*clusterAdminClientConfig, "admin")
	if err != nil {
		t.Fatalf("unexpected error getting project admin client: %v", err)
	}
	if err := testutil.WaitForPolicyUpdate(projectAdminClient, projName, "get", expapi.Resource("horizontalpodautoscalers"), true); err != nil {
		t.Fatalf("unexpected error waiting for policy update: %v", err)
	}

	// make sure the created objects got cleaned up by namespace deletion
	if hpas, err := projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(projName).List(metav1.ListOptions{}); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	} else if len(hpas.Items) > 0 {
		t.Fatalf("expected 0 HPA objects, got %#v", hpas.Items)
	}
	if jobs, err := projectAdminKubeClient.Batch().Jobs(projName).List(metav1.ListOptions{}); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	} else if len(jobs.Items) > 0 {
		t.Fatalf("expected 0 Job objects, got %#v", jobs.Items)
	}
}

func TestExtensionsAPIDisabled(t *testing.T) {
	const projName = "ext-disabled-proj"

	testutil.RequireEtcd(t)
	defer testutil.DumpEtcdOnFailure(t)
	masterConfig, err := testserver.DefaultMasterOptions()
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	// Disable all extensions API versions
	masterConfig.KubernetesMasterConfig.DisabledAPIGroupVersions = map[string][]string{"extensions": {"*"}, "autoscaling": {"*"}, "batch": {"*"}}

	clusterAdminKubeConfig, err := testserver.StartConfiguredMaster(masterConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	clusterAdminClient, err := testutil.GetClusterAdminClient(clusterAdminKubeConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	clusterAdminKubeClient, err := testutil.GetClusterAdminKubeClient(clusterAdminKubeConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	clusterAdminClientConfig, err := testutil.GetClusterAdminClientConfig(clusterAdminKubeConfig)
	if err != nil {
		t.Fatalf("unexpected error: %v", err)
	}

	// create the containing project
	if _, err := testserver.CreateNewProject(clusterAdminClient, *clusterAdminClientConfig, projName, "admin"); err != nil {
		t.Fatalf("unexpected error creating the project: %v", err)
	}
	projectAdminClient, projectAdminKubeClient, _, err := testutil.GetClientForUser(*clusterAdminClientConfig, "admin")
	if err != nil {
		t.Fatalf("unexpected error getting project admin client: %v", err)
	}
	if err := testutil.WaitForPolicyUpdate(projectAdminClient, projName, "get", expapi.Resource("horizontalpodautoscalers"), true); err != nil {
		t.Fatalf("unexpected error waiting for policy update: %v", err)
	}

	legacyAutoscalers := legacyExtensionsAutoscaling{
		projectAdminKubeClient.Autoscaling().HorizontalPodAutoscalers(projName),
		projectAdminKubeClient.Autoscaling().RESTClient(),
		projName,
	}

	// make sure extensions API objects cannot be listed or created
	if _, err := legacyAutoscalers.List(metav1.ListOptions{}); !errors.IsNotFound(err) {
		t.Fatalf("expected NotFound error listing HPA, got %v", err)
	}
	if _, err := legacyAutoscalers.Create(&autoscaling.HorizontalPodAutoscaler{}); !errors.IsNotFound(err) {
		t.Fatalf("expected NotFound error creating HPA, got %v", err)
	}

	// Delete the containing project
	if err := testutil.DeleteAndWaitForNamespaceTermination(clusterAdminKubeClient, projName); err != nil {
		t.Fatalf("unexpected error: %#v", err)
	}
}
<|endoftext|>


<commit_before>package trades_test

import (
	"testing"

	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/trades"
	"github.com/stretchr/testify/assert"
)

func TestFundingTradeFromRaw(t *testing.T) {
	cases := map[string]struct {
		pld      []interface{}
		expected trades.FundingTrade
		err      func(*testing.T, error)
	}{
		"invalid payload": {
			pld:      []interface{}{401597393},
			expected: trades.FundingTrade{},
			err: func(t *testing.T, err error) {
				assert.Error(t, err)
			},
		},
		"valid payload": {
			pld: []interface{}{133323072, 1574694245478, -258.7458086, 0.0002587, 2},
			expected: trades.FundingTrade{
				Symbol: "fUSD",
				ID:     133323072,
				MTS:    1574694245478,
				Amount: -258.7458086,
				Rate:   0.0002587,
				Period: 2,
			},
			err: func(t *testing.T, err error) {
				assert.NoError(t, err)
			},
		},
	}

	for k, v := range cases {
		t.Run(k, func(t *testing.T) {
			got, err := trades.FTFromRaw("fUSD", v.pld)
			v.err(t, err)
			assert.Equal(t, v.expected, got)
		})
	}
}

func TestFundingTradeExecutionFromRaw(t *testing.T) {
	cases := map[string]struct {
		pld      []interface{}
		expected trades.FundingTradeExecuted
		err      func(*testing.T, error)
	}{
		"invalid payload": {
			pld:      []interface{}{401597393},
			expected: trades.FundingTradeExecuted{},
			err: func(t *testing.T, err error) {
				assert.Error(t, err)
			},
		},
		"valid payload": {
			pld: []interface{}{133323543, 1574694605000, -59.84, 0.00023647, 2},
			expected: trades.FundingTradeExecuted{
				Symbol: "fUSD",
				ID:     133323543,
				MTS:    1574694605000,
				Amount: -59.84,
				Rate:   0.00023647,
				Period: 2,
			},
			err: func(t *testing.T, err error) {
				assert.NoError(t, err)
			},
		},
	}

	for k, v := range cases {
		t.Run(k, func(t *testing.T) {
			got, err := trades.FTEFromRaw("fUSD", v.pld)
			v.err(t, err)
			assert.Equal(t, v.expected, got)
		})
	}
}
<commit_msg>public funding trade execution update raw data mapping to data structure test coverage<commit_after>package trades_test

import (
	"testing"

	"github.com/bitfinexcom/bitfinex-api-go/pkg/models/trades"
	"github.com/stretchr/testify/assert"
)

func TestFundingTradeFromRaw(t *testing.T) {
	cases := map[string]struct {
		pld      []interface{}
		expected trades.FundingTrade
		err      func(*testing.T, error)
	}{
		"invalid payload": {
			pld:      []interface{}{401597393},
			expected: trades.FundingTrade{},
			err: func(t *testing.T, err error) {
				assert.Error(t, err)
			},
		},
		"valid payload": {
			pld: []interface{}{133323072, 1574694245478, -258.7458086, 0.0002587, 2},
			expected: trades.FundingTrade{
				Symbol: "fUSD",
				ID:     133323072,
				MTS:    1574694245478,
				Amount: -258.7458086,
				Rate:   0.0002587,
				Period: 2,
			},
			err: func(t *testing.T, err error) {
				assert.NoError(t, err)
			},
		},
	}

	for k, v := range cases {
		t.Run(k, func(t *testing.T) {
			got, err := trades.FTFromRaw("fUSD", v.pld)
			v.err(t, err)
			assert.Equal(t, v.expected, got)
		})
	}
}

func TestFundingTradeExecutionFromRaw(t *testing.T) {
	cases := map[string]struct {
		pld      []interface{}
		expected trades.FundingTradeExecuted
		err      func(*testing.T, error)
	}{
		"invalid payload": {
			pld:      []interface{}{401597393},
			expected: trades.FundingTradeExecuted{},
			err: func(t *testing.T, err error) {
				assert.Error(t, err)
			},
		},
		"valid payload": {
			pld: []interface{}{133323543, 1574694605000, -59.84, 0.00023647, 2},
			expected: trades.FundingTradeExecuted{
				Symbol: "fUSD",
				ID:     133323543,
				MTS:    1574694605000,
				Amount: -59.84,
				Rate:   0.00023647,
				Period: 2,
			},
			err: func(t *testing.T, err error) {
				assert.NoError(t, err)
			},
		},
	}

	for k, v := range cases {
		t.Run(k, func(t *testing.T) {
			got, err := trades.FTEFromRaw("fUSD", v.pld)
			v.err(t, err)
			assert.Equal(t, v.expected, got)
		})
	}
}

func TestFundingTradeExecutionUpdateFromRaw(t *testing.T) {
	cases := map[string]struct {
		pld      []interface{}
		expected trades.FundingTradeExecutionUpdate
		err      func(*testing.T, error)
	}{
		"invalid payload": {
			pld:      []interface{}{401597393},
			expected: trades.FundingTradeExecutionUpdate{},
			err: func(t *testing.T, err error) {
				assert.Error(t, err)
			},
		},
		"valid payload": {
			pld: []interface{}{133323543, 1574694605000, -59.84, 0.00023647, 2},
			expected: trades.FundingTradeExecutionUpdate{
				Symbol: "fUSD",
				ID:     133323543,
				MTS:    1574694605000,
				Amount: -59.84,
				Rate:   0.00023647,
				Period: 2,
			},
			err: func(t *testing.T, err error) {
				assert.NoError(t, err)
			},
		},
	}

	for k, v := range cases {
		t.Run(k, func(t *testing.T) {
			got, err := trades.FTEUFromRaw("fUSD", v.pld)
			v.err(t, err)
			assert.Equal(t, v.expected, got)
		})
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2014, Rob Thornton
// All rights reserved.
// This source code is governed by a Simplied BSD-License. Please see the
// LICENSE included in this distribution for a copy of the full license
// or, if one is not included, you may also find a copy at
// http://opensource.org/licenses/BSD-2-Clause

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/rthornton128/calc/comp"
)

var calcExt = ".calc"

func cleanup(filename string) {
	os.Remove(filename + ".c")
	os.Remove(filename + ".o")
}

func fatal(args ...interface{}) {
	fmt.Fprintln(os.Stderr, args...)
	os.Exit(1)
}

func findRuntime() string {
	var paths []string
	rpath := "/src/github.com/rthornton128/calc/runtime"
	if runtime.GOOS == "Windows" {
		paths = strings.Split(os.Getenv("GOPATH"), ";")
	} else {
		paths = strings.Split(os.Getenv("GOPATH"), ":")
	}
	for _, path := range paths {
		//fmt.Println("searching:", path+rpath)
		path = filepath.Join(path, rpath)
		_, err := os.Stat(filepath.Join(path, "runtime.a"))
		if err == nil || os.IsExist(err) {
			return path
		}
	}
	return ""
}

func make_args(options ...string) string {
	var args string
	for i, opt := range options {
		if len(opt) > 0 {
			args += opt
			if i < len(options)-1 {
				args += " "
			}
		}
	}
	return args
}

func printVersion() {
	fmt.Fprintln(os.Stderr, "Calc 1 Compiler Tool Version 1.1")
}

func main() {
	ext := ""
	if runtime.GOOS == "windows" {
		ext = ".exe"
	}
	flag.Usage = func() {
		printVersion()
		fmt.Fprintln(os.Stderr, "\nUsage of:", os.Args[0])
		fmt.Fprintln(os.Stderr, os.Args[0], "[flags] <filename>")
		flag.PrintDefaults()
	}
	var (
		cc   = flag.String("cc", "gcc", "C compiler to use")
		cfl  = flag.String("cflags", "-c -std=gnu99", "C compiler flags")
		cout = flag.String("cout", "--output=", "C compiler output flag")
		ld   = flag.String("ld", "gcc", "linker")
		ldf  = flag.String("ldflags", "", "linker flags")
		ver  = flag.Bool("version", false, "Print version number and exit")
	)
	flag.Parse()

	if *ver {
		printVersion()
		os.Exit(1)
	}
	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(1)
	}

	filename := flag.Arg(0)

	if filepath.Ext(filename) != calcExt {
		fatal("Calc source files should have the '.calc' extension")
	}

	/* do a preemptive search to see if runtime can be found. Does not
	 * guarantee it will be there at link time */
	rpath := findRuntime()
	if rpath == "" {
		fatal("Unable to find runtime in GOPATH. Make sure 'make' command was " +
			"run in source directory")
	}

	src, err := ioutil.ReadFile(filename)
	if err != nil {
		fatal(err)
	}
	fmt.Println("Compiling:", filename)

	filename = filename[:len(filename)-len(calcExt)]
	comp.CompileFile(filename, string(src))

	/* compile to object code */
	var out []byte
	args := make_args(*cfl, "-I "+rpath, *cout+filename+".o", filename+".c")
	out, err = exec.Command(*cc+ext, strings.Split(args, " ")...).CombinedOutput()
	if err != nil {
		cleanup(filename)
		fatal(string(out), err)
	}

	/* link to executable */
	args = make_args(*ldf, *cout+filename+ext, filename+".o", "-L "+rpath,
		"runtime.a")
	out, err = exec.Command(*ld+ext, strings.Split(args, " ")...).CombinedOutput()
	if err != nil {
		cleanup(filename)
		fatal(string(out), err)
	}
	cleanup(filename)
}
<commit_msg>fix path to runtime archive<commit_after>// Copyright (c) 2014, Rob Thornton
// All rights reserved.
// This source code is governed by a Simplied BSD-License. Please see the
// LICENSE included in this distribution for a copy of the full license
// or, if one is not included, you may also find a copy at
// http://opensource.org/licenses/BSD-2-Clause

package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"

	"github.com/rthornton128/calc/comp"
)

var calcExt = ".calc"

func cleanup(filename string) {
	os.Remove(filename + ".c")
	os.Remove(filename + ".o")
}

func fatal(args ...interface{}) {
	fmt.Fprintln(os.Stderr, args...)
	os.Exit(1)
}

func findRuntime() string {
	var paths []string
	rpath := "/src/github.com/rthornton128/calc/runtime"
	if runtime.GOOS == "Windows" {
		paths = strings.Split(os.Getenv("GOPATH"), ";")
	} else {
		paths = strings.Split(os.Getenv("GOPATH"), ":")
	}
	for _, path := range paths {
		//fmt.Println("searching:", path+rpath)
		path = filepath.Join(path, rpath)
		_, err := os.Stat(filepath.Join(path, "runtime.a"))
		if err == nil || os.IsExist(err) {
			return path
		}
	}
	return ""
}

func make_args(options ...string) string {
	var args string
	for i, opt := range options {
		if len(opt) > 0 {
			args += opt
			if i < len(options)-1 {
				args += " "
			}
		}
	}
	return args
}

func printVersion() {
	fmt.Fprintln(os.Stderr, "Calc 1 Compiler Tool Version 1.1")
}

func main() {
	ext := ""
	if runtime.GOOS == "windows" {
		ext = ".exe"
	}
	flag.Usage = func() {
		printVersion()
		fmt.Fprintln(os.Stderr, "\nUsage of:", os.Args[0])
		fmt.Fprintln(os.Stderr, os.Args[0], "[flags] <filename>")
		flag.PrintDefaults()
	}
	var (
		cc   = flag.String("cc", "gcc", "C compiler to use")
		cfl  = flag.String("cflags", "-c -std=gnu99", "C compiler flags")
		cout = flag.String("cout", "--output=", "C compiler output flag")
		ld   = flag.String("ld", "gcc", "linker")
		ldf  = flag.String("ldflags", "", "linker flags")
		ver  = flag.Bool("version", false, "Print version number and exit")
	)
	flag.Parse()

	if *ver {
		printVersion()
		os.Exit(1)
	}
	if flag.NArg() != 1 {
		flag.Usage()
		os.Exit(1)
	}

	filename := flag.Arg(0)

	if filepath.Ext(filename) != calcExt {
		fatal("Calc source files should have the '.calc' extension")
	}

	/* do a preemptive search to see if runtime can be found. Does not
	 * guarantee it will be there at link time */
	rpath := findRuntime()
	if rpath == "" {
		fatal("Unable to find runtime in GOPATH. Make sure 'make' command was " +
			"run in source directory")
	}

	src, err := ioutil.ReadFile(filename)
	if err != nil {
		fatal(err)
	}
	fmt.Println("Compiling:", filename)

	filename = filename[:len(filename)-len(calcExt)]
	comp.CompileFile(filename, string(src))

	/* compile to object code */
	var out []byte
	args := make_args(*cfl, "-I "+rpath, *cout+filename+".o", filename+".c")
	out, err = exec.Command(*cc+ext, strings.Split(args, " ")...).CombinedOutput()
	if err != nil {
		cleanup(filename)
		fatal(string(out), err)
	}

	/* link to executable */
	args = make_args(*ldf, *cout+filename+ext, filename+".o", rpath+"/runtime.a")
	out, err = exec.Command(*ld+ext, strings.Split(args, " ")...).CombinedOutput()
	if err != nil {
		cleanup(filename)
		fatal(string(out), err)
	}
	cleanup(filename)
}
<|endoftext|>


<commit_before>package main

import (
	. "github.com/OUCC/prism/logger"

	cv "github.com/lazywei/go-opencv/opencv"

	"bytes"
	"encoding/base64"
	"encoding/json"
	"image/jpeg"
	"io/ioutil"
	"net/http"
	"time"
)

var (
	cam0 *cv.Capture
)

type imageData struct {
	Key   string `json:"key"`
	Image string `json:"image"`
}

func main() {
	setupCamera()

	for {
		if img := capture(); img != nil {
			post(img)
		}

		time.Sleep(CAPTURE_INTERVAL)
	}
}

func setupCamera() {
	cam0 = cv.NewCameraCapture(0)
	if cam0 == nil {
		Log.Fatal("can not open camera")
	}
}

func capture() []byte {
	if !cam0.GrabFrame() {
		return nil
	}

	//!!!DO NOT RELEASE or MODIFY the retrieved frame!!!
	img := cam0.RetrieveFrame(1)
	if img == nil {
		Log.Error("failed to capture")
		return nil
	}

	buf := new(bytes.Buffer)
	err := jpeg.Encode(buf, img.ToImage(), nil)
	if err != nil {
		Log.Error(err.Error())
		return nil
	}
	if DEBUG {
		ioutil.WriteFile("test.jpg", buf.Bytes(), 0644)
	}
	return buf.Bytes()
}

func post(img []byte) {
	b, _ := json.Marshal(imageData{
		Key:   PRISM_KEY,
		Image: base64.StdEncoding.EncodeToString(img),
	})
	resp, err := http.Post(IMG_POST_URL, "application/json", bytes.NewReader(b))
	if err != nil {
		Log.Error(err.Error())
	} else {
		Log.Info(resp.Status)
	}
}
<commit_msg>[ADD] old post method to camera<commit_after>package main

import (
	. "github.com/OUCC/prism/logger"

	cv "github.com/lazywei/go-opencv/opencv"

	"bytes"
	"encoding/base64"
	"encoding/json"
	"image/jpeg"
	"io/ioutil"
	"net/http"
	"net/url"
	"time"
)

var (
	cam0 *cv.Capture
)

type imageData struct {
	Key   string `json:"key"`
	Image string `json:"image"`
}

func main() {
	setupCamera()

	for {
		if img := capture(); img != nil {
			post(img)
			post2(img)
		}

		time.Sleep(CAPTURE_INTERVAL)
	}
}

func setupCamera() {
	cam0 = cv.NewCameraCapture(0)
	if cam0 == nil {
		Log.Fatal("can not open camera")
	}
}

func capture() []byte {
	if !cam0.GrabFrame() {
		return nil
	}

	//!!!DO NOT RELEASE or MODIFY the retrieved frame!!!
	img := cam0.RetrieveFrame(1)
	if img == nil {
		Log.Error("failed to capture")
		return nil
	}

	buf := new(bytes.Buffer)
	err := jpeg.Encode(buf, img.ToImage(), nil)
	if err != nil {
		Log.Error(err.Error())
		return nil
	}
	if DEBUG {
		ioutil.WriteFile("test.jpg", buf.Bytes(), 0644)
	}
	return buf.Bytes()
}

func post(img []byte) {
	b, _ := json.Marshal(imageData{
		Key:   PRISM_KEY,
		Image: base64.StdEncoding.EncodeToString(img),
	})
	resp, err := http.Post(IMG_POST_URL, "application/json", bytes.NewReader(b))
	if err != nil {
		Log.Error(err.Error())
	} else if resp.StatusCode != http.StatusCreated {
		Log.Error(resp.Status)
	} else {
		Log.Info(resp.Status)
	}
}

func post2(img []byte) {
	values := url.Values{}
	values.Add("image", base64.StdEncoding.EncodeToString(img))
	values.Add("key", PRISM_KEY)
	resp, err := http.PostForm(IMG_POST_URL2, values)
	if err != nil {
		Log.Error(err.Error())
	} else if resp.StatusCode != http.StatusOK {
		Log.Error(resp.Status)
	} else {
		Log.Info(resp.Status)
	}
}
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package pipelinex

import (
	"github.com/apache/beam/sdks/go/pkg/beam/core/util/reflectx"
	pb "github.com/apache/beam/sdks/go/pkg/beam/model/pipeline_v1"
)

func shallowClonePipeline(p *pb.Pipeline) *pb.Pipeline {
	ret := &pb.Pipeline{
		Components: shallowCloneComponents(p.GetComponents()),
	}
	ret.RootTransformIds, _ = reflectx.ShallowClone(p.GetRootTransformIds()).([]string)
	return ret
}

func shallowCloneComponents(comp *pb.Components) *pb.Components {
	ret := &pb.Components{}
	ret.Transforms, _ = reflectx.ShallowClone(comp.GetTransforms()).(map[string]*pb.PTransform)
	ret.Pcollections, _ = reflectx.ShallowClone(comp.GetPcollections()).(map[string]*pb.PCollection)
	ret.WindowingStrategies, _ = reflectx.ShallowClone(comp.GetWindowingStrategies()).(map[string]*pb.WindowingStrategy)
	ret.Coders, _ = reflectx.ShallowClone(comp.GetCoders()).(map[string]*pb.Coder)
	ret.Environments, _ = reflectx.ShallowClone(comp.GetEnvironments()).(map[string]*pb.Environment)
	return ret
}

// ShallowClonePTransform makes a shallow copy of the given PTransform.
func ShallowClonePTransform(t *pb.PTransform) *pb.PTransform {
	if t == nil {
		return nil
	}

	ret := &pb.PTransform{
		UniqueName:  t.UniqueName,
		Spec:        t.Spec,
		DisplayData: t.DisplayData,
	}
	ret.Subtransforms, _ = reflectx.ShallowClone(t.Subtransforms).([]string)
	ret.Inputs, _ = reflectx.ShallowClone(t.Inputs).(map[string]string)
	ret.Outputs, _ = reflectx.ShallowClone(t.Outputs).(map[string]string)
	ret.EnvironmentId = t.EnvironmentId
	return ret
}

// ShallowCloneParDoPayload makes a shallow copy of the given ParDoPayload.
func ShallowCloneParDoPayload(p *pb.ParDoPayload) *pb.ParDoPayload {
	if p == nil {
		return nil
	}

	ret := &pb.ParDoPayload{
		DoFn:               p.DoFn,
		Splittable:         p.Splittable,
		RestrictionCoderId: p.RestrictionCoderId,
	}
	ret.Parameters, _ = reflectx.ShallowClone(p.Parameters).([]*pb.Parameter)
	ret.SideInputs, _ = reflectx.ShallowClone(p.SideInputs).(map[string]*pb.SideInput)
	ret.StateSpecs, _ = reflectx.ShallowClone(p.StateSpecs).(map[string]*pb.StateSpec)
	ret.TimerSpecs, _ = reflectx.ShallowClone(p.TimerSpecs).(map[string]*pb.TimerSpec)
	return ret
}

// ShallowCloneSideInput makes a shallow copy of the given SideInput.
func ShallowCloneSideInput(p *pb.SideInput) *pb.SideInput {
	if p == nil {
		return nil
	}
	var ret pb.SideInput
	ret = *p
	return &ret
}

// ShallowCloneFunctionSpec makes a shallow copy of the given FunctionSpec.
func ShallowCloneFunctionSpec(p *pb.FunctionSpec) *pb.FunctionSpec {
	if p == nil {
		return nil
	}
	var ret pb.FunctionSpec
	ret = *p
	return &ret
}
<commit_msg>Go changes for model updates. (#11211)<commit_after>// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements.  See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License.  You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package pipelinex

import (
	"github.com/apache/beam/sdks/go/pkg/beam/core/util/reflectx"
	pb "github.com/apache/beam/sdks/go/pkg/beam/model/pipeline_v1"
)

func shallowClonePipeline(p *pb.Pipeline) *pb.Pipeline {
	ret := &pb.Pipeline{
		Components: shallowCloneComponents(p.GetComponents()),
	}
	ret.RootTransformIds, _ = reflectx.ShallowClone(p.GetRootTransformIds()).([]string)
	return ret
}

func shallowCloneComponents(comp *pb.Components) *pb.Components {
	ret := &pb.Components{}
	ret.Transforms, _ = reflectx.ShallowClone(comp.GetTransforms()).(map[string]*pb.PTransform)
	ret.Pcollections, _ = reflectx.ShallowClone(comp.GetPcollections()).(map[string]*pb.PCollection)
	ret.WindowingStrategies, _ = reflectx.ShallowClone(comp.GetWindowingStrategies()).(map[string]*pb.WindowingStrategy)
	ret.Coders, _ = reflectx.ShallowClone(comp.GetCoders()).(map[string]*pb.Coder)
	ret.Environments, _ = reflectx.ShallowClone(comp.GetEnvironments()).(map[string]*pb.Environment)
	return ret
}

// ShallowClonePTransform makes a shallow copy of the given PTransform.
func ShallowClonePTransform(t *pb.PTransform) *pb.PTransform {
	if t == nil {
		return nil
	}

	ret := &pb.PTransform{
		UniqueName:  t.UniqueName,
		Spec:        t.Spec,
		DisplayData: t.DisplayData,
	}
	ret.Subtransforms, _ = reflectx.ShallowClone(t.Subtransforms).([]string)
	ret.Inputs, _ = reflectx.ShallowClone(t.Inputs).(map[string]string)
	ret.Outputs, _ = reflectx.ShallowClone(t.Outputs).(map[string]string)
	ret.EnvironmentId = t.EnvironmentId
	return ret
}

// ShallowCloneParDoPayload makes a shallow copy of the given ParDoPayload.
func ShallowCloneParDoPayload(p *pb.ParDoPayload) *pb.ParDoPayload {
	if p == nil {
		return nil
	}

	ret := &pb.ParDoPayload{
		DoFn:               p.DoFn,
		RestrictionCoderId: p.RestrictionCoderId,
	}
	ret.SideInputs, _ = reflectx.ShallowClone(p.SideInputs).(map[string]*pb.SideInput)
	ret.StateSpecs, _ = reflectx.ShallowClone(p.StateSpecs).(map[string]*pb.StateSpec)
	ret.TimerSpecs, _ = reflectx.ShallowClone(p.TimerSpecs).(map[string]*pb.TimerSpec)
	return ret
}

// ShallowCloneSideInput makes a shallow copy of the given SideInput.
func ShallowCloneSideInput(p *pb.SideInput) *pb.SideInput {
	if p == nil {
		return nil
	}
	var ret pb.SideInput
	ret = *p
	return &ret
}

// ShallowCloneFunctionSpec makes a shallow copy of the given FunctionSpec.
func ShallowCloneFunctionSpec(p *pb.FunctionSpec) *pb.FunctionSpec {
	if p == nil {
		return nil
	}
	var ret pb.FunctionSpec
	ret = *p
	return &ret
}
<|endoftext|>


<commit_before>// Command aws-gen-gocli parses a JSON description of an AWS API and generates a
// Go file containing a client for the API.
//
//     aws-gen-gocli apis/s3/2006-03-03.normal.json
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"runtime/debug"
	"sort"
	"strings"
	"sync"

	"github.com/awslabs/aws-sdk-go/internal/model/api"
)

type generateInfo struct {
	*api.API
	PackageDir string
}

func newGenerateInfo(modelFile, svcPath string) *generateInfo {
	g := &generateInfo{API: &api.API{}}
	g.API.Attach(modelFile)

	// ensure the directory exists
	pkgDir := filepath.Join(svcPath, g.API.PackageName())
	os.MkdirAll(pkgDir, 0775)

	g.PackageDir = pkgDir

	return g
}

func main() {
	var svcPath string
	flag.StringVar(&svcPath, "path", "service", "generate in a specific directory (default: 'service')")
	flag.Parse()

	files := []string{}
	for i := 0; i < flag.NArg(); i++ {
		file := flag.Arg(i)
		if strings.Contains(file, "*") {
			paths, _ := filepath.Glob(file)
			files = append(files, paths...)
		} else {
			files = append(files, file)
		}
	}

	sort.Strings(files)

	// Remove old API versions from list
	m := map[string]bool{}
	for i := range files {
		idx := len(files) - 1 - i
		parts := strings.Split(files[idx], string(filepath.Separator))
		svc := parts[len(parts)-2] // service name is 2nd-to-last component

		if m[svc] {
			files[idx] = "" // wipe this one out if we already saw the service
		}
		m[svc] = true
	}

	w := sync.WaitGroup{}
	for _, file := range files {
		if file == "" { // empty file
			continue
		}

		w.Add(1)
		go func() {
			defer func() {
				w.Done()
				if r := recover(); r != nil {
					fmtStr := "Error generating %s\n%s\n%s\n"
					fmt.Fprintf(os.Stderr, fmtStr, file, r, debug.Stack())
				}
			}()

			g := newGenerateInfo(file, svcPath)

			// write api.go and service.go files
			g.writeAPIFile()
			g.writeExamplesFile()
			g.writeServiceFile()
		}()
	}
	w.Wait()
}

func (g *generateInfo) writeExamplesFile() {
	file := filepath.Join(g.PackageDir, "examples_test.go")
	ioutil.WriteFile(file, []byte("package "+g.API.PackageName()+"_test\n\n"+g.API.ExampleGoCode()), 0664)
}

func (g *generateInfo) writeServiceFile() {
	file := filepath.Join(g.PackageDir, "service.go")
	ioutil.WriteFile(file, []byte("package "+g.API.PackageName()+"\n\n"+g.API.ServiceGoCode()), 0664)
}

const note = "// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT."

func (g *generateInfo) writeAPIFile() {
	file := filepath.Join(g.PackageDir, "api.go")
	pkg := g.API.PackageName()
	code := fmt.Sprintf("// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.\n\n"+
		"// Package %s provides a client for %s.\n"+
		"package %s\n\n%s", pkg, g.API.Metadata.ServiceFullName, pkg, g.API.APIGoCode())
	ioutil.WriteFile(file, []byte(code), 0664)
}
<commit_msg>Fix generator, ignore unsupported services, add log output<commit_after>// Command aws-gen-gocli parses a JSON description of an AWS API and generates a
// Go file containing a client for the API.
//
//     aws-gen-gocli apis/s3/2006-03-03.normal.json
package main

import (
	"flag"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"runtime/debug"
	"sort"
	"strings"
	"sync"

	"github.com/awslabs/aws-sdk-go/internal/model/api"
)

type generateInfo struct {
	*api.API
	PackageDir string
}

func newGenerateInfo(modelFile, svcPath string) *generateInfo {
	g := &generateInfo{API: &api.API{}}
	g.API.Attach(modelFile)

	// ensure the directory exists
	pkgDir := filepath.Join(svcPath, g.API.PackageName())
	os.MkdirAll(pkgDir, 0775)

	g.PackageDir = pkgDir

	return g
}

func main() {
	var svcPath string
	flag.StringVar(&svcPath, "path", "service", "generate in a specific directory (default: 'service')")
	flag.Parse()

	files := []string{}
	for i := 0; i < flag.NArg(); i++ {
		file := flag.Arg(i)
		if strings.Contains(file, "*") {
			paths, _ := filepath.Glob(file)
			files = append(files, paths...)
		} else {
			files = append(files, file)
		}
	}

	sort.Strings(files)

	// Remove old API versions from list
	m := map[string]bool{}
	for i := range files {
		idx := len(files) - 1 - i
		parts := strings.Split(files[idx], string(filepath.Separator))
		svc := parts[len(parts)-2] // service name is 2nd-to-last component

		if m[svc] {
			files[idx] = "" // wipe this one out if we already saw the service
		}
		m[svc] = true
	}

	w := sync.WaitGroup{}
	for i := range files {
		file := files[i]
		if file == "" { // empty file
			continue
		}

		w.Add(1)
		go func() {
			defer func() {
				w.Done()
				if r := recover(); r != nil {
					fmtStr := "Error generating %s\n%s\n%s\n"
					fmt.Fprintf(os.Stderr, fmtStr, file, r, debug.Stack())
				}
			}()

			g := newGenerateInfo(file, svcPath)

			switch g.API.PackageName() {
			case "simpledb", "importexport", "glacier", "cloudsearchdomain":
				// These services are not yet supported, do nothing.
			default:
				fmt.Printf("Generating %s (%s)...\n",
					g.API.PackageName(), g.API.Metadata.APIVersion)

				// write api.go and service.go files
				g.writeAPIFile()
				g.writeExamplesFile()
				g.writeServiceFile()
			}
		}()
	}
	w.Wait()
}

func (g *generateInfo) writeExamplesFile() {
	file := filepath.Join(g.PackageDir, "examples_test.go")
	ioutil.WriteFile(file, []byte("package "+g.API.PackageName()+"_test\n\n"+g.API.ExampleGoCode()), 0664)
}

func (g *generateInfo) writeServiceFile() {
	file := filepath.Join(g.PackageDir, "service.go")
	ioutil.WriteFile(file, []byte("package "+g.API.PackageName()+"\n\n"+g.API.ServiceGoCode()), 0664)
}

const note = "// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT."

func (g *generateInfo) writeAPIFile() {
	file := filepath.Join(g.PackageDir, "api.go")
	pkg := g.API.PackageName()
	code := fmt.Sprintf("// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.\n\n"+
		"// Package %s provides a client for %s.\n"+
		"package %s\n\n%s", pkg, g.API.Metadata.ServiceFullName, pkg, g.API.APIGoCode())
	ioutil.WriteFile(file, []byte(code), 0664)
}
<|endoftext|>