<commit_before>package SpedRead

import (
	"path/filepath"
	"os"
	"bufio"
	"strings"
	"github.com/jinzhu/gorm"
	"github.com/chapzin/parse-efd-fiscal/SpedExec"
	"github.com/chapzin/parse-efd-fiscal/SpedError"
	"time"
	"github.com/chapzin/parse-efd-fiscal/SpedConvert"
	"github.com/chapzin/parse-efd-fiscal/model"
	"io/ioutil"
	"github.com/clbanning/mxj"
)

var id int
var maxid = 100
// Ler todos os arquivos de uma determinada pasta
func RecursiveSpeds(path string) {
	filepath.Walk(path, func(file string, f os.FileInfo, err error) error {
		if f.IsDir() == false {
			ext := filepath.Ext(file)
			if ext == ".txt" {
				SpedError.CheckErr(err)
				// Possivelmente uma goroutines começando aqui
				r := SpedExec.Regs{}
				id++
				go InsertSped(file, &r)
				// Goroutines finalizando aqui
			}

			if ext == ".xml" {
				id++
				go InsertXml(file)
			}
			wait()
		}
		return nil
	})
}

func wait() {
	for {
		if id >= maxid {
			time.Sleep(1 * time.Second)
		} else {
			return
		}
	}

}

func InsertXml(xml string) {
	db, err := gorm.Open("mysql", "root@/auditoria2?charset=utf8")
	// Teste de lista produtos
	xmlFile, err := ioutil.ReadFile(xml)
	reader := SpedConvert.ConvXml(xml)
	SpedError.CheckErr(err)
	nfe, errOpenXml := mxj.NewMapXml(xmlFile)
	SpedError.CheckErr(errOpenXml)
	// Preenchendo o header da nfe
	nNf := reader("ide", "nNF")
	chnfe := reader("infProt", "chNFe")
	natOp := reader("ide", "natOp")
	indPag := reader("ide", "indPag")
	mod := reader("ide", "mod")
	serie := reader("ide", "serie")
	dEmit := reader("ide", "dEmi")
	if dEmit == "" {
		dhEmit := reader("ide", "dhEmi")
		dEmit = dhEmit
	}
	tpNf := reader("ide", "tpNF")
	tpImp := reader("ide", "tpImp")
	tpEmis := reader("ide", "tpEmis")
	cdv := reader("ide", "cDV")
	tpAmb := reader("ide", "tpAmb")
	finNFe := reader("ide", "finNFe")
	procEmi := reader("ide", "procEmi")

	// Preenchendo itens
	codigo, err := nfe.ValuesForKey("cProd")
	ean, err := nfe.ValuesForKey("cEAN")
	descricao, err := nfe.ValuesForKey("xProd")
	ncm, err := nfe.ValuesForKey("NCM")
	cfop, err := nfe.ValuesForKey("CFOP")
	unid, err := nfe.ValuesForKey("uCom")
	qtd, err := nfe.ValuesForKey("qCom")
	vUnit, err := nfe.ValuesForKey("vUnCom")
	vTotal, err := nfe.ValuesForKey("vProd")
	// Preenchendo Destinatario
	cnpj := reader("dest", "CNPJ")
	xNome := reader("dest", "xNome")
	xLgr := reader("enderDest", "xLgr")
	nro := reader("enderDest", "nro")
	xCpl := reader("enderDest", "xCpl")
	xBairro := reader("enderDest", "xBairro")
	cMun := reader("enderDest", "cMun")
	xMun := reader("enderDest", "xMun")
	uf := reader("enderDest", "UF")
	cep := reader("enderDest", "CEP")
	cPais := reader("enderDest", "cPais")
	xPais := reader("enderDest", "xPais")
	fone := reader("enderDest", "fone")
	ie := reader("dest", "IE")
	// Preenchendo Emitente
	cnpje := reader("emit", "CNPJ")
	xNomee := reader("emit", "xNome")
	xLgre := reader("enderEmit", "xLgr")
	nroe := reader("enderEmit", "nro")
	xCple := reader("enderEmit", "xCpl")
	xBairroe := reader("enderEmit", "xBairro")
	cMune := reader("enderEmit", "cMun")
	xMune := reader("enderEmit", "xMun")
	ufe := reader("enderEmit", "UF")
	cepe := reader("enderEmit", "CEP")
	cPaise := reader("enderEmit", "cPais")
	xPaise := reader("enderEmit", "xPais")
	fonee := reader("enderEmit", "fone")
	iee := reader("emit", "IE")

	destinatario := model.Destinatario{
		CNPJ:    cnpj,
		XNome:   xNome,
		XLgr:    xLgr,
		Nro:     nro,
		XCpl:    xCpl,
		XBairro: xBairro,
		CMun:    cMun,
		XMun:    xMun,
		Uf:      uf,
		Cep:     cep,
		CPais:   cPais,
		XPais:   xPais,
		Fone:    fone,
		Ie:      ie,
	}

	emitentede := model.Emitente{
		CNPJ:    cnpje,
		XNome:   xNomee,
		XLgr:    xLgre,
		Nro:     nroe,
		XCpl:    xCple,
		XBairro: xBairroe,
		CMun:    cMune,
		XMun:    xMune,
		Uf:      ufe,
		Cep:     cepe,
		CPais:   cPaise,
		XPais:   xPaise,
		Fone:    fonee,
		Ie:      iee,
	}

	var itens []model.Item

	for i, _ := range codigo {
		codigoi := codigo[i].(string)
		eani := ean[i].(string)
		descricaoi := descricao[i].(string)
		ncmi := ncm[i].(string)
		cfopi := cfop[i].(string)
		unidi := unid[i].(string)
		qtdi := qtd[i].(string)
		vuniti := vUnit[i].(string)
		vtotali := vTotal[i].(string)

		Item := model.Item{
			Codigo:    codigoi,
			Ean:       eani,
			Descricao: descricaoi,
			Ncm:       ncmi,
			Cfop:      cfopi,
			Unid:      unidi,
			Qtd:       SpedConvert.ConvFloat(qtdi),
			VUnit:     SpedConvert.ConvFloat(vuniti),
			VTotal:    SpedConvert.ConvFloat(vtotali),
			DtEmit:    SpedConvert.ConvertDataXml(dEmit),
		}
		itens = append(itens, Item)
		//fmt.Printf("%#v\n",Item)
	}

	notafiscal := model.NotaFiscal{
		NNF:          nNf,
		ChNFe:        chnfe,
		NatOp:        natOp,
		IndPag:       indPag,
		Mod:          mod,
		Serie:        serie,
		DEmi:         SpedConvert.ConvertDataXml(dEmit),
		TpNF:         tpNf,
		TpImp:        tpImp,
		TpEmis:       tpEmis,
		CDV:          cdv,
		TpAmb:        tpAmb,
		FinNFe:       finNFe,
		ProcEmi:      procEmi,
		Emitente:     emitentede,
		Destinatario: destinatario,
		Itens:        itens,
	}
	db.NewRecord(notafiscal)
	db.Create(&notafiscal)
	db.Close()
	id--
}

func InsertSped(sped string, r *SpedExec.Regs) {
	db, err := gorm.Open("mysql", "root@/auditoria2?charset=utf8")
	file, err := os.Open(sped)
	SpedError.CheckErr(err)
	defer file.Close()
	scanner := bufio.NewScanner(file)
	// guarda cada linha em indice diferente do slice
	for scanner.Scan() {
		ProcessRows(scanner.Text(), r, *db)
	}
	id--
}

func ProcessRows(line string, r *SpedExec.Regs, db gorm.DB) {
	if line == "" {
		return
	}
	if line[:1] == "|" {
		line = strings.Replace(line, ",", ".", -1)
		ln := strings.Split(line, "|")
		SpedExec.TrataLinha(ln[1], line, r, db)
	}
}
<commit_msg>correção preco total dos xmls<commit_after>package SpedRead

import (
	"path/filepath"
	"os"
	"bufio"
	"strings"
	"github.com/jinzhu/gorm"
	"github.com/chapzin/parse-efd-fiscal/SpedExec"
	"github.com/chapzin/parse-efd-fiscal/SpedError"
	"time"
	"github.com/chapzin/parse-efd-fiscal/SpedConvert"
	"github.com/chapzin/parse-efd-fiscal/model"
	"io/ioutil"
	"github.com/clbanning/mxj"
)

var id int
var maxid = 100
// Ler todos os arquivos de uma determinada pasta
func RecursiveSpeds(path string) {
	filepath.Walk(path, func(file string, f os.FileInfo, err error) error {
		if f.IsDir() == false {
			ext := filepath.Ext(file)
			if ext == ".txt" {
				SpedError.CheckErr(err)
				// Possivelmente uma goroutines começando aqui
				r := SpedExec.Regs{}
				id++
				go InsertSped(file, &r)
				// Goroutines finalizando aqui
			}

			if ext == ".xml" {
				id++
				go InsertXml(file)
			}
			wait()
		}
		return nil
	})
}

func wait() {
	for {
		if id >= maxid {
			time.Sleep(1 * time.Second)
		} else {
			return
		}
	}

}

func InsertXml(xml string) {
	db, err := gorm.Open("mysql", "root@/auditoria2?charset=utf8")
	// Teste de lista produtos
	xmlFile, err := ioutil.ReadFile(xml)
	reader := SpedConvert.ConvXml(xml)
	SpedError.CheckErr(err)
	nfe, errOpenXml := mxj.NewMapXml(xmlFile)
	SpedError.CheckErr(errOpenXml)
	// Preenchendo o header da nfe
	nNf := reader("ide", "nNF")
	chnfe := reader("infProt", "chNFe")
	natOp := reader("ide", "natOp")
	indPag := reader("ide", "indPag")
	mod := reader("ide", "mod")
	serie := reader("ide", "serie")
	dEmit := reader("ide", "dEmi")
	if dEmit == "" {
		dhEmit := reader("ide", "dhEmi")
		dEmit = dhEmit
	}
	tpNf := reader("ide", "tpNF")
	tpImp := reader("ide", "tpImp")
	tpEmis := reader("ide", "tpEmis")
	cdv := reader("ide", "cDV")
	tpAmb := reader("ide", "tpAmb")
	finNFe := reader("ide", "finNFe")
	procEmi := reader("ide", "procEmi")

	// Preenchendo itens
	codigo, err := nfe.ValuesForKey("cProd")
	ean, err := nfe.ValuesForKey("cEAN")
	descricao, err := nfe.ValuesForKey("xProd")
	ncm, err := nfe.ValuesForKey("NCM")
	cfop, err := nfe.ValuesForKey("CFOP")
	unid, err := nfe.ValuesForKey("uCom")
	qtd, err := nfe.ValuesForKey("qCom")
	vUnit, err := nfe.ValuesForKey("vUnCom")
	vTotal, err := nfe.ValuesForKey("vProd")
	// Preenchendo Destinatario
	cnpj := reader("dest", "CNPJ")
	xNome := reader("dest", "xNome")
	xLgr := reader("enderDest", "xLgr")
	nro := reader("enderDest", "nro")
	xCpl := reader("enderDest", "xCpl")
	xBairro := reader("enderDest", "xBairro")
	cMun := reader("enderDest", "cMun")
	xMun := reader("enderDest", "xMun")
	uf := reader("enderDest", "UF")
	cep := reader("enderDest", "CEP")
	cPais := reader("enderDest", "cPais")
	xPais := reader("enderDest", "xPais")
	fone := reader("enderDest", "fone")
	ie := reader("dest", "IE")
	// Preenchendo Emitente
	cnpje := reader("emit", "CNPJ")
	xNomee := reader("emit", "xNome")
	xLgre := reader("enderEmit", "xLgr")
	nroe := reader("enderEmit", "nro")
	xCple := reader("enderEmit", "xCpl")
	xBairroe := reader("enderEmit", "xBairro")
	cMune := reader("enderEmit", "cMun")
	xMune := reader("enderEmit", "xMun")
	ufe := reader("enderEmit", "UF")
	cepe := reader("enderEmit", "CEP")
	cPaise := reader("enderEmit", "cPais")
	xPaise := reader("enderEmit", "xPais")
	fonee := reader("enderEmit", "fone")
	iee := reader("emit", "IE")

	destinatario := model.Destinatario{
		CNPJ:    cnpj,
		XNome:   xNome,
		XLgr:    xLgr,
		Nro:     nro,
		XCpl:    xCpl,
		XBairro: xBairro,
		CMun:    cMun,
		XMun:    xMun,
		Uf:      uf,
		Cep:     cep,
		CPais:   cPais,
		XPais:   xPais,
		Fone:    fone,
		Ie:      ie,
	}

	emitentede := model.Emitente{
		CNPJ:    cnpje,
		XNome:   xNomee,
		XLgr:    xLgre,
		Nro:     nroe,
		XCpl:    xCple,
		XBairro: xBairroe,
		CMun:    cMune,
		XMun:    xMune,
		Uf:      ufe,
		Cep:     cepe,
		CPais:   cPaise,
		XPais:   xPaise,
		Fone:    fonee,
		Ie:      iee,
	}

	var itens []model.Item

	for i, _ := range codigo {
		i2 := i+1
		codigoi := codigo[i].(string)
		eani := ean[i].(string)
		descricaoi := descricao[i].(string)
		ncmi := ncm[i].(string)
		cfopi := cfop[i].(string)
		unidi := unid[i].(string)
		qtdi := qtd[i].(string)
		vuniti := vUnit[i].(string)
		vtotali := vTotal[i2].(string)

		Item := model.Item{
			Codigo:    codigoi,
			Ean:       eani,
			Descricao: descricaoi,
			Ncm:       ncmi,
			Cfop:      cfopi,
			Unid:      unidi,
			Qtd:       SpedConvert.ConvFloat(qtdi),
			VUnit:     SpedConvert.ConvFloat(vuniti),
			VTotal:    SpedConvert.ConvFloat(vtotali),
			DtEmit:    SpedConvert.ConvertDataXml(dEmit),
		}
		itens = append(itens, Item)
		//fmt.Printf("%#v\n",Item)
	}

	notafiscal := model.NotaFiscal{
		NNF:          nNf,
		ChNFe:        chnfe,
		NatOp:        natOp,
		IndPag:       indPag,
		Mod:          mod,
		Serie:        serie,
		DEmi:         SpedConvert.ConvertDataXml(dEmit),
		TpNF:         tpNf,
		TpImp:        tpImp,
		TpEmis:       tpEmis,
		CDV:          cdv,
		TpAmb:        tpAmb,
		FinNFe:       finNFe,
		ProcEmi:      procEmi,
		Emitente:     emitentede,
		Destinatario: destinatario,
		Itens:        itens,
	}
	db.NewRecord(notafiscal)
	db.Create(&notafiscal)
	db.Close()
	id--
}

func InsertSped(sped string, r *SpedExec.Regs) {
	db, err := gorm.Open("mysql", "root@/auditoria2?charset=utf8")
	file, err := os.Open(sped)
	SpedError.CheckErr(err)
	defer file.Close()
	scanner := bufio.NewScanner(file)
	// guarda cada linha em indice diferente do slice
	for scanner.Scan() {
		ProcessRows(scanner.Text(), r, *db)
	}
	id--
}

func ProcessRows(line string, r *SpedExec.Regs, db gorm.DB) {
	if line == "" {
		return
	}
	if line[:1] == "|" {
		line = strings.Replace(line, ",", ".", -1)
		ln := strings.Split(line, "|")
		SpedExec.TrataLinha(ln[1], line, r, db)
	}
}
<|endoftext|>


<commit_before>package docker2aci

import (
	"bufio"
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"os"
	"path"
	"strings"
)

type Compression int

const (
	Uncompressed Compression = iota
	Gzip
)

func makeEndpointsList(headers []string) []string {
	var endpoints []string

	for _, ep := range headers {
		endpointsList := strings.Split(ep, ",")
		for _, endpointEl := range endpointsList {
			endpoints = append(
				endpoints,
				// TODO(iaguis) discover if httpsOrHTTP
				path.Join(strings.TrimSpace(endpointEl), "v1"))
		}
	}

	return endpoints
}

func decompress(layer io.Reader) (io.Reader, error) {
	bufR := bufio.NewReader(layer)
	bs, _ := bufR.Peek(10)

	compression := detectCompression(bs)
	switch compression {
	case Gzip:
		gz, err := gzip.NewReader(bufR)
		if err != nil {
			return nil, fmt.Errorf("Error reading layer (gzip): %v", err)
		}
		return gz, nil
	case Uncompressed:
		return bufR, nil
	default:
		return nil, fmt.Errorf("Unknown layer format")
	}
}

func detectCompression(source []byte) Compression {
	for compression, m := range map[Compression][]byte{
		Gzip: {0x1F, 0x8B, 0x08},
	} {
		if len(source) < len(m) {
			fmt.Fprintf(os.Stderr, "Len too short")
			continue
		}
		if bytes.Compare(m, source[:len(m)]) == 0 {
			return compression
		}
	}
	return Uncompressed
}
<commit_msg>Remove compression-handling stuff<commit_after>package docker2aci

import (
	"path"
	"strings"
)

func makeEndpointsList(headers []string) []string {
	var endpoints []string

	for _, ep := range headers {
		endpointsList := strings.Split(ep, ",")
		for _, endpointEl := range endpointsList {
			endpoints = append(
				endpoints,
				// TODO(iaguis) discover if httpsOrHTTP
				path.Join(strings.TrimSpace(endpointEl), "v1"))
		}
	}

	return endpoints
}
<|endoftext|>


<commit_before>package controllertests

import (
	"github.com/kyma-project/kyma/tests/remote-environment-controller-tests/test/testkit"
	"github.com/stretchr/testify/require"
	k8serrors "k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/apis/meta/v1"
	"testing"
	"time"
)

const (
	initialWaitTimeSeconds = 10 * time.Second
	retryWaitTimeSeconds   = 5 * time.Second
	retryCount             = 6
)

func TestRemoteEnvironmentCreation(t *testing.T) {

	config, err := testkit.ReadConfig()
	require.NoError(t, err)

	k8sResourcesClient, err := testkit.NewK8sResourcesClient(config.Namespace)
	require.NoError(t, err)

	helmClient := testkit.NewHelmClient(config.TillerHost, retryCount, retryWaitTimeSeconds)
	testReName := "test-create-re"
	k8sResourcesChecker := testkit.NewK8sResourceChecker(testReName, k8sResourcesClient, retryCount, retryWaitTimeSeconds)

	t.Run("should create complete RE helm chart when new RE is created", func(t *testing.T) {
		// when
		testRe, err := k8sResourcesClient.CreateDummyRemoteEnvironment(testReName)

		// then
		require.NoError(t, err)
		require.NotNil(t, testRe)
		time.Sleep(initialWaitTimeSeconds)

		t.Run("Helm release and k8s resources should exist", func(t *testing.T) {
			// when
			exists, err := helmClient.ExistWhenShould(testRe.Name)

			//then
			require.NoError(t, err)
			require.True(t, exists, "Release %s should exist but does not", testRe.Name)

			k8sResourcesChecker.CheckK8sResources(t, false, requireNoError, requireNotEmpty)
		})

		// when
		err = k8sResourcesClient.DeleteRemoteEnvironment(testReName, &v1.DeleteOptions{})

		// then
		require.NoError(t, err)
	})
}

func TestRemoteEnvironmentRemoval(t *testing.T) {

	config, err := testkit.ReadConfig()
	require.NoError(t, err)

	k8sResourcesClient, err := testkit.NewK8sResourcesClient(config.Namespace)
	require.NoError(t, err)

	helmClient := testkit.NewHelmClient(config.TillerHost, retryCount, retryWaitTimeSeconds)

	testReName := "test-delete-re"
	k8sResourcesChecker := testkit.NewK8sResourceChecker(testReName, k8sResourcesClient, retryCount, retryWaitTimeSeconds)

	testRe, err := k8sResourcesClient.CreateDummyRemoteEnvironment(testReName)
	require.NoError(t, err)
	time.Sleep(initialWaitTimeSeconds)

	t.Run("should delete RE helm chart when RE is deleted", func(t *testing.T) {
		// when
		err := k8sResourcesClient.DeleteRemoteEnvironment(testRe.Name, &v1.DeleteOptions{})

		// then
		require.NoError(t, err)
		time.Sleep(initialWaitTimeSeconds)

		// when
		exists, err := helmClient.ExistWhenShouldNot(testRe.Name)

		//then
		require.NoError(t, err)
		require.False(t, exists, "Release %s should not exist does", testRe.Name)

		k8sResourcesChecker.CheckK8sResources(t, true, requireError, requireEmpty)
	})
}

func requireError(t *testing.T, err error) {
	require.Error(t, err)
	require.True(t, k8serrors.IsNotFound(err))
}

func requireNoError(t *testing.T, err error) {
	require.NoError(t, err)
}

func requireNotEmpty(t *testing.T, obj interface{}) {
	require.NotEmpty(t, obj)
}

func requireEmpty(t *testing.T, obj interface{}) {
	require.Empty(t, obj)
}
<commit_msg>Fix RE Controller Tests retries (#885)<commit_after>package controllertests

import (
	"github.com/kyma-project/kyma/tests/remote-environment-controller-tests/test/testkit"
	"github.com/stretchr/testify/require"
	k8serrors "k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/apis/meta/v1"
	"testing"
	"time"
)

const (
	initialWaitTimeSeconds = 10 * time.Second
	retryWaitTimeSeconds   = 5 * time.Second
	retryCount             = 6
)

func TestRemoteEnvironmentCreation(t *testing.T) {

	config, err := testkit.ReadConfig()
	require.NoError(t, err)

	k8sResourcesClient, err := testkit.NewK8sResourcesClient(config.Namespace)
	require.NoError(t, err)

	helmClient := testkit.NewHelmClient(config.TillerHost, retryCount, retryWaitTimeSeconds)
	testReName := "test-create-re"
	k8sResourcesChecker := testkit.NewK8sResourceChecker(testReName, k8sResourcesClient, retryCount, retryWaitTimeSeconds)

	t.Run("should create complete RE helm chart when new RE is created", func(t *testing.T) {
		// when
		testRe, err := k8sResourcesClient.CreateDummyRemoteEnvironment(testReName)

		// then
		require.NoError(t, err)
		require.NotNil(t, testRe)
		time.Sleep(initialWaitTimeSeconds)

		t.Run("Helm release and k8s resources should exist", func(t *testing.T) {
			// when
			exists, err := helmClient.ExistWhenShould(testRe.Name)

			//then
			require.NoError(t, err)
			require.True(t, exists, "Release %s should exist but does not", testRe.Name)

			k8sResourcesChecker.CheckK8sResources(t, true, requireNoError, requireNotEmpty)
		})

		// when
		err = k8sResourcesClient.DeleteRemoteEnvironment(testReName, &v1.DeleteOptions{})

		// then
		require.NoError(t, err)
	})
}

func TestRemoteEnvironmentRemoval(t *testing.T) {

	config, err := testkit.ReadConfig()
	require.NoError(t, err)

	k8sResourcesClient, err := testkit.NewK8sResourcesClient(config.Namespace)
	require.NoError(t, err)

	helmClient := testkit.NewHelmClient(config.TillerHost, retryCount, retryWaitTimeSeconds)

	testReName := "test-delete-re"
	k8sResourcesChecker := testkit.NewK8sResourceChecker(testReName, k8sResourcesClient, retryCount, retryWaitTimeSeconds)

	testRe, err := k8sResourcesClient.CreateDummyRemoteEnvironment(testReName)
	require.NoError(t, err)
	time.Sleep(initialWaitTimeSeconds)

	t.Run("should delete RE helm chart when RE is deleted", func(t *testing.T) {
		// when
		err := k8sResourcesClient.DeleteRemoteEnvironment(testRe.Name, &v1.DeleteOptions{})

		// then
		require.NoError(t, err)
		time.Sleep(initialWaitTimeSeconds)

		// when
		exists, err := helmClient.ExistWhenShouldNot(testRe.Name)

		//then
		require.NoError(t, err)
		require.False(t, exists, "Release %s should not exist does", testRe.Name)

		k8sResourcesChecker.CheckK8sResources(t, false, requireError, requireEmpty)
	})
}

func requireError(t *testing.T, err error) {
	require.Error(t, err)
	require.True(t, k8serrors.IsNotFound(err))
}

func requireNoError(t *testing.T, err error) {
	require.NoError(t, err)
}

func requireNotEmpty(t *testing.T, obj interface{}) {
	require.NotEmpty(t, obj)
}

func requireEmpty(t *testing.T, obj interface{}) {
	require.Empty(t, obj)
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"strings"

	"github.com/appleboy/drone-facebook/template"
	"github.com/line/line-bot-sdk-go/linebot"
)

const defaultPreviewImageURL = "https://cdn4.iconfinder.com/data/icons/miu/24/device-camera-recorder-video-glyph-256.png"

type (
	// Repo information.
	Repo struct {
		Owner string
		Name  string
	}

	// Build information.
	Build struct {
		Tag      string
		Event    string
		Number   int
		Commit   string
		Branch   string
		Author   string
		Email    string
		Message  string
		Status   string
		Link     string
		Started  float64
		Finished float64
	}

	// Config for the plugin.
	Config struct {
		ChannelToken  string
		ChannelSecret string
		To            []string
		Delimiter     string
		Message       []string
		Image         []string
		Video         []string
		Audio         []string
		Sticker       []string
		Location      []string
		MatchEmail    bool
		Port          int
	}

	// Plugin values.
	Plugin struct {
		Repo   Repo
		Build  Build
		Config Config
	}

	// Audio format
	Audio struct {
		URL      string
		Duration int
	}

	// Location format
	Location struct {
		Title     string
		Address   string
		Latitude  float64
		Longitude float64
	}
)

func trimElement(keys []string) []string {
	var newKeys []string

	for _, value := range keys {
		value = strings.Trim(value, " ")
		if len(value) == 0 {
			continue
		}
		newKeys = append(newKeys, value)
	}

	return newKeys
}

func convertImage(value, delimiter string) []string {
	values := trimElement(strings.Split(value, delimiter))

	if len(values) < 2 {
		values = append(values, values[0])
	}

	return values
}

func convertVideo(value, delimiter string) []string {
	values := trimElement(strings.Split(value, delimiter))

	if len(values) < 2 {
		values = append(values, defaultPreviewImageURL)
	}

	return values
}

func convertAudio(value, delimiter string) (Audio, bool) {
	values := trimElement(strings.Split(value, delimiter))

	if len(values) < 2 {
		return Audio{}, true
	}

	duration, err := strconv.Atoi(values[1])

	if err != nil {
		log.Println(err.Error())
		return Audio{}, true
	}

	return Audio{
		URL:      values[0],
		Duration: duration,
	}, false
}

func convertSticker(value, delimiter string) ([]string, bool) {
	values := trimElement(strings.Split(value, delimiter))

	if len(values) < 2 {
		return []string{}, true
	}

	return values, false
}

func convertLocation(value, delimiter string) (Location, bool) {
	var latitude, longitude float64
	var err error
	values := trimElement(strings.Split(value, delimiter))

	if len(values) < 4 {
		return Location{}, true
	}

	latitude, err = strconv.ParseFloat(values[2], 64)

	if err != nil {
		log.Println(err.Error())
		return Location{}, true
	}

	longitude, err = strconv.ParseFloat(values[3], 64)

	if err != nil {
		log.Println(err.Error())
		return Location{}, true
	}

	return Location{
		Title:     values[0],
		Address:   values[1],
		Latitude:  latitude,
		Longitude: longitude,
	}, false
}

func parseTo(to []string, authorEmail string, matchEmail bool, delimiter string) []string {
	var emails []string
	var ids []string
	attachEmail := true

	for _, value := range trimElement(to) {
		idArray := trimElement(strings.Split(value, delimiter))

		// check match author email
		if len(idArray) > 1 {
			if email := idArray[1]; email != authorEmail {
				continue
			}

			emails = append(emails, idArray[0])
			attachEmail = false
			continue
		}

		ids = append(ids, idArray[0])
	}

	if matchEmail == true && attachEmail == false {
		return emails
	}

	for _, value := range emails {
		ids = append(ids, value)
	}

	return ids
}

func (p Plugin) Bot() (*linebot.Client, error) {
	if len(p.Config.ChannelToken) == 0 || len(p.Config.ChannelSecret) == 0 {
		log.Println("missing line bot config")

		return nil, errors.New("missing line bot config")
	}

	return linebot.New(p.Config.ChannelSecret, p.Config.ChannelToken)
}

func (p Plugin) Webhook() error {

	bot, err := p.Bot()

	if err != nil {
		return err
	}

	// Setup HTTP Server for receiving requests from LINE platform
	http.HandleFunc("/callback", func(w http.ResponseWriter, req *http.Request) {
		events, err := bot.ParseRequest(req)
		if err != nil {
			if err == linebot.ErrInvalidSignature {
				w.WriteHeader(400)
			} else {
				w.WriteHeader(500)
			}
			return
		}
		for _, event := range events {
			if event.Type == linebot.EventTypeMessage {
				switch message := event.Message.(type) {
				case *linebot.TextMessage:
					log.Printf("User ID is %v\n", event.Source.UserID)
					if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(message.Text)).Do(); err != nil {
						log.Print(err)
					}
				}
			}
		}
	})
	// This is just sample code.
	// For actual use, you must support HTTPS by using `ListenAndServeTLS`, a reverse proxy or something else.
	log.Println("Line Webhook Server Listin on " + strconv.Itoa(p.Config.Port) + " port")
	if err := http.ListenAndServe(":"+strconv.Itoa(p.Config.Port), nil); err != nil {
		log.Fatal(err)
	}

	return nil
}

// Exec executes the plugin.
func (p Plugin) Exec() error {

	bot, err := p.Bot()

	if err != nil {
		return err
	}

	if len(p.Config.To) == 0 {
		log.Println("missing line user config")

		return errors.New("missing line user config")
	}

	var message []string
	if len(p.Config.Message) > 0 {
		message = p.Config.Message
	} else {
		message = p.Message(p.Repo, p.Build)
	}

	// Initial messages array.
	var messages []linebot.Message

	for _, value := range trimElement(message) {
		txt, err := template.RenderTrim(value, p)
		if err != nil {
			return err
		}

		messages = append(messages, linebot.NewTextMessage(txt))
	}

	// Add image message
	for _, value := range trimElement(p.Config.Image) {
		values := convertImage(value, p.Config.Delimiter)

		messages = append(messages, linebot.NewImageMessage(values[0], values[1]))
	}

	// Add image message.
	for _, value := range trimElement(p.Config.Video) {
		values := convertVideo(value, p.Config.Delimiter)

		messages = append(messages, linebot.NewVideoMessage(values[0], values[1]))
	}

	// Add Audio message.
	for _, value := range trimElement(p.Config.Audio) {
		audio, empty := convertAudio(value, p.Config.Delimiter)

		if empty == true {
			continue
		}

		messages = append(messages, linebot.NewAudioMessage(audio.URL, audio.Duration))
	}

	// Add Sticker message.
	for _, value := range trimElement(p.Config.Sticker) {
		sticker, empty := convertSticker(value, p.Config.Delimiter)

		if empty == true {
			continue
		}

		messages = append(messages, linebot.NewStickerMessage(sticker[0], sticker[1]))
	}

	// check Location array.
	for _, value := range trimElement(p.Config.Location) {
		location, empty := convertLocation(value, p.Config.Delimiter)

		if empty == true {
			continue
		}

		messages = append(messages, linebot.NewLocationMessage(location.Title, location.Address, location.Latitude, location.Longitude))
	}

	ids := parseTo(p.Config.To, p.Build.Email, p.Config.MatchEmail, p.Config.Delimiter)

	// send message to user
	for _, id := range ids {
		if _, err := bot.PushMessage(id, messages...).Do(); err != nil {
			log.Println(err.Error())
		}
	}

	return nil
}

// Message is line default message.
func (p Plugin) Message(repo Repo, build Build) []string {
	return []string{fmt.Sprintf("[%s] <%s> (%s)『%s』by %s",
		build.Status,
		build.Link,
		build.Branch,
		build.Message,
		build.Author,
	)}
}
<commit_msg>fix lint error.<commit_after>package main

import (
	"errors"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"strings"

	"github.com/appleboy/drone-facebook/template"
	"github.com/line/line-bot-sdk-go/linebot"
)

const defaultPreviewImageURL = "https://cdn4.iconfinder.com/data/icons/miu/24/device-camera-recorder-video-glyph-256.png"

type (
	// Repo information.
	Repo struct {
		Owner string
		Name  string
	}

	// Build information.
	Build struct {
		Tag      string
		Event    string
		Number   int
		Commit   string
		Branch   string
		Author   string
		Email    string
		Message  string
		Status   string
		Link     string
		Started  float64
		Finished float64
	}

	// Config for the plugin.
	Config struct {
		ChannelToken  string
		ChannelSecret string
		To            []string
		Delimiter     string
		Message       []string
		Image         []string
		Video         []string
		Audio         []string
		Sticker       []string
		Location      []string
		MatchEmail    bool
		Port          int
	}

	// Plugin values.
	Plugin struct {
		Repo   Repo
		Build  Build
		Config Config
	}

	// Audio format
	Audio struct {
		URL      string
		Duration int
	}

	// Location format
	Location struct {
		Title     string
		Address   string
		Latitude  float64
		Longitude float64
	}
)

func trimElement(keys []string) []string {
	var newKeys []string

	for _, value := range keys {
		value = strings.Trim(value, " ")
		if len(value) == 0 {
			continue
		}
		newKeys = append(newKeys, value)
	}

	return newKeys
}

func convertImage(value, delimiter string) []string {
	values := trimElement(strings.Split(value, delimiter))

	if len(values) < 2 {
		values = append(values, values[0])
	}

	return values
}

func convertVideo(value, delimiter string) []string {
	values := trimElement(strings.Split(value, delimiter))

	if len(values) < 2 {
		values = append(values, defaultPreviewImageURL)
	}

	return values
}

func convertAudio(value, delimiter string) (Audio, bool) {
	values := trimElement(strings.Split(value, delimiter))

	if len(values) < 2 {
		return Audio{}, true
	}

	duration, err := strconv.Atoi(values[1])

	if err != nil {
		log.Println(err.Error())
		return Audio{}, true
	}

	return Audio{
		URL:      values[0],
		Duration: duration,
	}, false
}

func convertSticker(value, delimiter string) ([]string, bool) {
	values := trimElement(strings.Split(value, delimiter))

	if len(values) < 2 {
		return []string{}, true
	}

	return values, false
}

func convertLocation(value, delimiter string) (Location, bool) {
	var latitude, longitude float64
	var err error
	values := trimElement(strings.Split(value, delimiter))

	if len(values) < 4 {
		return Location{}, true
	}

	latitude, err = strconv.ParseFloat(values[2], 64)

	if err != nil {
		log.Println(err.Error())
		return Location{}, true
	}

	longitude, err = strconv.ParseFloat(values[3], 64)

	if err != nil {
		log.Println(err.Error())
		return Location{}, true
	}

	return Location{
		Title:     values[0],
		Address:   values[1],
		Latitude:  latitude,
		Longitude: longitude,
	}, false
}

func parseTo(to []string, authorEmail string, matchEmail bool, delimiter string) []string {
	var emails []string
	var ids []string
	attachEmail := true

	for _, value := range trimElement(to) {
		idArray := trimElement(strings.Split(value, delimiter))

		// check match author email
		if len(idArray) > 1 {
			if email := idArray[1]; email != authorEmail {
				continue
			}

			emails = append(emails, idArray[0])
			attachEmail = false
			continue
		}

		ids = append(ids, idArray[0])
	}

	if matchEmail == true && attachEmail == false {
		return emails
	}

	for _, value := range emails {
		ids = append(ids, value)
	}

	return ids
}

// Bot is new Line Bot clien.
func (p Plugin) Bot() (*linebot.Client, error) {
	if len(p.Config.ChannelToken) == 0 || len(p.Config.ChannelSecret) == 0 {
		log.Println("missing line bot config")

		return nil, errors.New("missing line bot config")
	}

	return linebot.New(p.Config.ChannelSecret, p.Config.ChannelToken)
}

// Webhook support line callback service.
func (p Plugin) Webhook() error {

	bot, err := p.Bot()

	if err != nil {
		return err
	}

	// Setup HTTP Server for receiving requests from LINE platform
	http.HandleFunc("/callback", func(w http.ResponseWriter, req *http.Request) {
		events, err := bot.ParseRequest(req)
		if err != nil {
			if err == linebot.ErrInvalidSignature {
				w.WriteHeader(400)
			} else {
				w.WriteHeader(500)
			}
			return
		}
		for _, event := range events {
			if event.Type == linebot.EventTypeMessage {
				switch message := event.Message.(type) {
				case *linebot.TextMessage:
					log.Printf("User ID is %v\n", event.Source.UserID)
					if _, err = bot.ReplyMessage(event.ReplyToken, linebot.NewTextMessage(message.Text)).Do(); err != nil {
						log.Print(err)
					}
				}
			}
		}
	})
	// This is just sample code.
	// For actual use, you must support HTTPS by using `ListenAndServeTLS`, a reverse proxy or something else.
	log.Println("Line Webhook Server Listin on " + strconv.Itoa(p.Config.Port) + " port")
	if err := http.ListenAndServe(":"+strconv.Itoa(p.Config.Port), nil); err != nil {
		log.Fatal(err)
	}

	return nil
}

// Exec executes the plugin.
func (p Plugin) Exec() error {

	bot, err := p.Bot()

	if err != nil {
		return err
	}

	if len(p.Config.To) == 0 {
		log.Println("missing line user config")

		return errors.New("missing line user config")
	}

	var message []string
	if len(p.Config.Message) > 0 {
		message = p.Config.Message
	} else {
		message = p.Message(p.Repo, p.Build)
	}

	// Initial messages array.
	var messages []linebot.Message

	for _, value := range trimElement(message) {
		txt, err := template.RenderTrim(value, p)
		if err != nil {
			return err
		}

		messages = append(messages, linebot.NewTextMessage(txt))
	}

	// Add image message
	for _, value := range trimElement(p.Config.Image) {
		values := convertImage(value, p.Config.Delimiter)

		messages = append(messages, linebot.NewImageMessage(values[0], values[1]))
	}

	// Add image message.
	for _, value := range trimElement(p.Config.Video) {
		values := convertVideo(value, p.Config.Delimiter)

		messages = append(messages, linebot.NewVideoMessage(values[0], values[1]))
	}

	// Add Audio message.
	for _, value := range trimElement(p.Config.Audio) {
		audio, empty := convertAudio(value, p.Config.Delimiter)

		if empty == true {
			continue
		}

		messages = append(messages, linebot.NewAudioMessage(audio.URL, audio.Duration))
	}

	// Add Sticker message.
	for _, value := range trimElement(p.Config.Sticker) {
		sticker, empty := convertSticker(value, p.Config.Delimiter)

		if empty == true {
			continue
		}

		messages = append(messages, linebot.NewStickerMessage(sticker[0], sticker[1]))
	}

	// check Location array.
	for _, value := range trimElement(p.Config.Location) {
		location, empty := convertLocation(value, p.Config.Delimiter)

		if empty == true {
			continue
		}

		messages = append(messages, linebot.NewLocationMessage(location.Title, location.Address, location.Latitude, location.Longitude))
	}

	ids := parseTo(p.Config.To, p.Build.Email, p.Config.MatchEmail, p.Config.Delimiter)

	// send message to user
	for _, id := range ids {
		if _, err := bot.PushMessage(id, messages...).Do(); err != nil {
			log.Println(err.Error())
		}
	}

	return nil
}

// Message is line default message.
func (p Plugin) Message(repo Repo, build Build) []string {
	return []string{fmt.Sprintf("[%s] <%s> (%s)『%s』by %s",
		build.Status,
		build.Link,
		build.Branch,
		build.Message,
		build.Author,
	)}
}
<|endoftext|>


<commit_before>package testing

import (
	"sync"
	"time"

	"fmt"

	"github.com/awslabs/aws-sdk-go/gen/swf"
)

type TestAdapter interface {
	Logf(format string, args ...interface{})
	Fatalf(format string, args ...interface{})
	FailNow()
}

func NewTestListener(t TestAdapter, decisionOutcomes chan DecisionOutcome) *TestListener {
	tl := &TestListener{
		decisionOutcomes: decisionOutcomes,
		historyInterest:  make(map[string]chan swf.HistoryEvent, 1000),
		decisionInterest: make(map[string]chan swf.Decision, 1000),
		stateInterest:    make(map[string]chan string, 1000),
		DefaultWait:      10 * time.Second,
		testAdapter:      t,
	}
	tl.Start()
	return tl
}

type TestListener struct {
	decisionOutcomes chan DecisionOutcome
	historyInterest  map[string]chan swf.HistoryEvent
	historyLock      sync.Mutex
	decisionInterest map[string]chan swf.Decision
	decisionLock     sync.Mutex
	stateInterest    map[string]chan string
	stateLock        sync.Mutex
	DefaultWait      time.Duration
	testAdapter      TestAdapter
}

func (tl *TestListener) RegisterHistoryInterest(workflowID string) chan swf.HistoryEvent {
	defer tl.historyLock.Unlock()
	tl.historyLock.Lock()
	historyChan, ok := tl.historyInterest[workflowID]
	if !ok {
		historyChan = make(chan swf.HistoryEvent, 1000)
		tl.historyInterest[workflowID] = historyChan
	}
	return historyChan
}

func (tl *TestListener) RegisterDecisionInterest(workflowID string) chan swf.Decision {
	defer tl.decisionLock.Unlock()
	tl.decisionLock.Lock()
	decisionChan, ok := tl.decisionInterest[workflowID]
	if !ok {
		decisionChan = make(chan swf.Decision, 1000)
		tl.decisionInterest[workflowID] = decisionChan
	}
	return decisionChan
}

func (tl *TestListener) RegisterStateInterest(workflowID string) chan string {
	defer tl.stateLock.Unlock()
	tl.stateLock.Lock()
	stateChan, ok := tl.stateInterest[workflowID]
	if !ok {
		stateChan = make(chan string, 1000)
		tl.stateInterest[workflowID] = stateChan
	}
	return stateChan
}

func (tl *TestListener) AwaitStateFor(workflowID, state string, waitFor time.Duration) {
	ch := tl.RegisterStateInterest(workflowID)
	timer := time.After(waitFor)

	for {
		select {
		case s := <-ch:
			tl.testAdapter.Logf("TestListener: await state for workflow=%s state=%s received-state=%s", workflowID, state, s)
			if s == state {
				return
			}
		case <-timer:
			tl.testAdapter.Fatalf("TestListener: timed out waiting for workflow=%s state=%s", workflowID, state)
			tl.testAdapter.FailNow()
			panic(fmt.Sprintf("TestListener: timed out waiting for workflow=%s state=%s", workflowID, state))
		}
	}
}

func (tl *TestListener) AwaitState(workflowID, state string) {
	tl.AwaitStateFor(workflowID, state, tl.DefaultWait)
}

func (tl *TestListener) AwaitEventFor(workflowID string, waitFor time.Duration, predicate func(swf.HistoryEvent) bool) {
	ch := tl.RegisterHistoryInterest(workflowID)
	timer := time.After(waitFor)
	for {
		select {
		case h := <-ch:
			if predicate(h) {
				tl.testAdapter.Logf("TestListener: await event for workflow=%s received-event=%s predicate=true", workflowID, *h.EventType)
				return
			} else {
				tl.testAdapter.Logf("TestListener: await event for workflow=%s received-event=%s predicate=false", workflowID, *h.EventType)
			}
		case <-timer:
			tl.testAdapter.Fatalf("TestListener: timed out waiting for workflow=%s event", workflowID)
			tl.testAdapter.FailNow()
			panic(fmt.Sprintf("TestListener: timed out waiting for workflow=%s event", workflowID))
		}
	}
}

func (tl *TestListener) AwaitEvent(workflowID string, predicate func(swf.HistoryEvent) bool) {
	tl.AwaitEventFor(workflowID, tl.DefaultWait, predicate)
}

func (tl *TestListener) AwaitDecisionFor(workflowID string, waitFor time.Duration, predicate func(swf.Decision) bool) {
	ch := tl.RegisterDecisionInterest(workflowID)
	timer := time.After(waitFor)
	for {
		select {
		case h := <-ch:
			if predicate(h) {
				tl.testAdapter.Logf("TestListener: await decision for workflow=%s received-decision=%s predicate=true", workflowID, *h.DecisionType)
				return
			} else {
				tl.testAdapter.Logf("TestListener: await decision for workflow=%s received-decision=%s predicate=false", workflowID, *h.DecisionType)
			}
		case <-timer:
			tl.testAdapter.Fatalf("TestListener: timed out waiting for workflow=%s decision", workflowID)
			tl.testAdapter.FailNow()
			panic(fmt.Sprintf("TestListener: timed out waiting for workflow=%s decision", workflowID))
		}
	}
}

func (tl *TestListener) AwaitDecision(workflowID string, predicate func(swf.Decision) bool) {
	tl.AwaitDecisionFor(workflowID, tl.DefaultWait, predicate)
}

func (tl *TestListener) Start() {
	tl.testAdapter.Logf("TestListener: Starting")
	go tl.forward()
}

func (tl *TestListener) Stop() {
	close(tl.decisionOutcomes)
}

func (tl *TestListener) forward() {
	tl.testAdapter.Logf("TestListener: Forwarding")
	for {
		select {
		case do, ok := <-tl.decisionOutcomes:
			tl.testAdapter.Logf("TestListener: ")
			if !ok {
				tl.testAdapter.Logf("TestListener: decisionOutcomes closed!!!!!!!!")
				return
			}

			workflow := *do.DecisionTask.WorkflowExecution.WorkflowID
			tl.testAdapter.Logf("TestListener: DecisionOutcome for workflow %s", workflow)
			//send history events
			if c, ok := tl.historyInterest[workflow]; ok {
				tl.testAdapter.Logf("TestListener: yes historyInterest for workflow %s", workflow)
				for i := len(do.DecisionTask.Events) - 1; i >= 0; i-- {
					event := do.DecisionTask.Events[i]
					if *event.EventID > *do.DecisionTask.PreviousStartedEventID {
						tl.testAdapter.Logf("TestListener: yes historyInterest for workflow %s %s", workflow, *do.DecisionTask.Events[i].EventType)
						c <- do.DecisionTask.Events[i]
					}
				}
			} else {
				tl.testAdapter.Logf("TestListener: no historyInterest for workflow %s", workflow)
			}
			//send decisions
			if c, ok := tl.decisionInterest[workflow]; ok {
				for _, d := range do.Decisions {
					tl.testAdapter.Logf("TestListener: yes decisionInterest for workflow %s %s", workflow, *d.DecisionType)
					c <- d
				}
			} else {
				tl.testAdapter.Logf("TestListener: no decisionInterest for workflow %s", workflow)
			}
			//send states
			if c, ok := tl.stateInterest[workflow]; ok {
				tl.testAdapter.Logf("TestListener: yes stateInterest for workflow %s %s", workflow, do.State)
				c <- do.State
			} else {
				tl.testAdapter.Logf("TestListener: no stateInterest for workflow %s", workflow)
			}
		case <-time.After(1 * time.Second):
			tl.testAdapter.Logf("TestListener: warn, no DecisionOutcomes after 1 second")
		}
	}
}
<commit_msg>ffs. painc in the await failures so the effing test fails<commit_after>package testing

import (
	"sync"
	"time"

	"fmt"

	"github.com/awslabs/aws-sdk-go/gen/swf"
)

type TestAdapter interface {
	Logf(format string, args ...interface{})
	Fatalf(format string, args ...interface{})
	FailNow()
}

func NewTestListener(t TestAdapter, decisionOutcomes chan DecisionOutcome) *TestListener {
	tl := &TestListener{
		decisionOutcomes: decisionOutcomes,
		historyInterest:  make(map[string]chan swf.HistoryEvent, 1000),
		decisionInterest: make(map[string]chan swf.Decision, 1000),
		stateInterest:    make(map[string]chan string, 1000),
		DefaultWait:      10 * time.Second,
		testAdapter:      t,
	}
	tl.Start()
	return tl
}

type TestListener struct {
	decisionOutcomes chan DecisionOutcome
	historyInterest  map[string]chan swf.HistoryEvent
	historyLock      sync.Mutex
	decisionInterest map[string]chan swf.Decision
	decisionLock     sync.Mutex
	stateInterest    map[string]chan string
	stateLock        sync.Mutex
	DefaultWait      time.Duration
	testAdapter      TestAdapter
}

func (tl *TestListener) RegisterHistoryInterest(workflowID string) chan swf.HistoryEvent {
	defer tl.historyLock.Unlock()
	tl.historyLock.Lock()
	historyChan, ok := tl.historyInterest[workflowID]
	if !ok {
		historyChan = make(chan swf.HistoryEvent, 1000)
		tl.historyInterest[workflowID] = historyChan
	}
	return historyChan
}

func (tl *TestListener) RegisterDecisionInterest(workflowID string) chan swf.Decision {
	defer tl.decisionLock.Unlock()
	tl.decisionLock.Lock()
	decisionChan, ok := tl.decisionInterest[workflowID]
	if !ok {
		decisionChan = make(chan swf.Decision, 1000)
		tl.decisionInterest[workflowID] = decisionChan
	}
	return decisionChan
}

func (tl *TestListener) RegisterStateInterest(workflowID string) chan string {
	defer tl.stateLock.Unlock()
	tl.stateLock.Lock()
	stateChan, ok := tl.stateInterest[workflowID]
	if !ok {
		stateChan = make(chan string, 1000)
		tl.stateInterest[workflowID] = stateChan
	}
	return stateChan
}

func (tl *TestListener) AwaitStateFor(workflowID, state string, waitFor time.Duration) {
	ch := tl.RegisterStateInterest(workflowID)
	timer := time.After(waitFor)

	for {
		select {
		case s := <-ch:
			tl.testAdapter.Logf("TestListener: await state for workflow=%s state=%s received-state=%s", workflowID, state, s)
			if s == state {
				return
			}
		case <-timer:
			panic(fmt.Sprintf("TestListener: timed out waiting for workflow=%s state=%s", workflowID, state))
			tl.testAdapter.Fatalf("TestListener: timed out waiting for workflow=%s state=%s", workflowID, state)
			tl.testAdapter.FailNow()
		}
	}
}

func (tl *TestListener) AwaitState(workflowID, state string) {
	tl.AwaitStateFor(workflowID, state, tl.DefaultWait)
}

func (tl *TestListener) AwaitEventFor(workflowID string, waitFor time.Duration, predicate func(swf.HistoryEvent) bool) {
	ch := tl.RegisterHistoryInterest(workflowID)
	timer := time.After(waitFor)
	for {
		select {
		case h := <-ch:
			if predicate(h) {
				tl.testAdapter.Logf("TestListener: await event for workflow=%s received-event=%s predicate=true", workflowID, *h.EventType)
				return
			} else {
				tl.testAdapter.Logf("TestListener: await event for workflow=%s received-event=%s predicate=false", workflowID, *h.EventType)
			}
		case <-timer:
			panic(fmt.Sprintf("TestListener: timed out waiting for workflow=%s event", workflowID))
			tl.testAdapter.Fatalf("TestListener: timed out waiting for workflow=%s event", workflowID)
			tl.testAdapter.FailNow()
		}
	}
}

func (tl *TestListener) AwaitEvent(workflowID string, predicate func(swf.HistoryEvent) bool) {
	tl.AwaitEventFor(workflowID, tl.DefaultWait, predicate)
}

func (tl *TestListener) AwaitDecisionFor(workflowID string, waitFor time.Duration, predicate func(swf.Decision) bool) {
	ch := tl.RegisterDecisionInterest(workflowID)
	timer := time.After(waitFor)
	for {
		select {
		case h := <-ch:
			if predicate(h) {
				tl.testAdapter.Logf("TestListener: await decision for workflow=%s received-decision=%s predicate=true", workflowID, *h.DecisionType)
				return
			} else {
				tl.testAdapter.Logf("TestListener: await decision for workflow=%s received-decision=%s predicate=false", workflowID, *h.DecisionType)
			}
		case <-timer:
			panic(fmt.Sprintf("TestListener: timed out waiting for workflow=%s decision", workflowID))
			tl.testAdapter.Fatalf("TestListener: timed out waiting for workflow=%s decision", workflowID)
			tl.testAdapter.FailNow()
		}
	}
}

func (tl *TestListener) AwaitDecision(workflowID string, predicate func(swf.Decision) bool) {
	tl.AwaitDecisionFor(workflowID, tl.DefaultWait, predicate)
}

func (tl *TestListener) Start() {
	tl.testAdapter.Logf("TestListener: Starting")
	go tl.forward()
}

func (tl *TestListener) Stop() {
	close(tl.decisionOutcomes)
}

func (tl *TestListener) forward() {
	tl.testAdapter.Logf("TestListener: Forwarding")
	for {
		select {
		case do, ok := <-tl.decisionOutcomes:
			tl.testAdapter.Logf("TestListener: ")
			if !ok {
				tl.testAdapter.Logf("TestListener: decisionOutcomes closed!!!!!!!!")
				return
			}

			workflow := *do.DecisionTask.WorkflowExecution.WorkflowID
			tl.testAdapter.Logf("TestListener: DecisionOutcome for workflow %s", workflow)
			//send history events
			if c, ok := tl.historyInterest[workflow]; ok {
				tl.testAdapter.Logf("TestListener: yes historyInterest for workflow %s", workflow)
				for i := len(do.DecisionTask.Events) - 1; i >= 0; i-- {
					event := do.DecisionTask.Events[i]
					if *event.EventID > *do.DecisionTask.PreviousStartedEventID {
						tl.testAdapter.Logf("TestListener: yes historyInterest for workflow %s %s", workflow, *do.DecisionTask.Events[i].EventType)
						c <- do.DecisionTask.Events[i]
					}
				}
			} else {
				tl.testAdapter.Logf("TestListener: no historyInterest for workflow %s", workflow)
			}
			//send decisions
			if c, ok := tl.decisionInterest[workflow]; ok {
				for _, d := range do.Decisions {
					tl.testAdapter.Logf("TestListener: yes decisionInterest for workflow %s %s", workflow, *d.DecisionType)
					c <- d
				}
			} else {
				tl.testAdapter.Logf("TestListener: no decisionInterest for workflow %s", workflow)
			}
			//send states
			if c, ok := tl.stateInterest[workflow]; ok {
				tl.testAdapter.Logf("TestListener: yes stateInterest for workflow %s %s", workflow, do.State)
				c <- do.State
			} else {
				tl.testAdapter.Logf("TestListener: no stateInterest for workflow %s", workflow)
			}
		case <-time.After(1 * time.Second):
			tl.testAdapter.Logf("TestListener: warn, no DecisionOutcomes after 1 second")
		}
	}
}
<|endoftext|>


<commit_before>package notify

import (
	"errors"

	"github.com/godbus/dbus"
)

// Categories
const (
	Device              = "device"
	DeviceAdded         = "device.added"
	DeviceError         = "device.error"
	DeviceRemoved       = "device.removed"
	Email               = "email"
	EmailArrived        = "email.arrived"
	EmailBounced        = "email.bounced"
	Im                  = "im"
	ImError             = "im.error"
	ImReceived          = "im.received"
	Network             = "network"
	NetworkConnected    = "network.connected"
	NetworkDisconnected = "network.disconnected"
	NetworkError        = "network.error"
	Presence            = "presence"
	PresenceOffline     = "presence.offline"
	PresenceOnline      = "presence.online"
	Transfer            = "transfer"
	TransferComplete    = "transfer.complete"
	TransferError       = "transfer.error"
)

// Urgency Levels
const (
	Low      = 0
	Normal   = 1
	Critical = 2
)

// Capabilities
const (
	ActionIcons    = "action-icons"
	Actions        = "actions"
	Body           = "body"
	BodyHyperlinks = "body-hyperlinks"
	BodyImages     = "body-images"
	BodyMarkup     = "body-markup"
	IconMulti      = "icon-multi"
	IconStatic     = "icon-static"
	Persistence    = "persistence"
	Sound          = "sound"
)

type Capabilities struct {
	ActionIcons    bool
	Actions        bool
	Body           bool
	BodyHyperlinks bool
	BodyImages     bool
	BodyMarkup     bool
	IconMulti      bool
	IconStatic     bool
	Persistence    bool
	Sound          bool
}

// Returns the capabilities of the notification server
func GetCapabilities() (c *Capabilities, err error) {

	connection, err := dbus.SessionBus()
	if err != nil {

		return
	}
	obj := connection.Object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")

	call := obj.Call("org.freedesktop.Notifications.GetCapabilities", 0)
	if call.Err != nil {

		return nil, call.Err
	}

	c = &Capabilities{}
	s := []string{}

	if err := call.Store(&s); err != nil {

		return nil, err
	}

	for _, v := range s {

		if v == ActionIcons {

			c.ActionIcons = true
			continue
		}

		if v == Actions {

			c.Actions = true
			continue
		}

		if v == Body {

			c.Body = true
			continue
		}

		if v == BodyHyperlinks {

			c.BodyHyperlinks = true
			continue
		}

		if v == BodyImages {

			c.BodyImages = true
			continue
		}

		if v == BodyMarkup {

			c.BodyMarkup = true
			continue
		}

		if v == IconMulti {

			c.IconMulti = true
			continue
		}

		if v == IconStatic {

			c.IconStatic = true
			continue
		}

		if v == Persistence {

			c.Persistence = true
			continue
		}

		if v == Sound {

			c.Sound = true
			continue
		}
	}

	return
}

// Create a new notification object with some basic information
func NewNotification(summary, body string) (n *Notification, err error) {

	if len(summary) == 0 {

		return nil, errors.New("The Notification must contain a summary")
	}

	n = &Notification{

		Summary: summary,
		Body:    body,
		Timeout: -1,
	}
	return
}

// Send the notification
func (n *Notification) Send() (id uint32, err error) {

	hints := map[string]dbus.Variant{}
	if len(n.Hints) != 0 {

		for k, v := range n.Hints {

			hints[k] = dbus.MakeVariant(v)
		}
	}

	connection, err := dbus.SessionBus()
	if err != nil {

		return
	}
	obj := connection.Object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")

	call := obj.Call(
		"org.freedesktop.Notifications.Notify",
		0,
		n.AppName,
		n.ReplacesID,
		n.AppIcon,
		n.Summary,
		n.Body,
		n.Actions,
		hints,
		n.Timeout)
	if call.Err != nil {

		return 0, call.Err
	}

	if err := call.Store(&id); err != nil {

		return 0, err
	}

	return
}

// Closes the notification if it exists using its id
func CloseNotification(id uint32) (err error) {

	connection, err := dbus.SessionBus()
	if err != nil {

		return
	}
	obj := connection.Object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")

	call := obj.Call("org.freedesktop.Notifications.GetCapabilities", 0, id)
	if call.Err != nil {

		return call.Err
	}

	return
}

type ServerInformation struct {
	Name        string
	Vendor      string
	Version     string
	SpecVersion string
}

// Gets information about the notification server
func GetServerInformation() (i *ServerInformation, err error) {

	connection, err := dbus.SessionBus()
	if err != nil {

		return
	}
	obj := connection.Object("org.freedesktop.Notifications", "/org/freedesktop/Notifications")

	call := obj.Call("org.freedesktop.Notifications.GetServerInformation", 0)
	if call.Err != nil {

		return nil, call.Err
	}

	i = &ServerInformation{}
	if err := call.Store(&i.Name, i.Vendor, i.Version, i.SpecVersion); err != nil {

		return nil, err
	}

	return
}
<commit_msg>Removed notify_linux.go<commit_after><|endoftext|>


<commit_before>package sentinel

import (
	"time"

	"github.com/mdevilliers/redishappy/configuration"
	"github.com/mdevilliers/redishappy/services/logger"
	"github.com/mdevilliers/redishappy/services/redis"
	"github.com/mdevilliers/redishappy/types"
	"github.com/mdevilliers/redishappy/util"
)

const (
	SentinelMarkedUp    = 1
	SentinelMarkedDown  = 2
	SentinelMarkedAlive = 3
)

type Manager interface {
	Notify(event SentinelEvent)
}

type SentinelManager struct {
	eventsChannel          chan SentinelEvent
	topologyRequestChannel chan TopologyRequest
	switchmasterchannel    chan types.MasterSwitchedEvent
	redisConnection        redis.RedisConnection
	configurationManager   *configuration.ConfigurationManager
	throttle               *Throttle
}

var topologyState = SentinelTopology{Sentinels: map[string]*SentinelInfo{}}

func NewManager(switchmasterchannel chan types.MasterSwitchedEvent, cm *configuration.ConfigurationManager) *SentinelManager {

	events := make(chan SentinelEvent)
	requests := make(chan TopologyRequest)
	unthrottled := make(chan types.MasterSwitchedEvent)

	throttle := NewThrottle(unthrottled, switchmasterchannel)

	manager := &SentinelManager{eventsChannel: events,
		topologyRequestChannel: requests,
		switchmasterchannel:    unthrottled,
		redisConnection:        redis.RadixRedisConnection{},
		configurationManager:   cm,
		throttle:               throttle}

	go manager.loopEvents(events, requests)
	go manager.bootstrap()
	return manager
}

func (m *SentinelManager) Notify(event SentinelEvent) {
	m.eventsChannel <- event
}

func (m *SentinelManager) GetState(request TopologyRequest) {
	m.topologyRequestChannel <- request
}

func (m *SentinelManager) ClearState() {
	topologyState = SentinelTopology{Sentinels: map[string]*SentinelInfo{}}
}

func (m *SentinelManager) GetCurrentTopology() types.MasterDetailsCollection {
	stateChannel := make(chan types.MasterDetailsCollection)
	go m.getTopology(stateChannel)
	return <-stateChannel
}

func (m *SentinelManager) getTopology(stateChannel chan types.MasterDetailsCollection) {

	topology := types.NewMasterDetailsCollection()
	configuration := m.configurationManager.GetCurrentConfiguration()

	for _, sentinel := range configuration.Sentinels {
		client, err := NewSentinelClient(sentinel, m.redisConnection)

		if err != nil {
			logger.Info.Printf("Error starting sentinel (%s) client : %s", sentinel.GetLocation(), err.Error())
			continue
		}
		defer client.Close()

		for _, clusterDetails := range configuration.Clusters {

			details, err := client.DiscoverMasterForCluster(clusterDetails.Name)
			if err != nil {
				continue
			}

			details.ExternalPort = clusterDetails.ExternalPort
			// TODO : last one wins?
			topology.AddOrReplace(details)
		}
	}
	stateChannel <- topology
}

func (m *SentinelManager) bootstrap() {

	configuration := m.configurationManager.GetCurrentConfiguration()

	for _, sentinel := range configuration.Sentinels {
		m.Notify(&SentinelAdded{Sentinel: sentinel})
	}

	util.Schedule(func() { m.bootstrap() }, time.Second*60)
}

func (m *SentinelManager) exploreSentinelTopology(sentinel types.Sentinel) {

	client, err := NewSentinelClient(sentinel, m.redisConnection)

	if err != nil {
		logger.Info.Printf("Error starting sentinel (%s) client : %s", sentinel.GetLocation(), err.Error())
	}
	defer client.Close()

	knownClusters := client.FindKnownClusters()

	m.Notify(&SentinelClustersMonitoredUpdate{Sentinel: sentinel, Clusters: knownClusters})

	for _, clustername := range knownClusters {

		sentinels := client.FindConnectedSentinels(clustername)

		for _, connectedsentinel := range sentinels {
			m.Notify(&SentinelAdded{Sentinel: connectedsentinel})
		}
	}
}

func (m *SentinelManager) startNewMonitor(sentinel types.Sentinel) (*Monitor, error) {

	monitor, err := NewMonitor(sentinel, m, m.redisConnection)

	if err != nil {
		logger.Error.Printf("Error starting monitor %s : %s", sentinel.GetLocation(), err.Error())
		m.Notify(&SentinelLost{Sentinel: sentinel})
		return nil, err
	}

	go monitor.StartMonitoringMasterEvents(m.switchmasterchannel)

	return monitor, nil
}

func (m *SentinelManager) loopEvents(events chan SentinelEvent, topology chan TopologyRequest) {
	for {
		select {
		case event := <-events:
			m.updateState(event)
		case read := <-topology:
			read.ReplyChannel <- topologyState
		}
	}
}

func (m *SentinelManager) updateState(event interface{}) {

	switch e := event.(type) {
	case *SentinelAdded:

		sentinel := e.GetSentinel()
		uid := topologyState.createKey(sentinel)

		//if we don't know about the sentinel start monitoring it
		if _, exists := topologyState.Sentinels[uid]; !exists {

			info := &SentinelInfo{SentinelLocation: uid,
				LastUpdated: time.Now().UTC(),
				State:       SentinelMarkedUp}

			topologyState.Sentinels[uid] = info

			go m.startNewMonitor(sentinel)
			go m.exploreSentinelTopology(sentinel)

			logger.Trace.Printf("Sentinel added : %s", util.String(topologyState))
		}

	case *SentinelLost:

		sentinel := e.GetSentinel()
		uid := topologyState.createKey(sentinel)
		currentInfo, ok := topologyState.Sentinels[uid]

		if ok {
			currentInfo.State = SentinelMarkedDown
			currentInfo.LastUpdated = time.Now().UTC()
		}

		util.Schedule(func() { m.startNewMonitor(sentinel) }, time.Second*5)

		logger.Trace.Printf("Sentinel lost : %s (scheduling new client and monitor).", util.String(topologyState))

	case *SentinelPing:
		sentinel := e.GetSentinel()
		uid := topologyState.createKey(sentinel)
		currentInfo, ok := topologyState.Sentinels[uid]

		if ok {
			currentInfo.State = SentinelMarkedAlive
			currentInfo.LastUpdated = time.Now().UTC()
		}

	case *SentinelClustersMonitoredUpdate:
		sentinel := e.GetSentinel()
		uid := topologyState.createKey(sentinel)

		if info, exists := topologyState.Sentinels[uid]; exists {

			info.Clusters = e.Clusters
		}

	default:
		logger.Error.Println("Unknown sentinel event : ", util.String(e))
	}
}
<commit_msg>surface retry periods as constants<commit_after>package sentinel

import (
	"time"

	"github.com/mdevilliers/redishappy/configuration"
	"github.com/mdevilliers/redishappy/services/logger"
	"github.com/mdevilliers/redishappy/services/redis"
	"github.com/mdevilliers/redishappy/types"
	"github.com/mdevilliers/redishappy/util"
)

const (
	SentinelMarkedUp    = 1
	SentinelMarkedDown  = 2
	SentinelMarkedAlive = 3
)

const (
	SentinelReconnectionPeriod        = time.Second * 5
	SentinelTopologyExplorationPeriod = time.Second * 60
)

type Manager interface {
	Notify(event SentinelEvent)
}

type SentinelManager struct {
	eventsChannel          chan SentinelEvent
	topologyRequestChannel chan TopologyRequest
	switchmasterchannel    chan types.MasterSwitchedEvent
	redisConnection        redis.RedisConnection
	configurationManager   *configuration.ConfigurationManager
	throttle               *Throttle
}

var topologyState = SentinelTopology{Sentinels: map[string]*SentinelInfo{}}

func NewManager(switchmasterchannel chan types.MasterSwitchedEvent, cm *configuration.ConfigurationManager) *SentinelManager {

	events := make(chan SentinelEvent)
	requests := make(chan TopologyRequest)
	unthrottled := make(chan types.MasterSwitchedEvent)

	throttle := NewThrottle(unthrottled, switchmasterchannel)

	manager := &SentinelManager{eventsChannel: events,
		topologyRequestChannel: requests,
		switchmasterchannel:    unthrottled,
		redisConnection:        redis.RadixRedisConnection{},
		configurationManager:   cm,
		throttle:               throttle}

	go manager.loopEvents(events, requests)
	go manager.bootstrap()
	return manager
}

func (m *SentinelManager) Notify(event SentinelEvent) {
	m.eventsChannel <- event
}

func (m *SentinelManager) GetState(request TopologyRequest) {
	m.topologyRequestChannel <- request
}

func (m *SentinelManager) ClearState() {
	topologyState = SentinelTopology{Sentinels: map[string]*SentinelInfo{}}
}

func (m *SentinelManager) GetCurrentTopology() types.MasterDetailsCollection {
	stateChannel := make(chan types.MasterDetailsCollection)
	go m.getTopology(stateChannel)
	return <-stateChannel
}

func (m *SentinelManager) getTopology(stateChannel chan types.MasterDetailsCollection) {

	topology := types.NewMasterDetailsCollection()
	configuration := m.configurationManager.GetCurrentConfiguration()

	for _, sentinel := range configuration.Sentinels {
		client, err := NewSentinelClient(sentinel, m.redisConnection)

		if err != nil {
			logger.Info.Printf("Error starting sentinel (%s) client : %s", sentinel.GetLocation(), err.Error())
			continue
		}
		defer client.Close()

		for _, clusterDetails := range configuration.Clusters {

			details, err := client.DiscoverMasterForCluster(clusterDetails.Name)
			if err != nil {
				continue
			}

			details.ExternalPort = clusterDetails.ExternalPort
			// TODO : last one wins?
			topology.AddOrReplace(details)
		}
	}
	stateChannel <- topology
}

func (m *SentinelManager) bootstrap() {

	configuration := m.configurationManager.GetCurrentConfiguration()

	for _, sentinel := range configuration.Sentinels {
		m.Notify(&SentinelAdded{Sentinel: sentinel})
	}

	util.Schedule(func() { m.bootstrap() }, SentinelTopologyExplorationPeriod)
}

func (m *SentinelManager) exploreSentinelTopology(sentinel types.Sentinel) {

	client, err := NewSentinelClient(sentinel, m.redisConnection)

	if err != nil {
		logger.Info.Printf("Error starting sentinel (%s) client : %s", sentinel.GetLocation(), err.Error())
	}
	defer client.Close()

	knownClusters := client.FindKnownClusters()

	m.Notify(&SentinelClustersMonitoredUpdate{Sentinel: sentinel, Clusters: knownClusters})

	for _, clustername := range knownClusters {

		sentinels := client.FindConnectedSentinels(clustername)

		for _, connectedsentinel := range sentinels {
			m.Notify(&SentinelAdded{Sentinel: connectedsentinel})
		}
	}
}

func (m *SentinelManager) startNewMonitor(sentinel types.Sentinel) (*Monitor, error) {

	monitor, err := NewMonitor(sentinel, m, m.redisConnection)

	if err != nil {
		logger.Error.Printf("Error starting monitor %s : %s", sentinel.GetLocation(), err.Error())
		m.Notify(&SentinelLost{Sentinel: sentinel})
		return nil, err
	}

	go monitor.StartMonitoringMasterEvents(m.switchmasterchannel)

	return monitor, nil
}

func (m *SentinelManager) loopEvents(events chan SentinelEvent, topology chan TopologyRequest) {
	for {
		select {
		case event := <-events:
			m.updateState(event)
		case read := <-topology:
			read.ReplyChannel <- topologyState
		}
	}
}

func (m *SentinelManager) updateState(event interface{}) {

	switch e := event.(type) {
	case *SentinelAdded:

		sentinel := e.GetSentinel()
		uid := topologyState.createKey(sentinel)

		//if we don't know about the sentinel start monitoring it
		if _, exists := topologyState.Sentinels[uid]; !exists {

			info := &SentinelInfo{SentinelLocation: uid,
				LastUpdated: time.Now().UTC(),
				State:       SentinelMarkedUp}

			topologyState.Sentinels[uid] = info

			go m.startNewMonitor(sentinel)
			go m.exploreSentinelTopology(sentinel)

			logger.Trace.Printf("Sentinel added : %s", util.String(topologyState))
		}

	case *SentinelLost:

		sentinel := e.GetSentinel()
		uid := topologyState.createKey(sentinel)
		currentInfo, ok := topologyState.Sentinels[uid]

		if ok {
			currentInfo.State = SentinelMarkedDown
			currentInfo.LastUpdated = time.Now().UTC()
		}

		util.Schedule(func() { m.startNewMonitor(sentinel) }, SentinelReconnectionPeriod)

		logger.Trace.Printf("Sentinel lost : %s (scheduling new client and monitor).", util.String(topologyState))

	case *SentinelPing:
		sentinel := e.GetSentinel()
		uid := topologyState.createKey(sentinel)
		currentInfo, ok := topologyState.Sentinels[uid]

		if ok {
			currentInfo.State = SentinelMarkedAlive
			currentInfo.LastUpdated = time.Now().UTC()
		}

	case *SentinelClustersMonitoredUpdate:
		sentinel := e.GetSentinel()
		uid := topologyState.createKey(sentinel)

		if info, exists := topologyState.Sentinels[uid]; exists {

			info.Clusters = e.Clusters
		}

	default:
		logger.Error.Println("Unknown sentinel event : ", util.String(e))
	}
}
<|endoftext|>


<commit_before>package parser

import (
	"fmt"
	"github.com/zimmski/tavor/token/lists"
	"github.com/zimmski/tavor/token/primitives"
	"strings"
	"testing"

	. "github.com/stretchr/testify/assert"

	"github.com/zimmski/tavor/token"
)

func TestInternalParseErrors(t *testing.T) {
	var errs []error

	// nil root token
	errs = ParseInternal(nil, strings.NewReader(""))
	Equal(t, len(errs), 1)
	Equal(t, token.ParseErrorRootIsNil, errs[0].(*token.ParserError).Type)

	// constant integer errors
	errs = ParseInternal(primitives.NewConstantInt(1), strings.NewReader(""))
	Equal(t, len(errs), 1)
	Equal(t, token.ParseErrorUnexpectedEOF, errs[0].(*token.ParserError).Type)

	errs = ParseInternal(primitives.NewConstantInt(1), strings.NewReader("2"))
	Equal(t, len(errs), 1)
	Equal(t, token.ParseErrorUnexpectedData, errs[0].(*token.ParserError).Type)

	errs = ParseInternal(primitives.NewConstantInt(1), strings.NewReader("123"))
	Equal(t, len(errs), 1)
	Equal(t, token.ParseErrorExpectedEOF, errs[0].(*token.ParserError).Type)

	errs = ParseInternal(primitives.NewConstantInt(1), strings.NewReader("1234567890"))
	Equal(t, len(errs), 1)
	Equal(t, token.ParseErrorExpectedEOF, errs[0].(*token.ParserError).Type)

	// constant string errors
	errs = ParseInternal(primitives.NewConstantString("a"), strings.NewReader(""))
	Equal(t, len(errs), 1)
	Equal(t, token.ParseErrorUnexpectedEOF, errs[0].(*token.ParserError).Type)

	errs = ParseInternal(primitives.NewConstantString("a"), strings.NewReader("b"))
	Equal(t, len(errs), 1)
	Equal(t, token.ParseErrorUnexpectedData, errs[0].(*token.ParserError).Type)
}

func checkParse(t *testing.T, root token.Token, data string) {
	errs := ParseInternal(root, strings.NewReader(data))
	if len(errs) != 0 {
		fmt.Printf("ERRS: %+v\n", errs)
	}
	Nil(t, errs)
	Equal(t, data, root.String())
}

func TestInternalParse(t *testing.T) {
	var tok, o token.Token
	var errs []error

	// constant integer
	checkParse(
		t,
		primitives.NewConstantInt(1),
		"1",
	)

	checkParse(
		t,
		primitives.NewConstantInt(123),
		"123",
	)

	// constant string
	checkParse(
		t,
		primitives.NewConstantString("a"),
		"a",
	)

	checkParse(
		t,
		primitives.NewConstantString("abc"),
		"abc",
	)

	// All
	checkParse(
		t,
		lists.NewAll(
			primitives.NewConstantInt(1),
			primitives.NewConstantString("a"),
		),
		"1a",
	)

	errs = ParseInternal(lists.NewAll(
		primitives.NewConstantInt(1),
		primitives.NewConstantString("a"),
		primitives.NewConstantInt(2),
	), strings.NewReader("1a"))

	Equal(t, token.ParseErrorUnexpectedEOF, errs[0].(*token.ParserError).Type)
	Nil(t, tok)

	errs = ParseInternal(lists.NewAll(
		primitives.NewConstantInt(1),
		primitives.NewConstantString("a"),
	), strings.NewReader("1a2b"))

	Equal(t, token.ParseErrorExpectedEOF, errs[0].(*token.ParserError).Type)
	Nil(t, tok)

	// One
	o = lists.NewOne(
		primitives.NewConstantInt(1),
		primitives.NewConstantString("a"),
	)

	checkParse(
		t,
		o,
		"1",
	)

	checkParse(
		t,
		o,
		"a",
	)

	errs = ParseInternal(o, strings.NewReader("2"))
	Equal(t, token.ParseErrorUnexpectedData, errs[0].(*token.ParserError).Type)
	Nil(t, tok)
}
<commit_msg>testcase nested and and or<commit_after>package parser

import (
	"fmt"
	"github.com/zimmski/tavor/token/lists"
	"github.com/zimmski/tavor/token/primitives"
	"strings"
	"testing"

	. "github.com/stretchr/testify/assert"

	"github.com/zimmski/tavor/token"
)

func TestInternalParseErrors(t *testing.T) {
	var errs []error

	// nil root token
	errs = ParseInternal(nil, strings.NewReader(""))
	Equal(t, len(errs), 1)
	Equal(t, token.ParseErrorRootIsNil, errs[0].(*token.ParserError).Type)

	// constant integer errors
	errs = ParseInternal(primitives.NewConstantInt(1), strings.NewReader(""))
	Equal(t, len(errs), 1)
	Equal(t, token.ParseErrorUnexpectedEOF, errs[0].(*token.ParserError).Type)

	errs = ParseInternal(primitives.NewConstantInt(1), strings.NewReader("2"))
	Equal(t, len(errs), 1)
	Equal(t, token.ParseErrorUnexpectedData, errs[0].(*token.ParserError).Type)

	errs = ParseInternal(primitives.NewConstantInt(1), strings.NewReader("123"))
	Equal(t, len(errs), 1)
	Equal(t, token.ParseErrorExpectedEOF, errs[0].(*token.ParserError).Type)

	errs = ParseInternal(primitives.NewConstantInt(1), strings.NewReader("1234567890"))
	Equal(t, len(errs), 1)
	Equal(t, token.ParseErrorExpectedEOF, errs[0].(*token.ParserError).Type)

	// constant string errors
	errs = ParseInternal(primitives.NewConstantString("a"), strings.NewReader(""))
	Equal(t, len(errs), 1)
	Equal(t, token.ParseErrorUnexpectedEOF, errs[0].(*token.ParserError).Type)

	errs = ParseInternal(primitives.NewConstantString("a"), strings.NewReader("b"))
	Equal(t, len(errs), 1)
	Equal(t, token.ParseErrorUnexpectedData, errs[0].(*token.ParserError).Type)
}

func checkParse(t *testing.T, root token.Token, data string) {
	errs := ParseInternal(root, strings.NewReader(data))
	if len(errs) != 0 {
		fmt.Printf("ERRS: %+v\n", errs)
	}
	Nil(t, errs)
	Equal(t, data, root.String())
}

func TestInternalParse(t *testing.T) {
	var tok, o token.Token
	var errs []error

	// constant integer
	checkParse(
		t,
		primitives.NewConstantInt(1),
		"1",
	)

	checkParse(
		t,
		primitives.NewConstantInt(123),
		"123",
	)

	// constant string
	checkParse(
		t,
		primitives.NewConstantString("a"),
		"a",
	)

	checkParse(
		t,
		primitives.NewConstantString("abc"),
		"abc",
	)

	// All
	checkParse(
		t,
		lists.NewAll(
			primitives.NewConstantInt(1),
			primitives.NewConstantString("a"),
		),
		"1a",
	)

	errs = ParseInternal(lists.NewAll(
		primitives.NewConstantInt(1),
		primitives.NewConstantString("a"),
		primitives.NewConstantInt(2),
	), strings.NewReader("1a"))

	Equal(t, token.ParseErrorUnexpectedEOF, errs[0].(*token.ParserError).Type)
	Nil(t, tok)

	errs = ParseInternal(lists.NewAll(
		primitives.NewConstantInt(1),
		primitives.NewConstantString("a"),
	), strings.NewReader("1a2b"))

	Equal(t, token.ParseErrorExpectedEOF, errs[0].(*token.ParserError).Type)
	Nil(t, tok)

	// One
	o = lists.NewOne(
		primitives.NewConstantInt(1),
		primitives.NewConstantString("a"),
	)

	checkParse(
		t,
		o,
		"1",
	)

	checkParse(
		t,
		o,
		"a",
	)

	errs = ParseInternal(o, strings.NewReader("2"))
	Equal(t, token.ParseErrorUnexpectedData, errs[0].(*token.ParserError).Type)
	Nil(t, tok)

	// combine
	o = lists.NewOne(
		lists.NewAll(
			primitives.NewConstantInt(1),
			primitives.NewConstantString("a"),
		),
		lists.NewAll(
			primitives.NewConstantInt(1),
			primitives.NewConstantString("b"),
		),
	)

	checkParse(
		t,
		o,
		"1a",
	)

	checkParse(
		t,
		o,
		"1b",
	)

	errs = ParseInternal(o, strings.NewReader("1c"))
	Equal(t, token.ParseErrorUnexpectedData, errs[0].(*token.ParserError).Type)
	Nil(t, tok)
}
<|endoftext|>


<commit_before>package rtypes

import (
	"github.com/robloxapi/types"
)

type NilType struct{}

var Nil NilType

func (NilType) Type() string {
	return "nil"
}

func (NilType) String() string {
	return "nil"
}

func (n NilType) Copy() types.PropValue {
	return n
}
<commit_msg>Remove Copy method from Nil.<commit_after>package rtypes

type NilType struct{}

var Nil NilType

func (NilType) Type() string {
	return "nil"
}

func (NilType) String() string {
	return "nil"
}
<|endoftext|>


<commit_before>package apns

import (
	"bytes"
	"crypto/tls"
	"encoding/binary"
	"errors"
	"github.com/zhangpeihao/log"
	"net"
	"time"
)

const (
	MIN_QUEUE_SIZE = 8
)

var (
	LOG_HEADERS  = []string{"Out", "Out_E"}
	logger       *log.Logger
	READ_TIMEOUT = time.Second * 3600
)

var (
	ErrClosed  = errors.New("Closed")
	ErrBlocked = errors.New("Blocked")
	ErrTimeout = errors.New("Timeout")
)

func InitLog(l *log.Logger) {
	logger = l
	logger.Println("InitLog()")
}

type Conn struct {
	c           *tls.Conn
	sendTimeout time.Duration
	exit        bool
}

func Dial(serverAddress string, cert []tls.Certificate,
	sendTimeout time.Duration) (c *Conn, err error) {
	var conn net.Conn
	if conn, err = net.DialTimeout("tcp", serverAddress, sendTimeout); err != nil {
		return
	}
	tlsConn := tls.Client(conn, &tls.Config{
		Certificates:       cert,
		InsecureSkipVerify: true,
	})
	if err = tlsConn.SetWriteDeadline(time.Now().Add(sendTimeout)); err != nil {
		return
	}
	handshakeChan := make(chan bool)
	go func(ch chan<- bool) {
		logger.Debugln("apnd.Dial() Handshake")
		if err = tlsConn.Handshake(); err != nil {
			logger.Debugln("apnd.Dial() Handshake failed")
			ch <- false
			return
		}
		logger.Debugln("apnd.Dial() Handshake success")
		ch <- true
	}(handshakeChan)
	select {
	case b := <-handshakeChan:
		if !b {
			return
		}
	case <-time.After(time.Second * time.Duration(5)):
		logger.Debugln("apnd.Dial() Handshake timeout")
		tlsConn.Close()
		err = ErrTimeout
		return
	}
	c = &Conn{
		c:           tlsConn,
		sendTimeout: sendTimeout,
	}

	go c.readLoop()
	return
}

func (c *Conn) Closed() bool {
	return c.exit
}

func (c *Conn) Close() {
	c.exit = true
	c.c.Close()
}

func (c *Conn) readLoop() {
	//	var err error
	if err := c.c.SetReadDeadline(time.Unix(9999999999, 0)); err != nil {
		logger.Add("Out_E", int64(1))
		logger.Warningln("apns.Conn::readLoop() SetReadDeadline err:", err)
		c.Close()
		return
	}
	buf := make([]byte, 6)
	for !c.exit {
		// read response
		if n, err := c.c.Read(buf); err != nil {
			netErr, ok := err.(net.Error)
			if ok && netErr.Temporary() {
				time.Sleep(time.Second)
			} else {
				logger.Add("Out_E", int64(1))
				logger.Debugln("apns.Conn::readLoop() Read err:", err)
				if n > 0 {
					logger.Debugf("APNS read %02X\n", buf)
				}
				break
			}
		} else {
			logger.Debugf("APNS read %02X\n", buf)
		}
	}
	c.Close()
}

func (c *Conn) Send(data []byte) (err error) {
	if c.exit {
		return ErrClosed
	}
	if err = c.c.SetWriteDeadline(time.Now().Add(c.sendTimeout)); err != nil {
		logger.Add("Out_E", int64(1))
		logger.Warningln("apns.Conn::Send() SetWriteDeadline err:", err)
		return
	}
	logger.Debugf("sendLoop() data: % 02X\n", data)
	if _, err = c.c.Write(data); err != nil {
		logger.Add("Out_E", int64(1))
		logger.Warningln("apns.Conn::Send() Write err:", err)
		return
	}

	logger.Add("Out", int64(1))
	return
}

func (c *Conn) SendMessage(deviceToken []byte, message []byte) (err error) {
	buf := new(bytes.Buffer)
	if _, err = buf.Write([]byte{0, 0, 32}); err != nil {
		return
	}
	if _, err = buf.Write(deviceToken); err != nil {
		return
	}
	if err = binary.Write(buf, binary.BigEndian, uint16(len(message))); err != nil {
		return
	}
	if _, err = buf.Write(message); err != nil {
		return
	}
	return c.Send(buf.Bytes())
}
<commit_msg>Fixed bug: Dead lock when connect timeout<commit_after>package apns

import (
	"bytes"
	"crypto/tls"
	"encoding/binary"
	"errors"
	"github.com/zhangpeihao/log"
	"net"
	"time"
)

const (
	MIN_QUEUE_SIZE = 8
)

var (
	LOG_HEADERS  = []string{"Out", "Out_E"}
	logger       *log.Logger
	READ_TIMEOUT = time.Second * 3600
)

var (
	ErrClosed  = errors.New("Closed")
	ErrBlocked = errors.New("Blocked")
	ErrTimeout = errors.New("Timeout")
)

func InitLog(l *log.Logger) {
	logger = l
	logger.Println("InitLog()")
}

type Conn struct {
	c           *tls.Conn
	sendTimeout time.Duration
	exit        bool
}

func Dial(serverAddress string, cert []tls.Certificate,
	sendTimeout time.Duration) (c *Conn, err error) {
	var conn net.Conn
	if conn, err = net.DialTimeout("tcp", serverAddress, sendTimeout); err != nil {
		return
	}
	tlsConn := tls.Client(conn, &tls.Config{
		Certificates:       cert,
		InsecureSkipVerify: true,
	})
	if err = tlsConn.SetWriteDeadline(time.Now().Add(sendTimeout)); err != nil {
		return
	}
	handshakeChan := make(chan bool, 1)
	go func(ch chan<- bool) {
		logger.Debugln("apns.Dial() Handshake")
		if err = tlsConn.Handshake(); err != nil {
			logger.Debugln("apnd.Dial() Handshake failed")
			ch <- false
			return
		}
		logger.Debugln("apns.Dial() Handshake success")
		ch <- true
	}(handshakeChan)
	select {
	case b := <-handshakeChan:
		if !b {
			return
		}
	case <-time.After(time.Second * time.Duration(5)):
		logger.Debugln("apnd.Dial() Handshake timeout")
		tlsConn.Close()
		err = ErrTimeout
		return
	}
	c = &Conn{
		c:           tlsConn,
		sendTimeout: sendTimeout,
	}

	go c.readLoop()
	return
}

func (c *Conn) Closed() bool {
	return c.exit
}

func (c *Conn) Close() {
	c.exit = true
	c.c.Close()
}

func (c *Conn) readLoop() {
	//	var err error
	if err := c.c.SetReadDeadline(time.Unix(9999999999, 0)); err != nil {
		logger.Add("Out_E", int64(1))
		logger.Warningln("apns.Conn::readLoop() SetReadDeadline err:", err)
		c.Close()
		return
	}
	buf := make([]byte, 6)
	for !c.exit {
		// read response
		if n, err := c.c.Read(buf); err != nil {
			netErr, ok := err.(net.Error)
			if ok && netErr.Temporary() {
				time.Sleep(time.Second)
			} else {
				logger.Add("Out_E", int64(1))
				logger.Debugln("apns.Conn::readLoop() Read err:", err)
				if n > 0 {
					logger.Debugf("APNS read %02X\n", buf)
				}
				break
			}
		} else {
			logger.Debugf("APNS read %02X\n", buf)
		}
	}
	c.Close()
}

func (c *Conn) Send(data []byte) (err error) {
	if c.exit {
		return ErrClosed
	}
	if err = c.c.SetWriteDeadline(time.Now().Add(c.sendTimeout)); err != nil {
		logger.Add("Out_E", int64(1))
		logger.Warningln("apns.Conn::Send() SetWriteDeadline err:", err)
		return
	}
	logger.Debugf("sendLoop() data: % 02X\n", data)
	if _, err = c.c.Write(data); err != nil {
		logger.Add("Out_E", int64(1))
		logger.Warningln("apns.Conn::Send() Write err:", err)
		return
	}

	logger.Add("Out", int64(1))
	return
}

func (c *Conn) SendMessage(deviceToken []byte, message []byte) (err error) {
	buf := new(bytes.Buffer)
	if _, err = buf.Write([]byte{0, 0, 32}); err != nil {
		return
	}
	if _, err = buf.Write(deviceToken); err != nil {
		return
	}
	if err = binary.Write(buf, binary.BigEndian, uint16(len(message))); err != nil {
		return
	}
	if _, err = buf.Write(message); err != nil {
		return
	}
	return c.Send(buf.Bytes())
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net/http"
	"os"

	"github.com/nbari/go-sandbox/decorator/client"
)

func main() {
	c := client.Decorate(client.MockClient{},
		client.Last(log.New(os.Stdout, "[last decorator] ", 0)),
		client.Logging(log.New(os.Stdout, "[logging decorator] ", 0)),
		client.Audit(log.New(os.Stdout, "[audit decorator] ", 0)),
		client.First(log.New(os.Stdout, "[first decorator] ", 0)),
	)
	req, _ := http.NewRequest("GET", "http://example.com", nil)
	c.Do(req)
}
<commit_msg>update<commit_after>package main

import (
	"log"
	"net/http"
	"os"

	"github.com/nbari/go-sandbox/decorator/client"
)

func main() {
	// c := client.Decorate(&http.Client{},
	c := client.Decorate(client.MockClient{},
		client.Last(log.New(os.Stdout, "[last decorator] ", 0)),
		client.Logging(log.New(os.Stdout, "[logging decorator] ", 0)),
		client.Audit(log.New(os.Stdout, "[audit decorator] ", 0)),
		client.First(log.New(os.Stdout, "[first decorator] ", 0)),
	)
	req, _ := http.NewRequest("GET", "http://example.com", nil)
	c.Do(req)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"math/rand"
	"os"
	"path/filepath"
	"sync"
	"sync/atomic"
	"time"

	"github.com/dgraph-io/badger/y"
	"github.com/pkg/profile"
)

var (
	dir           = flag.String("dir", "datafiles", "File to read from")
	numReads      = flag.Int64("num", 2000000, "Number of reads")
	mode          = flag.Int("mode", 1, "0 = serial, 1 = parallel, 2 = parallel via channel")
	numGoroutines = flag.Int("jobs", 8, "Number of Goroutines")
	profilemode   = flag.String("profile.mode", "", "Enable profiling mode, one of [cpu, mem, mutex, block]")
)

var readSize int64 = 4 << 10

func getIndices(r *rand.Rand, flist []*os.File, maxFileSize int64) (*os.File, int64) {
	fidx := r.Intn(len(flist))
	iidx := r.Int63n(maxFileSize - readSize)
	return flist[fidx], iidx
}

func Serial(fList []*os.File, maxFileSize int64) {
	startT := time.Now()
	var i int64 = 0
	b := make([]byte, int(readSize))

	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for ; i < *numReads; i++ {
		fd, offset := getIndices(r, fList, maxFileSize)
		_, err := fd.ReadAt(b, offset)
		if err != nil {
			log.Fatalf("Error reading file: %v", err)
		}
		if i%10000 == 0 {
			log.Printf("Finished %v reads in serial", i)
		}
	}
	fmt.Println("Serial: Number of random reads per second: ",
		float64(*numReads)/time.Since(startT).Seconds())
	fmt.Println("Serial: Time Taken: ", time.Since(startT))
}

func Conc2(fList []*os.File, maxFileSize int64) {
	startT := time.Now()
	var i int64
	var wg sync.WaitGroup

	for k := 0; k < *numGoroutines; k++ {
		wg.Add(1)
		go func() {
			b := make([]byte, int(readSize))
			r := rand.New(rand.NewSource(time.Now().UnixNano()))
			for atomic.AddInt64(&i, 1) <= *numReads {
				fd, offset := getIndices(r, fList, maxFileSize)
				_, err := fd.ReadAt(b, offset)
				if err != nil {
					log.Fatalf("Error reading file: %v", err)
				}
			}
			wg.Done()
		}()
	}
	wg.Wait()
	fmt.Println("Concurrent 2: Number of random reads per second: ",
		float64(*numReads)/time.Since(startT).Seconds())
	fmt.Println("Concurrent 2: Time Taken: ", time.Since(startT))
}

type req struct {
	fd     *os.File
	offset int64
}

func Conc3(fList []*os.File, maxFileSize int64) {
	ch := make(chan req, 10000)
	go func() {
		var i int64
		rd := rand.New(rand.NewSource(time.Now().UnixNano()))
		for i = 0; i < *numReads; i++ {
			var r req
			r.fd, r.offset = getIndices(rd, fList, maxFileSize)
			ch <- r
		}
		close(ch)
	}()

	startT := time.Now()
	var wg sync.WaitGroup
	for k := 0; k < *numGoroutines; k++ {
		wg.Add(1)
		go func() {
			b := make([]byte, int(readSize))
			for req := range ch {
				_, err := req.fd.ReadAt(b, req.offset)
				if err != nil {
					log.Fatalf("Error reading file: %v", err)
				}
			}
			wg.Done()
		}()
	}
	wg.Wait()
	fmt.Println("Concurrent 3: Number of random reads per second: ",
		float64(*numReads)/time.Since(startT).Seconds())
	fmt.Println("Concurrent 3: Time Taken: ", time.Since(startT))
}

func main() {
	flag.Parse()

	var flist []*os.File
	var maxFileSize int64
	getFile := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			log.Print(err)
			return nil
		}

		if !info.IsDir() {
			f, err := os.Open(path)
			y.AssertTruef(err == nil, "Error opening file: %v", path)
			flist = append(flist, f)
			log.Println("Opened file:", path, "Size:", info.Size()/(1<<20), "MB")
			maxFileSize = info.Size()
		}
		return nil
	}

	err := filepath.Walk(*dir, getFile)
	if err != nil {
		log.Fatalf("%v", err)
	}
	if len(flist) == 0 {
		log.Fatalf("Must have files already created")
	}

	switch *profilemode {
	case "cpu":
		defer profile.Start(profile.CPUProfile).Stop()
	case "mem":
		defer profile.Start(profile.MemProfile).Stop()
	case "mutex":
		defer profile.Start(profile.MutexProfile).Stop()
	case "block":
		defer profile.Start(profile.BlockProfile).Stop()
	}

	switch *mode {
	case 0:
		Serial(flist, maxFileSize)
	case 1:
		Conc2(flist, maxFileSize)
	case 2:
		Conc3(flist, maxFileSize)
	}
}
<commit_msg>Remove atomics<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"math/rand"
	"os"
	"path/filepath"
	"sync"
	"time"

	"github.com/dgraph-io/badger/y"
	"github.com/pkg/profile"
)

var (
	dir           = flag.String("dir", "datafiles", "File to read from")
	numReads      = flag.Int64("num", 2000000, "Number of reads")
	mode          = flag.Int("mode", 1, "0 = serial, 1 = parallel, 2 = parallel via channel")
	numGoroutines = flag.Int("jobs", 8, "Number of Goroutines")
	profilemode   = flag.String("profile.mode", "", "Enable profiling mode, one of [cpu, mem, mutex, block]")
)

var readSize int64 = 4 << 10

func getIndices(r *rand.Rand, flist []*os.File, maxFileSize int64) (*os.File, int64) {
	fidx := r.Intn(len(flist))
	iidx := r.Int63n(maxFileSize - readSize)
	return flist[fidx], iidx
}

func Serial(fList []*os.File, maxFileSize int64) {
	startT := time.Now()
	var i int64 = 0
	b := make([]byte, int(readSize))

	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	for ; i < *numReads; i++ {
		fd, offset := getIndices(r, fList, maxFileSize)
		_, err := fd.ReadAt(b, offset)
		if err != nil {
			log.Fatalf("Error reading file: %v", err)
		}
		if i%10000 == 0 {
			log.Printf("Finished %v reads in serial", i)
		}
	}
	fmt.Println("Serial: Number of random reads per second: ",
		float64(*numReads)/time.Since(startT).Seconds())
	fmt.Println("Serial: Time Taken: ", time.Since(startT))
}

func Conc2(fList []*os.File, maxFileSize int64) {
	startT := time.Now()
	var wg sync.WaitGroup
	countPerGo := *numReads / int64(*numGoroutines)
	fmt.Printf("Concurrent mode: Reads per goroutine: %d\n", countPerGo)

	for k := 0; k < *numGoroutines; k++ {
		wg.Add(1)
		go func() {
			b := make([]byte, int(readSize))
			r := rand.New(rand.NewSource(time.Now().UnixNano()))
			var i int64
			for ; i < countPerGo; i++ {
				fd, offset := getIndices(r, fList, maxFileSize)
				_, err := fd.ReadAt(b, offset)
				if err != nil {
					log.Fatalf("Error reading file: %v", err)
				}
			}
			wg.Done()
		}()
	}
	wg.Wait()
	fmt.Println("Concurrent 2: Number of random reads per second: ",
		float64(*numReads)/time.Since(startT).Seconds())
	fmt.Println("Concurrent 2: Time Taken: ", time.Since(startT))
}

type req struct {
	fd     *os.File
	offset int64
}

func Conc3(fList []*os.File, maxFileSize int64) {
	ch := make(chan req, 10000)
	go func() {
		var i int64
		rd := rand.New(rand.NewSource(time.Now().UnixNano()))
		for i = 0; i < *numReads; i++ {
			var r req
			r.fd, r.offset = getIndices(rd, fList, maxFileSize)
			ch <- r
		}
		close(ch)
	}()

	startT := time.Now()
	var wg sync.WaitGroup
	for k := 0; k < *numGoroutines; k++ {
		wg.Add(1)
		go func() {
			b := make([]byte, int(readSize))
			for req := range ch {
				_, err := req.fd.ReadAt(b, req.offset)
				if err != nil {
					log.Fatalf("Error reading file: %v", err)
				}
			}
			wg.Done()
		}()
	}
	wg.Wait()
	fmt.Println("Concurrent 3: Number of random reads per second: ",
		float64(*numReads)/time.Since(startT).Seconds())
	fmt.Println("Concurrent 3: Time Taken: ", time.Since(startT))
}

func main() {
	flag.Parse()

	var flist []*os.File
	var maxFileSize int64
	getFile := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			log.Print(err)
			return nil
		}

		if !info.IsDir() {
			f, err := os.Open(path)
			y.AssertTruef(err == nil, "Error opening file: %v", path)
			flist = append(flist, f)
			log.Println("Opened file:", path, "Size:", info.Size()/(1<<20), "MB")
			maxFileSize = info.Size()
		}
		return nil
	}

	err := filepath.Walk(*dir, getFile)
	if err != nil {
		log.Fatalf("%v", err)
	}
	if len(flist) == 0 {
		log.Fatalf("Must have files already created")
	}

	switch *profilemode {
	case "cpu":
		defer profile.Start(profile.CPUProfile).Stop()
	case "mem":
		defer profile.Start(profile.MemProfile).Stop()
	case "mutex":
		defer profile.Start(profile.MutexProfile).Stop()
	case "block":
		defer profile.Start(profile.BlockProfile).Stop()
	}

	switch *mode {
	case 0:
		Serial(flist, maxFileSize)
	case 1:
		Conc2(flist, maxFileSize)
	case 2:
		Conc3(flist, maxFileSize)
	}
}
<|endoftext|>


<commit_before>package actor

import (
	"io/ioutil"
	"log"
	"sync/atomic"
	"time"

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

var nullReceive Receive = func(Context) {}

func init() {
	// discard all logging in tests
	log.SetOutput(ioutil.Discard)
}

type inlineDispatcher struct{}

func (inlineDispatcher) Schedule(runner MailboxRunner) {
	runner()
}

func (inlineDispatcher) Throughput() int {
	return 1
}

const defaultTimeout = 10 * time.Millisecond

type waiter struct {
	c  int32
	ch chan struct{}
}

func newWaiter(c int32) *waiter {
	return &waiter{c: c, ch: make(chan struct{})}
}

func (w *waiter) Add(c int32) {
	v := atomic.AddInt32(&w.c, c)
	if v == 0 {
		w.ch <- struct{}{}
	} else if v < 0 {
		panic("<0")
	}
}

func (w *waiter) Done() {
	w.Add(-1)
}

func (w *waiter) Wait() bool {
	return w.WaitTimeout(defaultTimeout)
}

func (w *waiter) WaitTimeout(t time.Duration) bool {
	select {
	case <-w.ch:
		return true
	case <-time.After(t):
		return false
	}
}

type mockActor struct {
	mock.Mock
}

func (m *mockActor) Receive(context Context) {
	m.Called(context)
}

func newMockActor() *mockActor {
	a := new(mockActor)
	a.On("Receive", mock.Anything).Once() // Started
	return a
}

type mockContext struct {
	mock.Mock
}

func (m *mockContext) Watch(pid *PID) {
	m.Called(pid)
}

func (m *mockContext) Unwatch(pid *PID) {
	m.Called(pid)
}

func (m *mockContext) Message() interface{} {
	args := m.Called()
	return args.Get(0)
}

func (m *mockContext) SetReceiveTimeout(d time.Duration) {
	m.Called(d)
}
func (m *mockContext) ReceiveTimeout() time.Duration {
	args := m.Called()
	return args.Get(0).(time.Duration)
}

func (m *mockContext) Sender() *PID {
	args := m.Called()
	return args.Get(0).(*PID)
}

func (m *mockContext) Become(r Receive) {
	m.Called(r)
}

func (m *mockContext) BecomeStacked(r Receive) {
	m.Called(r)
}

func (m *mockContext) UnbecomeStacked() {
	m.Called()
}

func (m *mockContext) Self() *PID {
	args := m.Called()
	return args.Get(0).(*PID)
}

func (m *mockContext) Parent() *PID {
	args := m.Called()
	return args.Get(0).(*PID)
}

func (m *mockContext) Spawn(p Props) *PID {
	args := m.Called(p)
	return args.Get(0).(*PID)
}

func (m *mockContext) SpawnNamed(p Props, name string) *PID {
	args := m.Called(p, name)
	return args.Get(0).(*PID)
}

func (m *mockContext) Children() []*PID {
	args := m.Called()
	return args.Get(0).([]*PID)
}

func (m *mockContext) Next() {
	m.Called()
}

func (m *mockContext) Receive(i interface{}) {
	m.Called(i)
}

func (m *mockContext) Stash() {
	m.Called()
}

func (m *mockContext) Respond(response interface{}) {
	m.Called(response)
}

func (m *mockContext) Actor() Actor {
	args := m.Called()
	return args.Get(0).(Actor)
}

type mockProcess struct {
	mock.Mock
}

func (m *mockProcess) SendUserMessage(pid *PID, message interface{}, sender *PID) {
	m.Called(pid, message, sender)
}
func (m *mockProcess) SendSystemMessage(pid *PID, message SystemMessage) {
	m.Called(pid, message)
}
func (m *mockProcess) Stop(pid *PID) {
	m.Called(pid)
}
func (m *mockProcess) Watch(pid *PID) {
	m.Called(pid)
}
func (m *mockProcess) Unwatch(pid *PID) {
	m.Called(pid)
}
<commit_msg>dead code<commit_after>package actor

import (
	"io/ioutil"
	"log"
	"time"

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

var nullReceive Receive = func(Context) {}

func init() {
	// discard all logging in tests
	log.SetOutput(ioutil.Discard)
}

type inlineDispatcher struct{}

func (inlineDispatcher) Schedule(runner MailboxRunner) {
	runner()
}

func (inlineDispatcher) Throughput() int {
	return 1
}

type mockActor struct {
	mock.Mock
}

func (m *mockActor) Receive(context Context) {
	m.Called(context)
}

func newMockActor() *mockActor {
	a := new(mockActor)
	a.On("Receive", mock.Anything).Once() // Started
	return a
}

type mockContext struct {
	mock.Mock
}

func (m *mockContext) Watch(pid *PID) {
	m.Called(pid)
}

func (m *mockContext) Unwatch(pid *PID) {
	m.Called(pid)
}

func (m *mockContext) Message() interface{} {
	args := m.Called()
	return args.Get(0)
}

func (m *mockContext) SetReceiveTimeout(d time.Duration) {
	m.Called(d)
}
func (m *mockContext) ReceiveTimeout() time.Duration {
	args := m.Called()
	return args.Get(0).(time.Duration)
}

func (m *mockContext) Sender() *PID {
	args := m.Called()
	return args.Get(0).(*PID)
}

func (m *mockContext) Become(r Receive) {
	m.Called(r)
}

func (m *mockContext) BecomeStacked(r Receive) {
	m.Called(r)
}

func (m *mockContext) UnbecomeStacked() {
	m.Called()
}

func (m *mockContext) Self() *PID {
	args := m.Called()
	return args.Get(0).(*PID)
}

func (m *mockContext) Parent() *PID {
	args := m.Called()
	return args.Get(0).(*PID)
}

func (m *mockContext) Spawn(p Props) *PID {
	args := m.Called(p)
	return args.Get(0).(*PID)
}

func (m *mockContext) SpawnNamed(p Props, name string) *PID {
	args := m.Called(p, name)
	return args.Get(0).(*PID)
}

func (m *mockContext) Children() []*PID {
	args := m.Called()
	return args.Get(0).([]*PID)
}

func (m *mockContext) Next() {
	m.Called()
}

func (m *mockContext) Receive(i interface{}) {
	m.Called(i)
}

func (m *mockContext) Stash() {
	m.Called()
}

func (m *mockContext) Respond(response interface{}) {
	m.Called(response)
}

func (m *mockContext) Actor() Actor {
	args := m.Called()
	return args.Get(0).(Actor)
}

type mockProcess struct {
	mock.Mock
}

func (m *mockProcess) SendUserMessage(pid *PID, message interface{}, sender *PID) {
	m.Called(pid, message, sender)
}
func (m *mockProcess) SendSystemMessage(pid *PID, message SystemMessage) {
	m.Called(pid, message)
}
func (m *mockProcess) Stop(pid *PID) {
	m.Called(pid)
}
func (m *mockProcess) Watch(pid *PID) {
	m.Called(pid)
}
func (m *mockProcess) Unwatch(pid *PID) {
	m.Called(pid)
}
<|endoftext|>