<commit_before>/*

   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 test

import (
	"bytes"
	"errors"
	"fmt"
	"net/http"

	tc "github.com/apache/incubator-trafficcontrol/lib/go-tc"
	"github.com/apache/incubator-trafficcontrol/traffic_ops/client"
)

var (
	to *client.Session
)

//GetCDN returns a Cdn struct
func GetCDN() (tc.CDN, error) {
	cdns, err := to.CDNs()
	if err != nil {
		return *new(tc.CDN), err
	}
	cdn := cdns[0]
	if cdn.Name == "ALL" {
		cdn = cdns[1]
	}
	return cdn, nil
}

//GetProfile returns a Profile Struct
func GetProfile() (tc.Profile, error) {
	profiles, err := to.Profiles()
	if err != nil {
		return *new(tc.Profile), err
	}
	return profiles[0], nil
}

//GetType returns a Type Struct
func GetType(useInTable string) (tc.Type, error) {
	types, err := to.Types()
	if err != nil {
		return *new(tc.Type), err
	}
	for _, myType := range types {
		if myType.UseInTable == useInTable {
			return myType, nil
		}
	}
	nfErr := fmt.Sprintf("No Types found for useInTable %s\n", useInTable)
	return *new(tc.Type), errors.New(nfErr)
}

//GetDeliveryService returns a DeliveryService Struct
func GetDeliveryService(cdn string) (tc.DeliveryService, error) {
	dss, err := to.DeliveryServices()
	if err != nil {
		return *new(tc.DeliveryService), err
	}
	if cdn != "" {
		for _, ds := range dss {
			if ds.CDNName == cdn {
				return ds, nil
			}
		}
	}
	return dss[0], nil
}

//Request sends a request to TO and returns a response.
//This is basically a copy of the private "request" method in the tc.go \
//but I didn't want to make that one public.
func Request(to client.Session, method, path string, body []byte) (*http.Response, error) {
	url := fmt.Sprintf("%s%s", to.URL, path)

	var req *http.Request
	var err error

	if body != nil && method != "GET" {
		req, err = http.NewRequest(method, url, bytes.NewBuffer(body))
		if err != nil {
			return nil, err
		}
		req.Header.Set("Content-Type", "application/json")
	} else {
		req, err = http.NewRequest("GET", url, nil)
		if err != nil {
			return nil, err
		}
	}

	resp, err := to.Client.Do(req)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode != http.StatusOK {
		e := client.HTTPError{
			HTTPStatus:     resp.Status,
			HTTPStatusCode: resp.StatusCode,
			URL:            url,
		}
		return nil, &e
	}

	return resp, nil
}
<commit_msg>removed import alias<commit_after>/*

   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 test

import (
	"bytes"
	"errors"
	"fmt"
	"net/http"

	"github.com/apache/incubator-trafficcontrol/lib/go-tc"
	"github.com/apache/incubator-trafficcontrol/traffic_ops/client"
)

var (
	to *client.Session
)

//GetCDN returns a Cdn struct
func GetCDN() (tc.CDN, error) {
	cdns, err := to.CDNs()
	if err != nil {
		return *new(tc.CDN), err
	}
	cdn := cdns[0]
	if cdn.Name == "ALL" {
		cdn = cdns[1]
	}
	return cdn, nil
}

//GetProfile returns a Profile Struct
func GetProfile() (tc.Profile, error) {
	profiles, err := to.Profiles()
	if err != nil {
		return *new(tc.Profile), err
	}
	return profiles[0], nil
}

//GetType returns a Type Struct
func GetType(useInTable string) (tc.Type, error) {
	types, err := to.Types()
	if err != nil {
		return *new(tc.Type), err
	}
	for _, myType := range types {
		if myType.UseInTable == useInTable {
			return myType, nil
		}
	}
	nfErr := fmt.Sprintf("No Types found for useInTable %s\n", useInTable)
	return *new(tc.Type), errors.New(nfErr)
}

//GetDeliveryService returns a DeliveryService Struct
func GetDeliveryService(cdn string) (tc.DeliveryService, error) {
	dss, err := to.DeliveryServices()
	if err != nil {
		return *new(tc.DeliveryService), err
	}
	if cdn != "" {
		for _, ds := range dss {
			if ds.CDNName == cdn {
				return ds, nil
			}
		}
	}
	return dss[0], nil
}

//Request sends a request to TO and returns a response.
//This is basically a copy of the private "request" method in the tc.go \
//but I didn't want to make that one public.
func Request(to client.Session, method, path string, body []byte) (*http.Response, error) {
	url := fmt.Sprintf("%s%s", to.URL, path)

	var req *http.Request
	var err error

	if body != nil && method != "GET" {
		req, err = http.NewRequest(method, url, bytes.NewBuffer(body))
		if err != nil {
			return nil, err
		}
		req.Header.Set("Content-Type", "application/json")
	} else {
		req, err = http.NewRequest("GET", url, nil)
		if err != nil {
			return nil, err
		}
	}

	resp, err := to.Client.Do(req)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode != http.StatusOK {
		e := client.HTTPError{
			HTTPStatus:     resp.Status,
			HTTPStatusCode: resp.StatusCode,
			URL:            url,
		}
		return nil, &e
	}

	return resp, nil
}
<|endoftext|>


<commit_before>package config

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"
)

var sampleConfig = `
apikey = "abcde"

[connection]
post_metrics_retry_delay_seconds = 600
post_metrics_retry_max = 5

[plugin.metrics.mysql]
command = "ruby /path/to/your/plugin/mysql.rb"

[sensu.checks.memory] # for backward compatibility
command = "ruby ../sensu/plugins/system/memory-metrics.rb"
type = "metric"
`

func TestLoadConfig(t *testing.T) {
	tmpFile, error := ioutil.TempFile("/tmp", "")
	if error != nil {
		t.Error("should not raise error")
	}
	if err := ioutil.WriteFile(tmpFile.Name(), []byte(sampleConfig), 0644); err != nil {
		t.Error("should not raise error")
	}

	config, err := LoadConfig(tmpFile.Name())
	if err != nil {
		t.Error("should not raise error")
	}

	if config.Apibase != "https://mackerel.io" {
		t.Error("should be https://mackerel.io (arg value should be used)")
	}

	if config.Apikey != "abcde" {
		t.Error("should be abcde (config value should be used)")
	}

	if config.Connection.PostMetricsDequeueDelaySeconds != 30 {
		t.Error("should be 30 (default value should be used)")
	}

	if config.Connection.PostMetricsRetryDelaySeconds != 180 {
		t.Error("should be 180 (max retry delay seconds is 180)")
	}

	if config.Connection.PostMetricsRetryMax != 5 {
		t.Error("should be 5 (config value should be used)")
	}
}

func TestLoadConfigFile(t *testing.T) {
	tmpFile, error := ioutil.TempFile("", "mackerel-config-test")
	if error != nil {
		t.Error("should not raise error")
	}
	if _, err := tmpFile.WriteString(sampleConfig); err != nil {
		t.Fatal("should not raise error")
	}
	tmpFile.Sync()
	tmpFile.Close()
	defer os.Remove(tmpFile.Name())

	config, err := loadConfigFile(tmpFile.Name())
	if err != nil {
		t.Error("should not raise error")
	}

	if config.Apikey != "abcde" {
		t.Error("Apikey should be abcde")
	}

	if config.Connection.PostMetricsRetryMax != 5 {
		t.Error("PostMetricsRetryMax should be 5")
	}

	if config.Plugin["metrics"] == nil {
		t.Error("plugin should have metrics")
	}
	pluginConf := config.Plugin["metrics"]["mysql"]
	if pluginConf.Command != "ruby /path/to/your/plugin/mysql.rb" {
		t.Errorf("plugin conf command should be 'ruby /path/to/your/plugin/mysql.rb' but %v", pluginConf.Command)
	}

	// for backward compatibility
	sensu := config.Plugin["metrics"]["DEPRECATED-sensu-memory"]
	if sensu.Command != "ruby ../sensu/plugins/system/memory-metrics.rb" {
		t.Error("sensu command should be 'ruby ../sensu/plugins/system/memory-metrics.rb'")
	}
}

func assertNoError(t *testing.T, err error) {
	if err != nil {
		t.Error(err)
	}
}

func assert(t *testing.T, ok bool, msg string) {
	if !ok {
		t.Error(msg)
	}
}

func TestLoadConfigFileInclude(t *testing.T) {
	configDir, err := ioutil.TempDir("", "mackerel-config-test")
	assertNoError(t, err)

	configFile, err := ioutil.TempFile("", "mackerel-config-test")
	assertNoError(t, err)

	includedFile, err := os.Create(filepath.Join(configDir, "sub1.conf"))

	configContent := fmt.Sprintf(`
apikey = "not overwritten"
roles = [ "roles", "to be overwritten" ]

include = "%s/*.conf"

[plugin.metrics.foo1]
command = "foo1"

[plugin.metrics.bar]
command = "this wille be overwritten"
`, configDir)

	includedContent := `
roles = [ "Service:role" ]

[plugin.metrics.foo2]
command = "foo2"

[plugin.metrics.bar]
command = "bar"
`

	_, err = configFile.WriteString(configContent)
	assertNoError(t, err)

	_, err = includedFile.WriteString(includedContent)
	assertNoError(t, err)

	configFile.Close()
	includedFile.Close()
	defer os.Remove(configFile.Name())
	defer os.Remove(includedFile.Name())

	config, err := loadConfigFile(configFile.Name())
	assertNoError(t, err)

	assert(t, config.Apikey == "not overwritten", "apikey should not be overwritten")
	assert(t, len(config.Roles) == 1, "roles should be overwritten")
	assert(t, config.Roles[0] == "Service:role", "roles should be overwritten")
	assert(t, config.Plugin["metrics"]["foo1"].Command == "foo1", "plugin.metrics.foo1 should exist")
	assert(t, config.Plugin["metrics"]["foo2"].Command == "foo2", "plugin.metrics.foo2 should exist")
	assert(t, config.Plugin["metrics"]["bar"].Command == "bar", "plugin.metrics.bar should be overwritten")
}
<commit_msg>fix config_test on windows<commit_after>package config

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"
	"strings"
)

var sampleConfig = `
apikey = "abcde"

[connection]
post_metrics_retry_delay_seconds = 600
post_metrics_retry_max = 5

[plugin.metrics.mysql]
command = "ruby /path/to/your/plugin/mysql.rb"

[sensu.checks.memory] # for backward compatibility
command = "ruby ../sensu/plugins/system/memory-metrics.rb"
type = "metric"
`

func TestLoadConfig(t *testing.T) {
	tmpFile, error := ioutil.TempFile("", "")
	if error != nil {
		t.Error("should not raise error")
	}
	if err := ioutil.WriteFile(tmpFile.Name(), []byte(sampleConfig), 0644); err != nil {
		t.Error("should not raise error")
	}

	config, err := LoadConfig(tmpFile.Name())
	if err != nil {
		t.Error("should not raise error")
	}

	if config.Apibase != "https://mackerel.io" {
		t.Error("should be https://mackerel.io (arg value should be used)")
	}

	if config.Apikey != "abcde" {
		t.Error("should be abcde (config value should be used)")
	}

	if config.Connection.PostMetricsDequeueDelaySeconds != 30 {
		t.Error("should be 30 (default value should be used)")
	}

	if config.Connection.PostMetricsRetryDelaySeconds != 180 {
		t.Error("should be 180 (max retry delay seconds is 180)")
	}

	if config.Connection.PostMetricsRetryMax != 5 {
		t.Error("should be 5 (config value should be used)")
	}
}

func TestLoadConfigFile(t *testing.T) {
	tmpFile, error := ioutil.TempFile("", "mackerel-config-test")
	if error != nil {
		t.Error("should not raise error")
	}
	if _, err := tmpFile.WriteString(sampleConfig); err != nil {
		t.Fatal("should not raise error")
	}
	tmpFile.Sync()
	tmpFile.Close()
	defer os.Remove(tmpFile.Name())

	config, err := loadConfigFile(tmpFile.Name())
	if err != nil {
		t.Error("should not raise error")
	}

	if config.Apikey != "abcde" {
		t.Error("Apikey should be abcde")
	}

	if config.Connection.PostMetricsRetryMax != 5 {
		t.Error("PostMetricsRetryMax should be 5")
	}

	if config.Plugin["metrics"] == nil {
		t.Error("plugin should have metrics")
	}
	pluginConf := config.Plugin["metrics"]["mysql"]
	if pluginConf.Command != "ruby /path/to/your/plugin/mysql.rb" {
		t.Errorf("plugin conf command should be 'ruby /path/to/your/plugin/mysql.rb' but %v", pluginConf.Command)
	}

	// for backward compatibility
	sensu := config.Plugin["metrics"]["DEPRECATED-sensu-memory"]
	if sensu.Command != "ruby ../sensu/plugins/system/memory-metrics.rb" {
		t.Error("sensu command should be 'ruby ../sensu/plugins/system/memory-metrics.rb'")
	}
}

func assertNoError(t *testing.T, err error) {
	if err != nil {
		t.Error(err)
	}
}

func assert(t *testing.T, ok bool, msg string) {
	if !ok {
		t.Error(msg)
	}
}

var tomlQuotedReplacer = strings.NewReplacer(
	"\t", "\\t",
	"\n", "\\n",
	"\r", "\\r",
	"\"", "\\\"",
	"\\", "\\\\",
)

func TestLoadConfigFileInclude(t *testing.T) {
	configDir, err := ioutil.TempDir("", "mackerel-config-test")
	assertNoError(t, err)

	configFile, err := ioutil.TempFile("", "mackerel-config-test")
	assertNoError(t, err)

	includedFile, err := os.Create(filepath.Join(configDir, "sub1.conf"))

	configContent := fmt.Sprintf(`
apikey = "not overwritten"
roles = [ "roles", "to be overwritten" ]

include = "%s/*.conf"

[plugin.metrics.foo1]
command = "foo1"

[plugin.metrics.bar]
command = "this wille be overwritten"
`, tomlQuotedReplacer.Replace(configDir))

	includedContent := `
roles = [ "Service:role" ]

[plugin.metrics.foo2]
command = "foo2"

[plugin.metrics.bar]
command = "bar"
`

	_, err = configFile.WriteString(configContent)
	assertNoError(t, err)

	_, err = includedFile.WriteString(includedContent)
	assertNoError(t, err)

	configFile.Close()
	includedFile.Close()
	defer os.Remove(configFile.Name())
	defer os.Remove(includedFile.Name())

	config, err := loadConfigFile(configFile.Name())
	assertNoError(t, err)

	assert(t, config.Apikey == "not overwritten", "apikey should not be overwritten")
	assert(t, len(config.Roles) == 1, "roles should be overwritten")
	assert(t, config.Roles[0] == "Service:role", "roles should be overwritten")
	assert(t, config.Plugin["metrics"]["foo1"].Command == "foo1", "plugin.metrics.foo1 should exist")
	assert(t, config.Plugin["metrics"]["foo2"].Command == "foo2", "plugin.metrics.foo2 should exist")
	assert(t, config.Plugin["metrics"]["bar"].Command == "bar", "plugin.metrics.bar should be overwritten")
}
<|endoftext|>


<commit_before>package middleware

import (
	"net/url"
	"testing"

	"github.com/stretchr/testify/require"
)

func Test_maskSecrets(t *testing.T) {
	r := require.New(t)
	pl := parameterLogger{}

	filteredForm := pl.maskSecrets(url.Values{
		"FirstName":            []string{"Antonio"},
		"MiddleName":           []string{"José"},
		"LastName":             []string{"Pagano"},
		"Password":             []string{"Secret!"},
		"password":             []string{"Other"},
		"pAssWorD":             []string{"Weird one"},
		"PasswordConfirmation": []string{"Secret!"},

		"SomeCVC": []string{"Untouched"},
	})

	r.Equal(filteredForm.Get("Password"), filteredIndicator[0])
	r.Equal(filteredForm.Get("password"), filteredIndicator[0])
	r.Equal(filteredForm.Get("pAssWorD"), filteredIndicator[0])
	r.Equal(filteredForm.Get("PasswordConfirmation"), filteredIndicator[0])
	r.Equal(filteredForm.Get("LastName"), "Pagano")
	r.Equal(filteredForm.Get("SomeCVC"), "Untouched")
}

func Test_maskSecretsCustom(t *testing.T) {
	r := require.New(t)
	ParameterFilterBlackList = []string{
		"FirstName", "LastName", "MiddleName",
	}

	pl := parameterLogger{}

	filteredForm := pl.maskSecrets(url.Values{
		"FirstName":            []string{"Antonio"},
		"MiddleName":           []string{"José"},
		"LastName":             []string{"Pagano"},
		"Password":             []string{"Secret!"},
		"password":             []string{"Other"},
		"pAssWorD":             []string{"Weird one"},
		"PasswordConfirmation": []string{"Secret!"},

		"SomeCVC": []string{"Untouched"},
	})

	r.Equal(filteredForm.Get("Password"), "Secret!")
	r.Equal(filteredForm.Get("password"), "Other")
	r.Equal(filteredForm.Get("LastName"), filteredIndicator[0])
	r.Equal(filteredForm.Get("SomeCVC"), "Untouched")
}
<commit_msg>adding a bit more of tests<commit_after>package middleware

import (
	"net/url"
	"testing"

	"github.com/gobuffalo/buffalo"
	"github.com/markbates/willie"
	"github.com/sirupsen/logrus"
	"github.com/stretchr/testify/require"
)

func Test_maskSecrets(t *testing.T) {
	r := require.New(t)
	pl := parameterLogger{}

	filteredForm := pl.maskSecrets(url.Values{
		"FirstName":            []string{"Antonio"},
		"MiddleName":           []string{"José"},
		"LastName":             []string{"Pagano"},
		"Password":             []string{"Secret!"},
		"password":             []string{"Other"},
		"pAssWorD":             []string{"Weird one"},
		"PasswordConfirmation": []string{"Secret!"},

		"SomeCVC": []string{"Untouched"},
	})

	r.Equal(filteredForm.Get("Password"), filteredIndicator[0])
	r.Equal(filteredForm.Get("password"), filteredIndicator[0])
	r.Equal(filteredForm.Get("pAssWorD"), filteredIndicator[0])
	r.Equal(filteredForm.Get("PasswordConfirmation"), filteredIndicator[0])
	r.Equal(filteredForm.Get("LastName"), "Pagano")
	r.Equal(filteredForm.Get("SomeCVC"), "Untouched")
}

func Test_maskSecretsCustom(t *testing.T) {
	r := require.New(t)
	ParameterFilterBlackList = []string{
		"FirstName", "LastName", "MiddleName",
	}

	pl := parameterLogger{}

	filteredForm := pl.maskSecrets(url.Values{
		"FirstName":            []string{"Antonio"},
		"MiddleName":           []string{"José"},
		"LastName":             []string{"Pagano"},
		"Password":             []string{"Secret!"},
		"password":             []string{"Other"},
		"pAssWorD":             []string{"Weird one"},
		"PasswordConfirmation": []string{"Secret!"},

		"SomeCVC": []string{"Untouched"},
	})

	r.Equal(filteredForm.Get("Password"), "Secret!")
	r.Equal(filteredForm.Get("password"), "Other")
	r.Equal(filteredForm.Get("LastName"), filteredIndicator[0])
	r.Equal(filteredForm.Get("SomeCVC"), "Untouched")
}

var lastEntry *logrus.Entry

type testHook struct{}

func (th testHook) Levels() []logrus.Level {
	return logrus.AllLevels
}

func (th testHook) Fire(entry *logrus.Entry) error {
	lastEntry = entry
	return nil
}

type testLogger struct {
	logrus.FieldLogger
}

func (l testLogger) WithField(s string, i interface{}) buffalo.Logger {
	return testLogger{l.FieldLogger.WithField(s, i)}
}

func (l testLogger) WithFields(m map[string]interface{}) buffalo.Logger {
	return testLogger{l.FieldLogger.WithFields(m)}
}

func newTestLogger() testLogger {
	l := logrus.New()
	l.AddHook(testHook{})
	l.Level, _ = logrus.ParseLevel("debug")

	return testLogger{l}
}

func Test_Logger(t *testing.T) {
	r := require.New(t)
	app := buffalo.New(buffalo.Options{})
	app.Use(ParameterLogger)
	app.Logger = newTestLogger()
	emptyHandler := func(c buffalo.Context) error {
		return nil
	}

	app.GET("/", emptyHandler)
	app.POST("/", emptyHandler)

	wi := willie.New(app)
	wi.HTML("/?param=value").Get()

	r.Contains(lastEntry.Data["params"], "{\"param\":[\"value\"]}")

	wi.HTML("/").Post(url.Values{
		"Password": []string{"123"},
		"Name":     []string{"Antonio"},
		"CVC":      []string{"123"},
	})

	r.Equal(lastEntry.Data["form"], "{\"CVC\":[\"[FILTERED]\"],\"Name\":[\"Antonio\"],\"Password\":[\"[FILTERED]\"]")

}
<|endoftext|>


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

// Macpanic summarizes macOS panic logs.
//
// Usage:
//
//	macpanic [-k kernel] [file...]
//
// Macpanic reads each of the named panic logs and summarizes the panic.
// With no arguments it reads /Library/Logs/DiagnosticReports/Kernel*panic.
// To add symbol information to the panic summary, macpanic uses symbols
// from kernel (default /System/Library/Kernels/kernel) and also inspects
// installed kernel modules.
package main

import (
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"unicode/utf8"

	"github.com/ianlancetaylor/demangle"
)

func usage() {
	fmt.Fprintf(os.Stderr, "usage: macpanic [-k kernel] [file...]\n")
	os.Exit(2)
}

var kernel = flag.String("k", "/System/Library/Kernels/kernel", "kernel binary")
var version string

type sym struct {
	addr uint64
	name string
}

var syms []sym

func main() {
	log.SetPrefix("macpanic: ")
	log.SetFlags(0)
	flag.Usage = usage
	flag.Parse()

	data, err := ioutil.ReadFile(*kernel)
	if err != nil {
		log.Fatal(err)
	}
	i := bytes.Index(data, []byte("Darwin Kernel Version"))
	if i < 0 {
		log.Fatalf("cannot find 'Darwin Kernel Version' in kernel")
	}
	data = data[i:]
	i = bytes.IndexByte(data, 0)
	if i < 0 || !utf8.Valid(data[:i]) {
		log.Fatalf("found malformed 'Darwin Kernel Version' in kernel")
	}
	version = string(data[:i])
	fmt.Printf("kernel %s: %s\n", *kernel, version)

	syms, err = nm(*kernel)
	if err != nil {
		log.Fatal(err)
	}

	args := flag.Args()
	if len(args) == 0 {
		list, err := filepath.Glob("/Library/Logs/DiagnosticReports/Kernel*panic")
		if err != nil {
			log.Fatal(err)
		}
		args = list
	}
	for _, arg := range args {
		process(arg)
	}
}

func nm(file string) ([]sym, error) {
	var syms []sym
	data, err := exec.Command("nm", file).Output()
	if err != nil {
		return nil, fmt.Errorf("nm %s: %v", file, err)
	}
	for _, line := range bytes.Split(data, []byte("\n")) {
		i := bytes.IndexByte(line, ' ')
		if i < 0 {
			continue
		}
		j := bytes.IndexByte(line[i+1:], ' ')
		if i < 0 {
			continue
		}
		j += i + 1
		addr, err := strconv.ParseUint(string(line[:i]), 16, 64)
		if err != nil {
			continue
		}
		name := string(line[j+1:])
		syms = append(syms, sym{addr, name})
	}
	sort.Slice(syms, func(i, j int) bool {
		return syms[i].addr < syms[j].addr
	})
	return syms, nil
}

func process(file string) {
	data, err := ioutil.ReadFile(file)
	if err != nil {
		log.Print(err)
		return
	}

	i := bytes.Index(data, []byte("Kernel slide:"))
	if i < 0 {
		log.Printf("%s: cannot find kernel slide", file)
		return
	}
	j := bytes.IndexByte(data[i:], '\n')
	if j < 0 {
		log.Printf("%s: cannot find kernel slide", file)
		return
	}
	j += i

	s := strings.TrimSpace(string(data[i+len("Kernel slide:") : j]))
	slide, err := strconv.ParseUint(s, 0, 64)
	if err != nil {
		log.Printf("%s: cannot parse kernel slide %q", file, s)
		return
	}

	i = bytes.Index(data, []byte("Kernel text base:"))
	if i < 0 {
		log.Printf("%s: cannot find kernel slide", file)
		return
	}
	j = bytes.IndexByte(data[i:], '\n')
	if j < 0 {
		log.Printf("%s: cannot find kernel text base", file)
		return
	}
	j += i
	s = strings.TrimSpace(string(data[i+len("Kernel text base:") : j]))
	base, err := strconv.ParseUint(s, 0, 64)
	if err != nil {
		log.Printf("%s: cannot parse kernel text base %q", file, s)
		return
	}

	i = bytes.Index(data, []byte("Kernel version:\n"))
	if i < 0 {
		log.Printf("%s: cannot find kernel version", file)
		return
	}
	j = bytes.IndexByte(data[i+len("Kernel version:\n"):], '\n')
	if j < 0 {
		log.Printf("%s: cannot find kernel version", file)
		return
	}
	j += i + len("Kernel version:\n")
	v := string(data[i+len("Kernel version:\n") : j])
	if v != version {
		log.Printf("%s: mismatched kernel version %q != %q", file, v, version)
		return
	}

	i = bytes.Index(data, []byte("\npanic"))
	if i < 0 {
		log.Printf("%s: cannot find panic", file)
		return
	}
	i++
	j = bytes.Index(data[i:], []byte("\n"))
	if j < 0 {
		log.Printf("%s: cannot find panic", file)
		return
	}
	p := string(data[i : i+j])

	i = bytes.Index(data, []byte("\nBacktrace"))
	if i < 0 {
		log.Printf("%s: cannot find backtrace", file)
		return
	}

	var trace [][2]uint64
	var exts []sym
	lines := bytes.Split(data[i+1:], []byte("\n"))[1:]
	for len(lines) > 0 {
		line := strings.TrimSpace(string(lines[0]))
		if line == "" {
			break
		}
		lines = lines[1:]
		if strings.HasPrefix(line, "Kernel Extensions in backtrace") {
			for len(lines) > 0 {
				line := strings.TrimSpace(string(lines[0]))
				if line == "" {
					break
				}
				lines = lines[1:]
				i := strings.Index(line, "(")
				if i < 0 {
					break
				}
				j := strings.LastIndex(line, "@")
				if j < 0 {
					break
				}
				name := line[:i]
				addr := line[j+1:]
				if i := strings.Index(addr, "->"); i >= 0 {
					addr = addr[:i]
				}
				a, err := strconv.ParseUint(addr, 0, 64)
				if err != nil {
					log.Printf("%s: cannot parse extension address: %s", file, line)
					continue
				}
				exts = append(exts, sym{a, name})
			}
			break
		}
		i := strings.Index(line, " : ")
		if i < 0 {
			log.Printf("%s: cannot parse backtrace line: %s", file, line)
			break
		}
		a, err := strconv.ParseUint(line[:i], 0, 64)
		b, err1 := strconv.ParseUint(line[i+3:], 0, 64)
		if err != nil || err1 != nil {
			log.Printf("%s: cannot parse backtrace line: %s", file, line)
			break
		}
		trace = append(trace, [2]uint64{a, b})
	}

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

	fmt.Printf("\n%s\n", file)
	fmt.Printf("\t%s\n", p)
	for _, t := range trace {
		var desc string
		if t[1] < base {
			desc = translate(t[1], exts, true)
		} else {
			desc = translate(t[1]-slide, syms, false)
		}
		fmt.Printf("\t%#x : %#x : %s\n", t[0], t[1], desc)
	}
}

func translate(pc uint64, syms []sym, exts bool) string {
	i := sort.Search(len(syms), func(i int) bool {
		return i+1 >= len(syms) || syms[i+1].addr > pc
	})
	if i >= len(syms) {
		return "???"
	}
	name := syms[i].name
	n, err := demangle.ToString(name)
	if err != nil {
		n, err = demangle.ToString(strings.TrimPrefix(name, "_"))
	}
	if err == nil {
		name = n
	}
	desc := fmt.Sprintf("%s + %#x", name, pc-syms[i].addr)
	if exts {
		elem := syms[i].name[strings.LastIndex(syms[i].name, ".")+1:]
		esyms, err := nm("/System/Library/Extensions/" + elem + ".kext/Contents/MacOS/" + elem)
		if err == nil {
			d := translate(pc-syms[i].addr, esyms, false)
			if d != "???" {
				desc += " (" + d + ")"
			}
		}
	}
	return desc
}
<commit_msg>macpanic: fix lookup for a few extensions<commit_after>// Copyright 2017 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Macpanic summarizes macOS panic logs.
//
// Usage:
//
//	macpanic [-k kernel] [file...]
//
// Macpanic reads each of the named panic logs and summarizes the panic.
// With no arguments it reads /Library/Logs/DiagnosticReports/Kernel*panic.
// To add symbol information to the panic summary, macpanic uses symbols
// from kernel (default /System/Library/Kernels/kernel) and also inspects
// installed kernel modules.
package main

import (
	"bytes"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"unicode/utf8"

	"github.com/ianlancetaylor/demangle"
)

func usage() {
	fmt.Fprintf(os.Stderr, "usage: macpanic [-k kernel] [file...]\n")
	os.Exit(2)
}

var kernel = flag.String("k", "/System/Library/Kernels/kernel", "kernel binary")
var version string

type sym struct {
	addr uint64
	name string
}

var syms []sym

func main() {
	log.SetPrefix("macpanic: ")
	log.SetFlags(0)
	flag.Usage = usage
	flag.Parse()

	data, err := ioutil.ReadFile(*kernel)
	if err != nil {
		log.Fatal(err)
	}
	i := bytes.Index(data, []byte("Darwin Kernel Version"))
	if i < 0 {
		log.Fatalf("cannot find 'Darwin Kernel Version' in kernel")
	}
	data = data[i:]
	i = bytes.IndexByte(data, 0)
	if i < 0 || !utf8.Valid(data[:i]) {
		log.Fatalf("found malformed 'Darwin Kernel Version' in kernel")
	}
	version = string(data[:i])
	fmt.Printf("kernel %s: %s\n", *kernel, version)

	syms, err = nm(*kernel)
	if err != nil {
		log.Fatal(err)
	}

	args := flag.Args()
	if len(args) == 0 {
		list, err := filepath.Glob("/Library/Logs/DiagnosticReports/Kernel*panic")
		if err != nil {
			log.Fatal(err)
		}
		args = list
	}
	for _, arg := range args {
		process(arg)
	}
}

func nm(file string) ([]sym, error) {
	var syms []sym
	data, err := exec.Command("nm", file).Output()
	if err != nil {
		return nil, fmt.Errorf("nm %s: %v", file, err)
	}
	for _, line := range bytes.Split(data, []byte("\n")) {
		i := bytes.IndexByte(line, ' ')
		if i < 0 {
			continue
		}
		j := bytes.IndexByte(line[i+1:], ' ')
		if i < 0 {
			continue
		}
		j += i + 1
		addr, err := strconv.ParseUint(string(line[:i]), 16, 64)
		if err != nil {
			continue
		}
		name := string(line[j+1:])
		syms = append(syms, sym{addr, name})
	}
	sort.Slice(syms, func(i, j int) bool {
		return syms[i].addr < syms[j].addr
	})
	return syms, nil
}

func process(file string) {
	data, err := ioutil.ReadFile(file)
	if err != nil {
		log.Print(err)
		return
	}

	i := bytes.Index(data, []byte("Kernel slide:"))
	if i < 0 {
		log.Printf("%s: cannot find kernel slide", file)
		return
	}
	j := bytes.IndexByte(data[i:], '\n')
	if j < 0 {
		log.Printf("%s: cannot find kernel slide", file)
		return
	}
	j += i

	s := strings.TrimSpace(string(data[i+len("Kernel slide:") : j]))
	slide, err := strconv.ParseUint(s, 0, 64)
	if err != nil {
		log.Printf("%s: cannot parse kernel slide %q", file, s)
		return
	}

	i = bytes.Index(data, []byte("Kernel text base:"))
	if i < 0 {
		log.Printf("%s: cannot find kernel slide", file)
		return
	}
	j = bytes.IndexByte(data[i:], '\n')
	if j < 0 {
		log.Printf("%s: cannot find kernel text base", file)
		return
	}
	j += i
	s = strings.TrimSpace(string(data[i+len("Kernel text base:") : j]))
	base, err := strconv.ParseUint(s, 0, 64)
	if err != nil {
		log.Printf("%s: cannot parse kernel text base %q", file, s)
		return
	}

	i = bytes.Index(data, []byte("Kernel version:\n"))
	if i < 0 {
		log.Printf("%s: cannot find kernel version", file)
		return
	}
	j = bytes.IndexByte(data[i+len("Kernel version:\n"):], '\n')
	if j < 0 {
		log.Printf("%s: cannot find kernel version", file)
		return
	}
	j += i + len("Kernel version:\n")
	v := string(data[i+len("Kernel version:\n") : j])
	if v != version {
		log.Printf("%s: mismatched kernel version %q != %q", file, v, version)
		return
	}

	i = bytes.Index(data, []byte("\npanic"))
	if i < 0 {
		log.Printf("%s: cannot find panic", file)
		return
	}
	i++
	j = bytes.Index(data[i:], []byte("\n"))
	if j < 0 {
		log.Printf("%s: cannot find panic", file)
		return
	}
	p := string(data[i : i+j])

	i = bytes.Index(data, []byte("\nBacktrace"))
	if i < 0 {
		log.Printf("%s: cannot find backtrace", file)
		return
	}

	var trace [][2]uint64
	var exts []sym
	lines := bytes.Split(data[i+1:], []byte("\n"))[1:]
	for len(lines) > 0 {
		line := strings.TrimSpace(string(lines[0]))
		if line == "" {
			break
		}
		lines = lines[1:]
		if strings.HasPrefix(line, "Kernel Extensions in backtrace") {
			for len(lines) > 0 {
				line := strings.TrimSpace(string(lines[0]))
				if line == "" {
					break
				}
				lines = lines[1:]
				i := strings.Index(line, "(")
				if i < 0 {
					break
				}
				j := strings.LastIndex(line, "@")
				if j < 0 {
					break
				}
				name := line[:i]
				addr := line[j+1:]
				if i := strings.Index(addr, "->"); i >= 0 {
					addr = addr[:i]
				}
				a, err := strconv.ParseUint(addr, 0, 64)
				if err != nil {
					log.Printf("%s: cannot parse extension address: %s", file, line)
					continue
				}
				exts = append(exts, sym{a, name})
			}
			break
		}
		i := strings.Index(line, " : ")
		if i < 0 {
			log.Printf("%s: cannot parse backtrace line: %s", file, line)
			break
		}
		a, err := strconv.ParseUint(line[:i], 0, 64)
		b, err1 := strconv.ParseUint(line[i+3:], 0, 64)
		if err != nil || err1 != nil {
			log.Printf("%s: cannot parse backtrace line: %s", file, line)
			break
		}
		trace = append(trace, [2]uint64{a, b})
	}

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

	fmt.Printf("\n%s\n", file)
	fmt.Printf("\t%s\n", p)
	for _, t := range trace {
		var desc string
		if t[1] < base {
			desc = translate(t[1], exts, true)
		} else {
			desc = translate(t[1]-slide, syms, false)
		}
		fmt.Printf("\t%#x : %#x : %s\n", t[0], t[1], desc)
	}
}

func translate(pc uint64, syms []sym, exts bool) string {
	i := sort.Search(len(syms), func(i int) bool {
		return i+1 >= len(syms) || syms[i+1].addr > pc
	})
	if i >= len(syms) {
		return "???"
	}
	name := syms[i].name
	n, err := demangle.ToString(name)
	if err != nil {
		n, err = demangle.ToString(strings.TrimPrefix(name, "_"))
	}
	if err == nil {
		name = n
	}
	desc := fmt.Sprintf("%s + %#x", name, pc-syms[i].addr)
	if exts {
		name := strings.TrimSuffix(syms[i].name, ".kext")
		elem := name[strings.LastIndex(name, ".")+1:]
		esyms, err := nm("/System/Library/Extensions/" + elem + ".kext/Contents/MacOS/" + elem)
		if err != nil {
			esyms, err = nm("/Library/Extensions/" + elem + ".kext/Contents/MacOS/" + elem)
		}
		if err == nil {
			d := translate(pc-syms[i].addr, esyms, false)
			if d != "???" {
				desc += " (" + d + ")"
			}
		}
	}
	return desc
}
<|endoftext|>


<commit_before>package gqt_test

import (
	"code.cloudfoundry.org/garden"
	"code.cloudfoundry.org/guardian/gqt/runner"

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

var _ = Describe("runC Logging", func() {
	var (
		client   *runner.RunningGarden
		logLevel string
	)

	BeforeEach(func() {
		skipIfContainerd()
	})

	JustBeforeEach(func() {
		binPath, err := gexec.Build("code.cloudfoundry.org/guardian/gqt/cmd/fake_runc")
		Expect(err).NotTo(HaveOccurred())

		containerSpec := garden.ContainerSpec{}

		config.RuntimePluginBin = binPath
		config.LogLevel = logLevel
		client = runner.Start(config)
		client.Create(containerSpec)
	})

	AfterEach(func() {
		Expect(client.DestroyAndStop()).To(Succeed())
	})

	Context("when the log-level is set to debug", func() {
		BeforeEach(func() {
			logLevel = "debug"
		})

		It("logs runc logs to stdout", func() {
			Eventually(client, "1s").Should(gbytes.Say("guardian-runc-logging-test-info"))
			Eventually(client, "1s").Should(gbytes.Say("guardian-runc-logging-test-warn"))
			Eventually(client, "1s").Should(gbytes.Say("guardian-runc-logging-test-error"))
			Eventually(client, "1s").Should(gbytes.Say("guardian-runc-logging-test-print"))
		})
	})

	Context("when the log-level is set to info", func() {
		BeforeEach(func() {
			logLevel = "info"
		})

		It("does not log runc logs to stdout", func() {
			Consistently(client, "1s").ShouldNot(gbytes.Say("guardian-runc-logging-test-info"))
			Consistently(client, "1s").ShouldNot(gbytes.Say("guardian-runc-logging-test-warn"))
			Consistently(client, "1s").ShouldNot(gbytes.Say("guardian-runc-logging-test-error"))
			Consistently(client, "1s").ShouldNot(gbytes.Say("guardian-runc-logging-test-print"))
		})
	})
})

var _ = Describe("garden server Logging", func() {
	var (
		client *runner.RunningGarden
	)

	JustBeforeEach(func() {
		client = runner.Start(config)
	})

	Context("when the log-level is passed as debug", func() {
		BeforeEach(func() {
			config.LogLevel = "debug"
		})

		AfterEach(func() {
			Expect(client.DestroyAndStop()).To(Succeed())
		})

		It("logs at debug level", func() {
			// create a container in order to execute a code path that prints debug
			// logs
			_, err := client.Create(garden.ContainerSpec{})
			Expect(err).NotTo(HaveOccurred())

			Eventually(client, "1s").Should(gbytes.Say(`"log_level":0`))
		})

		It("doesn't log spurious messages on start", func() {
			Consistently(client).ShouldNot(gbytes.Say(`guardian.iptables-runner.command.failed`))
			Consistently(client).ShouldNot(gbytes.Say(`guardian.failed-to-parse-port-pool-properties`))

			Eventually(client).Should(gbytes.Say(`guardian.no-port-pool-state-to-recover-starting-clean`))
		})
	})

	Context("when log-level is not passed", func() {
		AfterEach(func() {
			Expect(client.Stop()).To(Succeed())
		})

		It("logs at info level", func() {
			Eventually(client, "1s").Should(gbytes.Say(`"log_level":1`))
		})

		It("does not log at debug level", func() {
			Consistently(client, "1s").ShouldNot(gbytes.Say(`"log_level":0`))
		})
	})

	Context("when a nonsense log-level is passed", func() {
		BeforeEach(func() {
			config.StartupExpectedToFail = true
			config.LogLevel = "nonsense-log-level"
		})

		It("exits with a code of 1", func() {
			Eventually(client, "1s").Should(gexec.Exit(1))
		})
	})
})
<commit_msg>Fix log level test<commit_after>package gqt_test

import (
	"code.cloudfoundry.org/garden"
	"code.cloudfoundry.org/guardian/gqt/runner"

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

var _ = Describe("runC Logging", func() {
	var (
		client   *runner.RunningGarden
		logLevel string
	)

	BeforeEach(func() {
		skipIfContainerd()
	})

	JustBeforeEach(func() {
		binPath, err := gexec.Build("code.cloudfoundry.org/guardian/gqt/cmd/fake_runc")
		Expect(err).NotTo(HaveOccurred())

		containerSpec := garden.ContainerSpec{}

		config.RuntimePluginBin = binPath
		config.LogLevel = logLevel
		client = runner.Start(config)
		client.Create(containerSpec)
	})

	AfterEach(func() {
		Expect(client.DestroyAndStop()).To(Succeed())
	})

	Context("when the log-level is set to debug", func() {
		BeforeEach(func() {
			logLevel = "debug"
		})

		It("logs runc logs to stdout", func() {
			Eventually(client, "1s").Should(gbytes.Say("guardian-runc-logging-test-info"))
			Eventually(client, "1s").Should(gbytes.Say("guardian-runc-logging-test-warn"))
			Eventually(client, "1s").Should(gbytes.Say("guardian-runc-logging-test-error"))
			Eventually(client, "1s").Should(gbytes.Say("guardian-runc-logging-test-print"))
		})
	})

	Context("when the log-level is set to info", func() {
		BeforeEach(func() {
			logLevel = "info"
		})

		It("does not log runc logs to stdout", func() {
			Consistently(client, "1s").ShouldNot(gbytes.Say("guardian-runc-logging-test-info"))
			Consistently(client, "1s").ShouldNot(gbytes.Say("guardian-runc-logging-test-warn"))
			Consistently(client, "1s").ShouldNot(gbytes.Say("guardian-runc-logging-test-error"))
			Consistently(client, "1s").ShouldNot(gbytes.Say("guardian-runc-logging-test-print"))
		})
	})
})

var _ = Describe("garden server Logging", func() {
	var (
		client *runner.RunningGarden
	)

	JustBeforeEach(func() {
		client = runner.Start(config)
	})

	Context("when the log-level is passed as debug", func() {
		BeforeEach(func() {
			config.LogLevel = "debug"
		})

		AfterEach(func() {
			Expect(client.DestroyAndStop()).To(Succeed())
		})

		It("logs at debug level", func() {
			// create a container in order to execute a code path that prints debug
			// logs
			_, err := client.Create(garden.ContainerSpec{})
			Expect(err).NotTo(HaveOccurred())

			Eventually(client, "1s").Should(gbytes.Say(`"log_level":0`))
		})

		It("doesn't log spurious messages on start", func() {
			Consistently(client).ShouldNot(gbytes.Say(`guardian.iptables-runner.command.failed`))
			Consistently(client).ShouldNot(gbytes.Say(`guardian.failed-to-parse-port-pool-properties`))

			Eventually(client).Should(gbytes.Say(`guardian.no-port-pool-state-to-recover-starting-clean`))
		})
	})

	Context("when log-level is not passed", func() {
		BeforeEach(func() {
			config.LogLevel = ""
		})

		AfterEach(func() {
			Expect(client.Stop()).To(Succeed())
		})

		It("logs at info level", func() {
			Eventually(client, "1s").Should(gbytes.Say(`"log_level":1`))
		})

		It("does not log at debug level", func() {
			Consistently(client, "1s").ShouldNot(gbytes.Say(`"log_level":0`))
		})
	})

	Context("when a nonsense log-level is passed", func() {
		BeforeEach(func() {
			config.StartupExpectedToFail = true
			config.LogLevel = "nonsense-log-level"
		})

		It("exits with a code of 1", func() {
			Eventually(client, "1s").Should(gexec.Exit(1))
		})
	})
})
<|endoftext|>


<commit_before>package main

import (
	"eaciit/gdrj/model"
	"eaciit/gdrj/modules"
	"os"

	"flag"
	"github.com/eaciit/dbox"
	"github.com/eaciit/toolkit"
	"sync"
	"time"
)

var conn dbox.IConnection
var count int

var (
	t0                                         time.Time
	fiscalyear, gscount, iscount, scount, step int
	data                                       map[string]float64
	mwg                                        sync.WaitGroup
	mutex                                      = &sync.Mutex{}
)

func setinitialconnection() {
	var err error
	conn, err = modules.GetDboxIConnection("db_godrej")

	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}

	err = gdrj.SetDb(conn)
	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}
}

func main() {
	t0 = time.Now()
	data = make(map[string]float64)
	flag.IntVar(&fiscalyear, "year", 2015, "YYYY representation of godrej fiscal year. Default is 2015")
	flag.Parse()

	setinitialconnection()
	defer gdrj.CloseDb()

	toolkit.Println("Start data query...")

	filter := dbox.Eq("date.fiscal", toolkit.Sprintf("%d-%d", fiscalyear-1, fiscalyear))
	c, _ := gdrj.Find(new(gdrj.SalesPL), filter, nil)
	defer c.Close()

	scount = c.Count()
	step = scount / 100

	jobs := make(chan map[string]*gdrj.PLData, count)
	toolkit.Println("Prepare Worker")
	for wi := 0; wi < 30; wi++ {
		mwg.Add(1)
		go worker(wi, jobs)
	}

	for {
		iscount++
		spl := new(gdrj.SalesPL)
		e := c.Fetch(spl, 1, false)
		if e != nil {
			toolkit.Println("EOF")
			break
		}

		// for k, v := range spl.PLDatas {
		// 	data[k] += v.Amount
		// }

		jobs <- spl.PLDatas

		if iscount%step == 0 {
			toolkit.Printfn("Sending %d of %d in %s", iscount, scount,
				time.Since(t0).String())
		}

	}

	close(jobs)
	mwg.Wait()

	for k, v := range data {
		toolkit.Printfn("%s,%v", k, v)
	}

	toolkit.Printfn("Processing done in %s",
		time.Since(t0).String())
}

func worker(wi int, jobs <-chan map[string]*gdrj.PLData) {
	defer mwg.Done()
	var j map[string]*gdrj.PLData
	for j = range jobs {
		gscount++
		for k, v := range j {
			mutex.Lock()
			data[k] += v.Amount
			mutex.Unlock()
		}

		if gscount%step == 0 {
			toolkit.Printfn("Processing %d of %d in %s", gscount, scount,
				time.Since(t0).String())
		}
	}
}
<commit_msg>update aggr<commit_after>package main

import (
	"eaciit/gdrj/model"
	"eaciit/gdrj/modules"
	"os"

	"flag"
	"github.com/eaciit/dbox"
	"github.com/eaciit/toolkit"
	"sync"
	"time"
)

var conn dbox.IConnection
var count int

var (
	t0         time.Time
	fiscalyear int
	data       map[string]float64
	mutex      = &sync.Mutex{}
)

func setinitialconnection() {
	var err error
	conn, err = modules.GetDboxIConnection("db_godrej")

	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}

	err = gdrj.SetDb(conn)
	if err != nil {
		toolkit.Println("Initial connection found : ", err)
		os.Exit(1)
	}
}

func main() {
	t0 = time.Now()
	data = make(map[string]float64)
	flag.IntVar(&fiscalyear, "year", 2015, "YYYY representation of godrej fiscal year. Default is 2015")
	flag.Parse()

	setinitialconnection()
	defer gdrj.CloseDb()

	toolkit.Println("Start data query...")

	eperiode := time.Date(fiscalyear, 4, 1, 0, 0, 0, 0, time.UTC)
	// speriode := eperiode.AddDate(-1, 0, 0)

	// filter := dbox.And(dbox.Gte("date.date", speriode), dbox.Lt("date.date", eperiode))
	// csr, _ := conn.NewQuery().Select("date.fiscal", "pldatas").From("salespls-1").Where(filter).Cursor(nil)
	// defer csr.Close()

	result := make(chan int, 12)
	for i := 1; i <= 12; i++ {
		tstart := eperiode.AddDate(0, -i, 0)
		tend := tstart.AddDate(0, 1, 0)
		toolkit.Sprintf("From : %v, To : %v", tstart, tend)

		filter := dbox.And(dbox.Gte("date.date", tstart), dbox.Lt("date.date", tend))
		go workerproc(i, filter, result)
	}

	for i := 1; i <= 12; i++ {
		a := <-result
		toolkit.Sprintf("Worker-%d Done in %s", a, time.Since(t0).String())
	}

	for k, v := range data {
		toolkit.Printfn("%s,%v", k, v)
	}

	toolkit.Printfn("Processing done in %s",
		time.Since(t0).String())
}

func workerproc(wi int, filter *dbox.Filter, result chan<- int) {
	workerconn, _ := modules.GetDboxIConnection("db_godrej")
	defer workerconn.Close()

	csr, _ := workerconn.NewQuery().Select("date.fiscal", "pldatas").From("salespls-1").Where(filter).Cursor(nil)
	defer csr.Close()

	scount := csr.Count()
	iscount := 0
	step := scount / 100

	if step == 0 {
		step = 1
	}

	for {
		iscount++
		spl := new(gdrj.SalesPL)
		e := csr.Fetch(spl, 1, false)
		if e != nil {
			toolkit.Println("EOF")
			break
		}

		fiscal := spl.Date.Fiscal
		for k, v := range spl.PLDatas {
			key := toolkit.Sprintf("%s_%s", fiscal, k)
			mutex.Lock()
			data[key] += v.Amount
			mutex.Unlock()
		}

		if iscount%step == 0 {
			toolkit.Printfn("Go %d. Processing %d of %d (%d) in %s", wi, iscount, scount, iscount/step,
				time.Since(t0).String())
		}

		if iscount == 20 {
			break
		}

	}

	result <- wi
}
<|endoftext|>


<commit_before>package mailer

import (
	"fmt"
	"errors"

	"github.com/sendgrid/sendgrid-go/helpers/mail"
	"github.com/sendgrid/sendgrid-go"

	"github.com/vikashvverma/greeter/config"
)

type Mailer interface {
	Greet() error
}

type greetingMailer struct {
	config config.Config
}

func New(c config.Config) Mailer {
	return &greetingMailer{config:c}
}

func (gm *greetingMailer) Greet() error {
	m := mail.NewV3MailInit(gm.config.From, gm.config.Subject, gm.config.To, gm.config.Content)
	request := sendgrid.GetRequest(gm.config.APIKey, "/v3/mail/send", "https://api.sendgrid.com")
	request.Method = "POST"
	request.Body = mail.GetRequestBody(m)
	response, err := sendgrid.API(request)
	if err != nil {
		return fmt.Errorf("Mail: could not send greeting to %s(%s): err: ", gm.config.To.Name, gm.config.To.Address, err)
	}

	if response.StatusCode >= 400 && response.StatusCode <= 500 {
		return errors.New("Mail: greeting not sent")
	}

	fmt.Printf("Greet: greeting sent successfully!: %#v", response)
	return nil
}
<commit_msg>Remove mailer<commit_after><|endoftext|>


<commit_before>// +build linux

package specs

// LinuxSpec is the full specification for linux containers.
type LinuxSpec struct {
	Spec
	// Linux is platform specific configuration for linux based containers.
	Linux Linux `json:"linux"`
}

// Linux contains platform specific configuration for linux based containers.
type Linux struct {
	// UidMapping specifies user mappings for supporting user namespaces on linux.
	UidMappings []IDMapping `json:"uidMappings"`
	// UidMapping specifies group mappings for supporting user namespaces on linux.
	GidMappings []IDMapping `json:"gidMappings"`
	// Rlimits specifies rlimit options to apply to the container's process.
	Rlimits []Rlimit `json:"rlimits"`
	// SystemProperties are a set of key value pairs that are set for the container on start.
	SystemProperties map[string]string `json:"systemProperties"`
	// Resources contain cgroup information for handling resource constraints
	// for the container.
	Resources Resources `json:"resources"`
	// Namespaces contains the namespaces that are created and/or joined by the container.
	Namespaces []Namespace `json:"namespaces"`
	// Capabilities are linux capabilities that are kept for the container.
	Capabilities []string `json:"capabilities"`
	// Devices are a list of device nodes that are created and enabled for the container.
	Devices []string `json:"devices"`
}

// User specifies linux specific user and group information for the container's
// main process.
type User struct {
	// Uid is the user id.
	Uid int32 `json:"uid"`
	// Gid is the group id.
	Gid int32 `json:"gid"`
	// AdditionalGids are additional group ids set the the container's process.
	AdditionalGids []int32 `json:"additionalGids"`
}

// Namespace is the configuration for a linux namespace.
type Namespace struct {
	// Type is the type of linux namespace.
	Type string `json:"type"`
	// Path is a path to an existing namespace persisted on disk that can be joined
	// and is of the same type.
	Path string `json:"path"`
}

// IDMapping specifies uid/gid mappings.
type IDMapping struct {
	// From is the uid/gid of the host user or group.
	From int32 `json:"from"`
	// To is the uid/gid of the container's user or group.
	To int32 `json:"to"`
	// Count is how many uid/gids to map after To.
	Count int32 `json:"count"`
}

// Rlimit type and restrictions.
type Rlimit struct {
	// Type of the rlimit to set.
	Type int `json:"type"`
	// Hard is the hard limit for the specified type.
	Hard uint64 `json:"hard"`
	// Soft is the soft limit for the specified type.
	Soft uint64 `json:"soft"`
}

type HugepageLimit struct {
	Pagesize string `json:"pageSize"`
	Limit    int    `json:"limit"`
}

type InterfacePriority struct {
	// Name is the name of the network interface.
	Name string `json:"name"`
	// Priority for the interface.
	Priority int64 `json:"priority"`
}

type BlockIO struct {
	// Specifies per cgroup weight, range is from 10 to 1000.
	Weight int64 `json:"blkioWeight"`
	// Weight per cgroup per device, can override BlkioWeight.
	WeightDevice string `json:"blkioWeightDevice"`
	// IO read rate limit per cgroup per device, bytes per second.
	ThrottleReadBpsDevice string `json:"blkioThrottleReadBpsDevice"`
	// IO write rate limit per cgroup per divice, bytes per second.
	ThrottleWriteBpsDevice string `json:"blkioThrottleWriteBpsDevice"`
	// IO read rate limit per cgroup per device, IO per second.
	ThrottleReadIOpsDevice string `json:"blkioThrottleReadIopsDevice"`
	// IO write rate limit per cgroup per device, IO per second.
	ThrottleWriteIOpsDevice string `json:"blkioThrottleWriteIopsDevice"`
}

type Memory struct {
	// Memory limit (in bytes)
	Limit int64 `json:"limit"`
	// Memory reservation or soft_limit (in bytes)
	Reservation int64 `json:"reservation"`
	// Total memory usage (memory + swap); set `-1' to disable swap
	Swap int64 `json:"swap"`
	// Kernel memory limit (in bytes)
	Kernel int64 `json:"kernel"`
}

type CPU struct {
	// CPU shares (relative weight vs. other cgroups with cpu shares).
	Shares int64 `json:"shares"`
	// CPU hardcap limit (in usecs). Allowed cpu time in a given period.
	Quota int64 `json:"quota"`
	// CPU period to be used for hardcapping (in usecs). 0 to use system default.
	Period int64 `json:"period"`
	// How many time CPU will use in realtime scheduling (in usecs).
	RealtimeRuntime int64 `json:"realtimeRuntime"`
	// CPU period to be used for realtime scheduling (in usecs).
	RealtimePeriod int64 `json:"realtimePeriod"`
	// CPU to use within the cpuset.
	Cpus string `json:"cpus"`
	// MEM to use within the cpuset.
	Mems string `json:"mems"`
}

type Network struct {
	// Set class identifier for container's network packets.
	ClassID string `json:"classId"`
	// Set priority of network traffic for container.
	Priorities []InterfacePriority `json:"priorities"`
}

type Resources struct {
	// DisableOOMKiller disables the OOM killer for out of memory conditions.
	DisableOOMKiller bool `json:"disableOOMKiller"`
	// Memory restriction configuration.
	Memory Memory `json:"memory"`
	// CPU resource restriction configuration.
	CPU CPU `json:"cpu"`
	// BlockIO restriction configuration.
	BlockIO BlockIO `json:"blockIO"`
	// Hugetlb limit (in bytes)
	HugepageLimits []HugepageLimit `json:"hugepageLimits"`
	// Network restriction configuration.
	Network Network `json:"network"`
}
<commit_msg>Add memory swappiness to linux spec<commit_after>// +build linux

package specs

// LinuxSpec is the full specification for linux containers.
type LinuxSpec struct {
	Spec
	// Linux is platform specific configuration for linux based containers.
	Linux Linux `json:"linux"`
}

// Linux contains platform specific configuration for linux based containers.
type Linux struct {
	// UidMapping specifies user mappings for supporting user namespaces on linux.
	UidMappings []IDMapping `json:"uidMappings"`
	// UidMapping specifies group mappings for supporting user namespaces on linux.
	GidMappings []IDMapping `json:"gidMappings"`
	// Rlimits specifies rlimit options to apply to the container's process.
	Rlimits []Rlimit `json:"rlimits"`
	// SystemProperties are a set of key value pairs that are set for the container on start.
	SystemProperties map[string]string `json:"systemProperties"`
	// Resources contain cgroup information for handling resource constraints
	// for the container.
	Resources Resources `json:"resources"`
	// Namespaces contains the namespaces that are created and/or joined by the container.
	Namespaces []Namespace `json:"namespaces"`
	// Capabilities are linux capabilities that are kept for the container.
	Capabilities []string `json:"capabilities"`
	// Devices are a list of device nodes that are created and enabled for the container.
	Devices []string `json:"devices"`
}

// User specifies linux specific user and group information for the container's
// main process.
type User struct {
	// Uid is the user id.
	Uid int32 `json:"uid"`
	// Gid is the group id.
	Gid int32 `json:"gid"`
	// AdditionalGids are additional group ids set the the container's process.
	AdditionalGids []int32 `json:"additionalGids"`
}

// Namespace is the configuration for a linux namespace.
type Namespace struct {
	// Type is the type of linux namespace.
	Type string `json:"type"`
	// Path is a path to an existing namespace persisted on disk that can be joined
	// and is of the same type.
	Path string `json:"path"`
}

// IDMapping specifies uid/gid mappings.
type IDMapping struct {
	// From is the uid/gid of the host user or group.
	From int32 `json:"from"`
	// To is the uid/gid of the container's user or group.
	To int32 `json:"to"`
	// Count is how many uid/gids to map after To.
	Count int32 `json:"count"`
}

// Rlimit type and restrictions.
type Rlimit struct {
	// Type of the rlimit to set.
	Type int `json:"type"`
	// Hard is the hard limit for the specified type.
	Hard uint64 `json:"hard"`
	// Soft is the soft limit for the specified type.
	Soft uint64 `json:"soft"`
}

type HugepageLimit struct {
	Pagesize string `json:"pageSize"`
	Limit    int    `json:"limit"`
}

type InterfacePriority struct {
	// Name is the name of the network interface.
	Name string `json:"name"`
	// Priority for the interface.
	Priority int64 `json:"priority"`
}

type BlockIO struct {
	// Specifies per cgroup weight, range is from 10 to 1000.
	Weight int64 `json:"blkioWeight"`
	// Weight per cgroup per device, can override BlkioWeight.
	WeightDevice string `json:"blkioWeightDevice"`
	// IO read rate limit per cgroup per device, bytes per second.
	ThrottleReadBpsDevice string `json:"blkioThrottleReadBpsDevice"`
	// IO write rate limit per cgroup per divice, bytes per second.
	ThrottleWriteBpsDevice string `json:"blkioThrottleWriteBpsDevice"`
	// IO read rate limit per cgroup per device, IO per second.
	ThrottleReadIOpsDevice string `json:"blkioThrottleReadIopsDevice"`
	// IO write rate limit per cgroup per device, IO per second.
	ThrottleWriteIOpsDevice string `json:"blkioThrottleWriteIopsDevice"`
}

type Memory struct {
	// Memory limit (in bytes)
	Limit int64 `json:"limit"`
	// Memory reservation or soft_limit (in bytes)
	Reservation int64 `json:"reservation"`
	// Total memory usage (memory + swap); set `-1' to disable swap
	Swap int64 `json:"swap"`
	// Kernel memory limit (in bytes)
	Kernel int64 `json:"kernel"`
	// How aggressive the kernel will swap memory pages. Range from 0 to 100. Set -1 to use system default.
	Swappiness int64 `json:"swappiness"`
}

type CPU struct {
	// CPU shares (relative weight vs. other cgroups with cpu shares).
	Shares int64 `json:"shares"`
	// CPU hardcap limit (in usecs). Allowed cpu time in a given period.
	Quota int64 `json:"quota"`
	// CPU period to be used for hardcapping (in usecs). 0 to use system default.
	Period int64 `json:"period"`
	// How many time CPU will use in realtime scheduling (in usecs).
	RealtimeRuntime int64 `json:"realtimeRuntime"`
	// CPU period to be used for realtime scheduling (in usecs).
	RealtimePeriod int64 `json:"realtimePeriod"`
	// CPU to use within the cpuset.
	Cpus string `json:"cpus"`
	// MEM to use within the cpuset.
	Mems string `json:"mems"`
}

type Network struct {
	// Set class identifier for container's network packets.
	ClassID string `json:"classId"`
	// Set priority of network traffic for container.
	Priorities []InterfacePriority `json:"priorities"`
}

type Resources struct {
	// DisableOOMKiller disables the OOM killer for out of memory conditions.
	DisableOOMKiller bool `json:"disableOOMKiller"`
	// Memory restriction configuration.
	Memory Memory `json:"memory"`
	// CPU resource restriction configuration.
	CPU CPU `json:"cpu"`
	// BlockIO restriction configuration.
	BlockIO BlockIO `json:"blockIO"`
	// Hugetlb limit (in bytes)
	HugepageLimits []HugepageLimit `json:"hugepageLimits"`
	// Network restriction configuration.
	Network Network `json:"network"`
}
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems                */
/*                                                                            */
/* 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 goca

import (
	"testing"
	"time"

	hk "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/hook"
	"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/hook/keys"
)

var call = "one.zone.info"

// Helper to create a Hook Network
func createHook(t *testing.T) (*hk.Hook, int) {

	tpl := hk.NewTemplate()
	tpl.Add(keys.Name, "hook-goca")
	tpl.Add(keys.Type, "api")
	tpl.Add(keys.Command, "/usr/bin/ls -l")
	tpl.AddPair("CALL", call)

	id, err := testCtrl.Hooks().Create(tpl.String())
	if err != nil {
		t.Fatal(err)
	}

	// Get Hook Network by ID
	hook, err := testCtrl.Hook(id).Info(false)
	if err != nil {
		t.Error(err)
	}

	return hook, id
}

func TestHook(t *testing.T) {
	var err error

	hook, idOrig := createHook(t)

	idParse := hook.ID
	if idParse != idOrig {
		t.Errorf("Hook ID does not match")
	}

	// Get hook by Name
	name := hook.Name

	id, err := testCtrl.Hooks().ByName(name)
	if err != nil {
		t.Fatal(err)
	}

	hookC := testCtrl.Hook(id)
	hook, err = hookC.Info(false)
	if err != nil {
		t.Error(err)
	}

	idParse = hook.ID
	if idParse != idOrig {
		t.Errorf("Hook ID does not match")
	}

	// Check execution records
	currentExecs := len(hook.Log.ExecutionRecords)

	//triger the hook
	testCtrl.Zone(0).Info(false)

	time.Sleep(2 * time.Second)

	hook, err = hookC.Info(false)

	if len(hook.Log.ExecutionRecords) <= currentExecs {
		t.Errorf("Hook have not been triggered")
	}

	// Check retry functionality
	currentExecs = len(hook.Log.ExecutionRecords)

	hookC.Retry(hook.Log.ExecutionRecords[0].ExecId)

	time.Sleep(2 * time.Second)

	hook, err = hookC.Info(false)

	if len(hook.Log.ExecutionRecords) <= currentExecs {
		t.Errorf("Hook execution have not been retried")
	}

	if hook.Log.ExecutionRecords[len(hook.Log.ExecutionRecords)-1].Retry != "yes" {
		t.Errorf("Hook execution have not been retried")
	}

	// Delete template
	err = hookC.Delete()
	if err != nil {
		t.Error(err)
	}
}
<commit_msg>M #: Fix GOCA hook tests (#4186)<commit_after>/* -------------------------------------------------------------------------- */
/* Copyright 2002-2019, OpenNebula Project, OpenNebula Systems                */
/*                                                                            */
/* 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 goca

import (
	"testing"
	"time"

	hk "github.com/OpenNebula/one/src/oca/go/src/goca/schemas/hook"
	"github.com/OpenNebula/one/src/oca/go/src/goca/schemas/hook/keys"
)

var call = "one.zone.raftstatus"

// Helper to create a Hook Network
func createHook(t *testing.T) (*hk.Hook, int) {

	tpl := hk.NewTemplate()
	tpl.Add(keys.Name, "hook-goca")
	tpl.Add(keys.Type, "api")
	tpl.Add(keys.Command, "/usr/bin/ls -l")
	tpl.AddPair("CALL", call)

	id, err := testCtrl.Hooks().Create(tpl.String())
	if err != nil {
		t.Fatal(err)
	}

	// Get Hook Network by ID
	hook, err := testCtrl.Hook(id).Info(false)
	if err != nil {
		t.Error(err)
	}

	return hook, id
}

func TestHook(t *testing.T) {
	var err error

	hook, idOrig := createHook(t)

	idParse := hook.ID
	if idParse != idOrig {
		t.Errorf("Hook ID does not match")
	}

	// Get hook by Name
	name := hook.Name

	id, err := testCtrl.Hooks().ByName(name)
	if err != nil {
		t.Fatal(err)
	}

	hookC := testCtrl.Hook(id)
	hook, err = hookC.Info(false)
	if err != nil {
		t.Error(err)
	}

	idParse = hook.ID
	if idParse != idOrig {
		t.Errorf("Hook ID does not match")
	}

	// Check execution records
	currentExecs := len(hook.Log.ExecutionRecords)

	//triger the hook
	testCtrl.Zones().ServerRaftStatus()

	time.Sleep(2 * time.Second)

	hook, err = hookC.Info(false)

	if len(hook.Log.ExecutionRecords) <= currentExecs {
		t.Errorf("Hook have not been triggered")
	}

	// Check retry functionality
	currentExecs = len(hook.Log.ExecutionRecords)

	hookC.Retry(hook.Log.ExecutionRecords[0].ExecId)

	time.Sleep(2 * time.Second)

	hook, err = hookC.Info(false)

	if len(hook.Log.ExecutionRecords) <= currentExecs {
		t.Errorf("Hook execution have not been retried")
	}

	if hook.Log.ExecutionRecords[len(hook.Log.ExecutionRecords)-1].Retry != "yes" {
		t.Errorf("Hook execution have not been retried")
	}

	// Delete template
	err = hookC.Delete()
	if err != nil {
		t.Error(err)
	}
}
<|endoftext|>


<commit_before>package gochimp3

import (
	"errors"
	"fmt"
)

const (
	members_path       = "/lists/%s/members"
	single_member_path = members_path + "/%s"

	member_activity_path = single_member_path + "/activity"
	member_goals_path    = single_member_path + "/goals"

	member_notes_path       = single_member_path + "/notes"
	single_member_note_path = member_notes_path + "/%s"

	member_tags_path       = single_member_path + "/tags"
	single_member_tag_path = member_notes_path + "/%s"
)

type ListOfMembers struct {
	baseList

	ListID  string   `json:"list_id"`
	Members []Member `json:"members"`
}

type MemberResponse struct {
	EmailAddress    string                 `json:"email_address"`
	EmailType       string                 `json:"email_type,omitempty"`
	Status          string                 `json:"status"`
	StatusIfNew     string                 `json:"status_if_new,omitempty"`
	MergeFields     map[string]interface{} `json:"merge_fields,omitempty"`
	Interests       map[string]bool        `json:"interests,omitempty"`
	Language        string                 `json:"language"`
	VIP             bool                   `json:"vip"`
	Location        *MemberLocation        `json:"location,omitempty"`
	IPOpt           string                 `json:"ip_opt,omitempty"`
	IPSignup        string                 `json:"ip_signup,omitempty"`
	Tags            []MemberTag            `json:"tags,omitempty"`
	TimestampSignup string                 `json:"timestamp_signup,omitempty"`
	TimestampOpt    string                 `json:"timestamp_opt,omitempty"`
}

type MemberRequest struct {
	EmailAddress         string                 `json:"email_address"`
	EmailType            string                 `json:"email_type,omitempty"`
	Status               string                 `json:"status"`
	StatusIfNew          string                 `json:"status_if_new,omitempty"`
	MergeFields          map[string]interface{} `json:"merge_fields,omitempty"`
	Interests            map[string]bool        `json:"interests,omitempty"`
	Language             string                 `json:"language"`
	VIP                  bool                   `json:"vip"`
	Location             *MemberLocation        `json:"location,omitempty"`
	MarketingPermissions *MarketingPermissions  `json:"marketing_permissions,omitempty"`
	IPOpt                string                 `json:"ip_opt,omitempty"`
	IPSignup             string                 `json:"ip_signup,omitempty"`
	Tags                 []string               `json:"tags,omitempty"`
	TimestampSignup      string                 `json:"timestamp_signup,omitempty"`
	TimestampOpt         string                 `json:"timestamp_opt,omitempty"`
}

type Member struct {
	MemberResponse

	ID            string          `json:"id"`
	ListID        string          `json:"list_id"`
	UniqueEmailID string          `json:"unique_email_id"`
	EmailType     string          `json:"email_type"`
	Stats         MemberStats     `json:"stats"`
	MemberRating  int             `json:"member_rating"`
	LastChanged   string          `json:"last_changed"`
	EmailClient   string          `json:"email_client"`
	LastNote      MemberNoteShort `json:"last_note"`

	api *API
}

func (mem Member) CanMakeRequest() error {
	if mem.ListID == "" {
		return errors.New("No ListID provided")
	}

	if mem.ID == "" {
		return errors.New("No ID provided")
	}

	return nil
}

type MemberStats struct {
	AvgOpenRate  float64 `json:"avg_open_rate"`
	AvgClickRate float64 `json:"avg_click_rate"`
}

type MemberLocation struct {
	Latitude    float64 `json:"latitude"`
	Longitude   float64 `json:"longitude"`
	GMTOffset   int     `json:"gmtoff"`
	DSTOffset   int     `json:"dstoff"`
	CountryCode string  `json:"country_code"`
	Timezone    string  `json:"timezone"`
}

type MarketingPermissions []MarketingPermission

type MarketingPermission struct {
	MarketingPermissionID string `json:"marketing_permission_id"`
	Text                  string `json:"text"`
	Enabled               bool   `json:"enabled"`
}

type MemberNoteShort struct {
	ID        int    `json:"note_id"`
	CreatedAt string `json:"created_at"`
	CreatedBy string `json:"created_by"`
	Note      string `json:"note"`
}

type MemberTag struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

func (list ListResponse) GetMembers(params *InterestCategoriesQueryParams) (*ListOfMembers, error) {
	if err := list.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(members_path, list.ID)
	response := new(ListOfMembers)

	err := list.api.Request("GET", endpoint, params, nil, response)
	if err != nil {
		return nil, err
	}

	for _, m := range response.Members {
		m.api = list.api
	}

	return response, nil
}

func (list ListResponse) GetMember(id string, params *BasicQueryParams) (*Member, error) {
	if err := list.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(single_member_path, list.ID, id)
	response := new(Member)
	response.api = list.api

	return response, list.api.Request("GET", endpoint, params, nil, response)
}

func (list ListResponse) CreateMember(body *MemberRequest) (*Member, error) {
	if err := list.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(members_path, list.ID)
	response := new(Member)
	response.api = list.api

	return response, list.api.Request("POST", endpoint, nil, body, response)
}

func (list ListResponse) UpdateMember(id string, body *MemberRequest) (*Member, error) {
	if err := list.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(single_member_path, list.ID, id)
	response := new(Member)
	response.api = list.api

	return response, list.api.Request("PATCH", endpoint, nil, body, response)
}

func (list ListResponse) AddOrUpdateMember(id string, body *MemberRequest) (*Member, error) {
	if err := list.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(single_member_path, list.ID, id)
	response := new(Member)
	response.api = list.api

	return response, list.api.Request("PUT", endpoint, nil, body, response)
}

func (list ListResponse) DeleteMember(id string) (bool, error) {
	if err := list.CanMakeRequest(); err != nil {
		return false, err
	}

	endpoint := fmt.Sprintf(single_member_path, list.ID, id)
	return list.api.RequestOk("DELETE", endpoint)
}

// ------------------------------------------------------------------------------------------------
// Activity
// ------------------------------------------------------------------------------------------------

type ListOfMemberActivity struct {
	baseList

	EmailID  string     `json:"email_id"`
	ListID   string     `json:"list_id"`
	Activity []Activity `json:"activity"`
}

type MemberActivity struct {
	Action         string `json:"action"`
	Timestamp      string `json:"timestamp"`
	URL            string `json:"url"`
	Type           string `json:"type"`
	CampaignID     string `json:"campaign_id"`
	Title          string `json:"title"`
	ParentCampaign string `json:"parent_campaign"`
}

func (mem Member) GetActivity(params *BasicQueryParams) (*ListOfMemberActivity, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(member_activity_path, mem.ListID, mem.ID)
	response := new(ListOfMemberActivity)

	return response, mem.api.Request("GET", endpoint, params, nil, response)
}

// ------------------------------------------------------------------------------------------------
// Goals
// ------------------------------------------------------------------------------------------------

type ListOfMemberGoals struct {
	baseList

	EmailID string       `json:"email_id"`
	ListID  string       `json:"list_id"`
	Goals   []MemberGoal `json:"goals"`
}

type MemberGoal struct {
	ID            int    `json:"goal_id"`
	Event         string `json:"event"`
	LastVisitedAt string `json:"last_visited_at"`
	Data          string `json:"data"`
}

func (mem Member) GetGoals(params *BasicQueryParams) (*ListOfMemberGoals, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(member_goals_path, mem.ListID, mem.ID)
	response := new(ListOfMemberGoals)

	return response, mem.api.Request("GET", endpoint, params, nil, response)
}

// ------------------------------------------------------------------------------------------------
// NOTES
// ------------------------------------------------------------------------------------------------

type ListOfMemberNotes struct {
	baseList

	EmailID string           `json:"email_id"`
	ListID  string           `json:"list_id"`
	Notes   []MemberNoteLong `json:"notes"`
}

type MemberNoteLong struct {
	ID        int    `json:"id"`
	CreatedAt string `json:"created_at"`
	CreatedBy string `json:"created_by"`
	UpdatedAt string `json:"updated_at"`
	Note      string `json:"note"`
	ListID    string `json:"list_id"`
	EmailID   string `json:"email_id"`

	withLinks
}

func (mem Member) GetNotes(params *ExtendedQueryParams) (*ListOfMemberNotes, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(member_notes_path, mem.ListID, mem.ID)
	response := new(ListOfMemberNotes)

	return response, mem.api.Request("GET", endpoint, params, nil, response)
}

func (mem Member) CreateNote(msg string) (*MemberNoteLong, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(member_notes_path, mem.ListID, mem.ID)
	response := new(MemberNoteLong)

	body := struct{ Note string }{
		Note: msg,
	}

	return response, mem.api.Request("POST", endpoint, nil, &body, response)
}

func (mem Member) UpdateNote(id, msg string) (*MemberNoteLong, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(single_member_note_path, mem.ListID, mem.ID, id)
	response := new(MemberNoteLong)

	body := struct{ Note string }{
		Note: msg,
	}

	return response, mem.api.Request("PATCH", endpoint, nil, &body, response)
}

func (mem Member) GetNote(id string, params *BasicQueryParams) (*MemberNoteLong, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(single_member_note_path, mem.ListID, mem.ID, id)
	response := new(MemberNoteLong)

	return response, mem.api.Request("GET", endpoint, params, nil, response)
}

func (mem Member) DeleteNote(id string) (bool, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return false, err
	}

	endpoint := fmt.Sprintf(single_member_note_path, mem.ListID, mem.ID, id)
	return mem.api.RequestOk("DELETE", endpoint)
}

// ------------------------------------------------------------------------------------------------
// TAGS
// ------------------------------------------------------------------------------------------------

type ListOfMemberTags struct {
	baseList

	Tags []MemberTagLong `json:"tags"`
}

type MemberTagLong struct {
	ID        int     `json:"id"`
	Name      string  `json:"name"`
	DataAdded *string `json:"date_added,omitempty"`
	Status    string  `json:"status,omitempty"`

	withLinks
}

func (mem Member) GetTags(params *ExtendedQueryParams) (*ListOfMemberTags, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(member_tags_path, mem.ListID, mem.ID)
	response := new(ListOfMemberTags)

	return response, mem.api.Request("GET", endpoint, params, nil, response)
}

func (mem Member) UpdateTags(tags []MemberTagLong) (*ListOfMemberTags, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(member_tags_path, mem.ListID, mem.ID)
	response := new(ListOfMemberTags)

	body := struct{ tags []MemberTagLong }{
		tags: tags,
	}

	return response, mem.api.Request("POST", endpoint, nil, &body, response)
}
<commit_msg>Introduce Tags<commit_after>package gochimp3

import (
	"errors"
	"fmt"
)

const (
	members_path       = "/lists/%s/members"
	single_member_path = members_path + "/%s"

	member_activity_path = single_member_path + "/activity"
	member_goals_path    = single_member_path + "/goals"

	member_notes_path       = single_member_path + "/notes"
	single_member_note_path = member_notes_path + "/%s"

	member_tags_path       = single_member_path + "/tags"
	single_member_tag_path = member_tags_path + "/%s"
)

type ListOfMembers struct {
	baseList

	ListID  string   `json:"list_id"`
	Members []Member `json:"members"`
}

type MemberResponse struct {
	EmailAddress    string                 `json:"email_address"`
	EmailType       string                 `json:"email_type,omitempty"`
	Status          string                 `json:"status"`
	StatusIfNew     string                 `json:"status_if_new,omitempty"`
	MergeFields     map[string]interface{} `json:"merge_fields,omitempty"`
	Interests       map[string]bool        `json:"interests,omitempty"`
	Language        string                 `json:"language"`
	VIP             bool                   `json:"vip"`
	Location        *MemberLocation        `json:"location,omitempty"`
	IPOpt           string                 `json:"ip_opt,omitempty"`
	IPSignup        string                 `json:"ip_signup,omitempty"`
	Tags            []MemberTag            `json:"tags,omitempty"`
	TimestampSignup string                 `json:"timestamp_signup,omitempty"`
	TimestampOpt    string                 `json:"timestamp_opt,omitempty"`
}

type MemberRequest struct {
	EmailAddress         string                 `json:"email_address"`
	EmailType            string                 `json:"email_type,omitempty"`
	Status               string                 `json:"status"`
	StatusIfNew          string                 `json:"status_if_new,omitempty"`
	MergeFields          map[string]interface{} `json:"merge_fields,omitempty"`
	Interests            map[string]bool        `json:"interests,omitempty"`
	Language             string                 `json:"language"`
	VIP                  bool                   `json:"vip"`
	Location             *MemberLocation        `json:"location,omitempty"`
	MarketingPermissions *MarketingPermissions  `json:"marketing_permissions,omitempty"`
	IPOpt                string                 `json:"ip_opt,omitempty"`
	IPSignup             string                 `json:"ip_signup,omitempty"`
	Tags                 []string               `json:"tags,omitempty"`
	TimestampSignup      string                 `json:"timestamp_signup,omitempty"`
	TimestampOpt         string                 `json:"timestamp_opt,omitempty"`
}

type Member struct {
	MemberResponse

	ID            string          `json:"id"`
	ListID        string          `json:"list_id"`
	UniqueEmailID string          `json:"unique_email_id"`
	EmailType     string          `json:"email_type"`
	Stats         MemberStats     `json:"stats"`
	MemberRating  int             `json:"member_rating"`
	LastChanged   string          `json:"last_changed"`
	EmailClient   string          `json:"email_client"`
	LastNote      MemberNoteShort `json:"last_note"`

	api *API
}

func (mem Member) CanMakeRequest() error {
	if mem.ListID == "" {
		return errors.New("No ListID provided")
	}

	if mem.ID == "" {
		return errors.New("No ID provided")
	}

	return nil
}

type MemberStats struct {
	AvgOpenRate  float64 `json:"avg_open_rate"`
	AvgClickRate float64 `json:"avg_click_rate"`
}

type MemberLocation struct {
	Latitude    float64 `json:"latitude"`
	Longitude   float64 `json:"longitude"`
	GMTOffset   int     `json:"gmtoff"`
	DSTOffset   int     `json:"dstoff"`
	CountryCode string  `json:"country_code"`
	Timezone    string  `json:"timezone"`
}

type MarketingPermissions []MarketingPermission

type MarketingPermission struct {
	MarketingPermissionID string `json:"marketing_permission_id"`
	Text                  string `json:"text"`
	Enabled               bool   `json:"enabled"`
}

type MemberNoteShort struct {
	ID        int    `json:"note_id"`
	CreatedAt string `json:"created_at"`
	CreatedBy string `json:"created_by"`
	Note      string `json:"note"`
}

type MemberTag struct {
	ID   int    `json:"id"`
	Name string `json:"name"`
}

func (list ListResponse) GetMembers(params *InterestCategoriesQueryParams) (*ListOfMembers, error) {
	if err := list.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(members_path, list.ID)
	response := new(ListOfMembers)

	err := list.api.Request("GET", endpoint, params, nil, response)
	if err != nil {
		return nil, err
	}

	for _, m := range response.Members {
		m.api = list.api
	}

	return response, nil
}

func (list ListResponse) GetMember(id string, params *BasicQueryParams) (*Member, error) {
	if err := list.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(single_member_path, list.ID, id)
	response := new(Member)
	response.api = list.api

	return response, list.api.Request("GET", endpoint, params, nil, response)
}

func (list ListResponse) CreateMember(body *MemberRequest) (*Member, error) {
	if err := list.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(members_path, list.ID)
	response := new(Member)
	response.api = list.api

	return response, list.api.Request("POST", endpoint, nil, body, response)
}

func (list ListResponse) UpdateMember(id string, body *MemberRequest) (*Member, error) {
	if err := list.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(single_member_path, list.ID, id)
	response := new(Member)
	response.api = list.api

	return response, list.api.Request("PATCH", endpoint, nil, body, response)
}

func (list ListResponse) AddOrUpdateMember(id string, body *MemberRequest) (*Member, error) {
	if err := list.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(single_member_path, list.ID, id)
	response := new(Member)
	response.api = list.api

	return response, list.api.Request("PUT", endpoint, nil, body, response)
}

func (list ListResponse) DeleteMember(id string) (bool, error) {
	if err := list.CanMakeRequest(); err != nil {
		return false, err
	}

	endpoint := fmt.Sprintf(single_member_path, list.ID, id)
	return list.api.RequestOk("DELETE", endpoint)
}

// ------------------------------------------------------------------------------------------------
// Activity
// ------------------------------------------------------------------------------------------------

type ListOfMemberActivity struct {
	baseList

	EmailID  string     `json:"email_id"`
	ListID   string     `json:"list_id"`
	Activity []Activity `json:"activity"`
}

type MemberActivity struct {
	Action         string `json:"action"`
	Timestamp      string `json:"timestamp"`
	URL            string `json:"url"`
	Type           string `json:"type"`
	CampaignID     string `json:"campaign_id"`
	Title          string `json:"title"`
	ParentCampaign string `json:"parent_campaign"`
}

func (mem Member) GetActivity(params *BasicQueryParams) (*ListOfMemberActivity, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(member_activity_path, mem.ListID, mem.ID)
	response := new(ListOfMemberActivity)

	return response, mem.api.Request("GET", endpoint, params, nil, response)
}

// ------------------------------------------------------------------------------------------------
// Goals
// ------------------------------------------------------------------------------------------------

type ListOfMemberGoals struct {
	baseList

	EmailID string       `json:"email_id"`
	ListID  string       `json:"list_id"`
	Goals   []MemberGoal `json:"goals"`
}

type MemberGoal struct {
	ID            int    `json:"goal_id"`
	Event         string `json:"event"`
	LastVisitedAt string `json:"last_visited_at"`
	Data          string `json:"data"`
}

func (mem Member) GetGoals(params *BasicQueryParams) (*ListOfMemberGoals, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(member_goals_path, mem.ListID, mem.ID)
	response := new(ListOfMemberGoals)

	return response, mem.api.Request("GET", endpoint, params, nil, response)
}

// ------------------------------------------------------------------------------------------------
// NOTES
// ------------------------------------------------------------------------------------------------

type ListOfMemberNotes struct {
	baseList

	EmailID string           `json:"email_id"`
	ListID  string           `json:"list_id"`
	Notes   []MemberNoteLong `json:"notes"`
}

type MemberNoteLong struct {
	ID        int    `json:"id"`
	CreatedAt string `json:"created_at"`
	CreatedBy string `json:"created_by"`
	UpdatedAt string `json:"updated_at"`
	Note      string `json:"note"`
	ListID    string `json:"list_id"`
	EmailID   string `json:"email_id"`

	withLinks
}

func (mem Member) GetNotes(params *ExtendedQueryParams) (*ListOfMemberNotes, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(member_notes_path, mem.ListID, mem.ID)
	response := new(ListOfMemberNotes)

	return response, mem.api.Request("GET", endpoint, params, nil, response)
}

func (mem Member) CreateNote(msg string) (*MemberNoteLong, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(member_notes_path, mem.ListID, mem.ID)
	response := new(MemberNoteLong)

	body := struct{ Note string }{
		Note: msg,
	}

	return response, mem.api.Request("POST", endpoint, nil, &body, response)
}

func (mem Member) UpdateNote(id, msg string) (*MemberNoteLong, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(single_member_note_path, mem.ListID, mem.ID, id)
	response := new(MemberNoteLong)

	body := struct{ Note string }{
		Note: msg,
	}

	return response, mem.api.Request("PATCH", endpoint, nil, &body, response)
}

func (mem Member) GetNote(id string, params *BasicQueryParams) (*MemberNoteLong, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(single_member_note_path, mem.ListID, mem.ID, id)
	response := new(MemberNoteLong)

	return response, mem.api.Request("GET", endpoint, params, nil, response)
}

func (mem Member) DeleteNote(id string) (bool, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return false, err
	}

	endpoint := fmt.Sprintf(single_member_note_path, mem.ListID, mem.ID, id)
	return mem.api.RequestOk("DELETE", endpoint)
}

// ------------------------------------------------------------------------------------------------
// TAGS
// ------------------------------------------------------------------------------------------------

type ListOfMemberTags struct {
	baseList

	Tags []MemberTagLong `json:"tags"`
}

type MemberTagShort struct {
	ID     int    `json:"id"`
	Name   string `json:"name"`
	Status string `json:"status,omitempty"`

	withLinks
}

type MemberTagLong struct {
	DataAdded *string `json:"date_added,omitempty"`
	MemberTagShort
}

func (mem Member) GetTags(params *ExtendedQueryParams) (*ListOfMemberTags, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(member_tags_path, mem.ListID, mem.ID)
	response := new(ListOfMemberTags)

	return response, mem.api.Request("GET", endpoint, params, nil, response)
}

func (mem Member) UpdateTags(tags []MemberTagShort) (*ListOfMemberTags, error) {
	if err := mem.CanMakeRequest(); err != nil {
		return nil, err
	}

	endpoint := fmt.Sprintf(member_tags_path, mem.ListID, mem.ID)
	response := new(ListOfMemberTags)

	body := struct{ tags []MemberTagShort }{
		tags: tags,
	}

	return response, mem.api.Request("POST", endpoint, nil, &body, response)
}
<|endoftext|>


<commit_before>package golbStore

import (
	"time"

	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

// LatestEntries loads all Blogentries in the results slice
// (sorted descending by date)
func (b MgoBlog) LatestEntries() (entries []*Entry, err error) {
	coll, s := b.getCollection()
	defer s.Close()

	err = coll.Find(nil).Sort("-_written").All(&entries)
	if err != nil {
		return nil, err
	}

	return
}

func (b MgoBlog) FindById(id string) (e *Entry, err error) {
	if !bson.IsObjectIdHex(id) {
		return nil, ErrBadObjectId
	}

	coll, s := b.getCollection()
	defer s.Close()

	qry := bson.M{"_id": bson.ObjectIdHex(id)}
	err = coll.Find(qry).One(&e)
	switch {
	case err == nil:
		return

	case err == mgo.ErrNotFound:
		return nil, ErrEntryNotFound

	default:
		return nil, err
	}
}

func (b MgoBlog) Delete(id string) error {
	// validate the post id
	if !bson.IsObjectIdHex(id) {
		return ErrBadObjectId
	}
	entryId := bson.ObjectIdHex(id)

	coll, s := b.getCollection()
	defer s.Close()

	// Delete entry
	return coll.Remove(bson.M{"_id": entryId})
}

func (b MgoBlog) Save(e *Entry) error {
	// if we have a valid ObjId we assume it's an update
	if bson.IsObjectIdHex(e.Id) {
		e.ObjId = bson.ObjectIdHex(e.Id)
	} else {
		// no valid ObjId, so we assume it's a new post
		// and generate a new one
		e.ObjId = bson.NewObjectId()
		// set creation datetime
		e.Written = time.Now()
	}
	coll, s := b.getCollection()
	defer s.Close()

	// building the update bson manually is necessery because mgo/bson irgnores
	// the "ommitempty" tag and we don't want to update timestamp and username.
	// this requires MongoDB 2.4!
	_, err := coll.UpsertId(e.ObjId, bson.M{
		"$setOnInsert": bson.M{
			"_id":     e.ObjId,
			"author":  e.Author,
			"written": e.Written,
		},
		"$set": bson.M{
			"text":  e.Text,
			"title": e.Title,
		},
	})
	return err
}
<commit_msg>Hide text from List by default<commit_after>package golbStore

import (
	"time"

	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

// LatestEntries loads all Blogentries in the results slice
// (sorted descending by date)
func (b MgoBlog) LatestEntries(withText bool) (entries []*Entry, err error) {
	coll, s := b.getCollection()
	defer s.Close()

	proj := bson.M{"text": 0}
	if withText {
		proj["text"] = 1
	}

	err = coll.Find(nil).Select(proj).Sort("-_written").All(&entries)
	if err != nil {
		return nil, err
	}

	return
}

func (b MgoBlog) FindById(id string) (e *Entry, err error) {
	if !bson.IsObjectIdHex(id) {
		return nil, ErrBadObjectId
	}

	coll, s := b.getCollection()
	defer s.Close()

	qry := bson.M{"_id": bson.ObjectIdHex(id)}
	err = coll.Find(qry).One(&e)
	switch {
	case err == nil:
		return

	case err == mgo.ErrNotFound:
		return nil, ErrEntryNotFound

	default:
		return nil, err
	}
}

func (b MgoBlog) Delete(id string) error {
	// validate the post id
	if !bson.IsObjectIdHex(id) {
		return ErrBadObjectId
	}
	entryId := bson.ObjectIdHex(id)

	coll, s := b.getCollection()
	defer s.Close()

	// Delete entry
	return coll.Remove(bson.M{"_id": entryId})
}

func (b MgoBlog) Save(e *Entry) error {
	// if we have a valid ObjId we assume it's an update
	if bson.IsObjectIdHex(e.Id) {
		e.ObjId = bson.ObjectIdHex(e.Id)
	} else {
		// no valid ObjId, so we assume it's a new post
		// and generate a new one
		e.ObjId = bson.NewObjectId()
		// set creation datetime
		e.Written = time.Now()
	}
	coll, s := b.getCollection()
	defer s.Close()

	// building the update bson manually is necessery because mgo/bson irgnores
	// the "ommitempty" tag and we don't want to update timestamp and username.
	// this requires MongoDB 2.4!
	_, err := coll.UpsertId(e.ObjId, bson.M{
		"$setOnInsert": bson.M{
			"_id":     e.ObjId,
			"author":  e.Author,
			"written": e.Written,
		},
		"$set": bson.M{
			"text":  e.Text,
			"title": e.Title,
		},
	})
	return err
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"time"

	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/mem"
)

//Metrics represents a basic struct with systems stats
type Metrics struct {
	CpuStats []cpu.TimesStat        `json:"cpustats"`
	MemStats *mem.VirtualMemoryStat `json:"memstats"`
}

func getRAMInfo() (*mem.VirtualMemoryStat, error) {
	memstats, err := mem.VirtualMemory()
	if err != nil {
		return nil, fmt.Errorf("Error getting memory information: %v", err)
	}
	return memstats, nil
}

func getCPUInfo() ([]cpu.TimesStat, error) {
	cpustats, err := cpu.Times(true)
	if err != nil {
		return nil, fmt.Errorf("Error getting cpu information: %v", err)
	}
	return cpustats, nil
}

func (agent *Agent) basicMetrics() {
	for {
		c, err := getCPUInfo()
		if err != nil {
			log.Println(err)
		}
		m, err := getRAMInfo()
		if err != nil {
			log.Println(err)
		}
		metrics.CpuStats = c
		metrics.MemStats = m
		time.Sleep(3 * time.Second)
	}
}
<commit_msg>Return SWAP info<commit_after>package main

import (
	"fmt"
	"log"
	"time"

	"github.com/shirou/gopsutil/cpu"
	"github.com/shirou/gopsutil/mem"
)

//Metrics represents a basic struct with systems stats
type Metrics struct {
	CPUStats  []cpu.TimesStat        `json:"cpustats"`
	MemStats  *mem.VirtualMemoryStat `json:"memstats"`
	SwapStats *mem.SwapMemoryStat    `json:"swapstats"`
}

func getSWAPInfo() (*mem.SwapMemoryStat, error) {
	swapstats, err := mem.SwapMemory()
	if err != nil {
		return nil, fmt.Errorf("Error getting swap information: %v", err)
	}
	return swapstats, nil
}

func getRAMInfo() (*mem.VirtualMemoryStat, error) {
	memstats, err := mem.VirtualMemory()
	if err != nil {
		return nil, fmt.Errorf("Error getting memory information: %v", err)
	}
	return memstats, nil
}

func getCPUInfo() ([]cpu.TimesStat, error) {
	cpustats, err := cpu.Times(true)
	if err != nil {
		return nil, fmt.Errorf("Error getting cpu information: %v", err)
	}
	return cpustats, nil
}

func (agent *Agent) basicMetrics() {
	for {
		c, err := getCPUInfo()
		if err != nil {
			log.Println(err)
		}
		m, err := getRAMInfo()
		if err != nil {
			log.Println(err)
		}
		s, err := getSWAPInfo()
		if err != nil {
			log.Println(err)
		}
		metrics.CPUStats = c
		metrics.MemStats = m
		metrics.SwapStats = s
		time.Sleep(3 * time.Second)
	}
}
<|endoftext|>