<commit_before>/*
Copyright IBM Corp All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/

package pvtdata

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"path/filepath"
	"time"

	"github.com/hyperledger/fabric/integration/chaincode/kvexecutor"
	"github.com/hyperledger/fabric/integration/nwo"
	"github.com/hyperledger/fabric/integration/nwo/commands"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/tedsuo/ifrit"
)

var _ bool = Describe("Pvtdata dissemination for implicit collection", func() {
	var (
		network       *nwo.Network
		process       ifrit.Process
		orderer       *nwo.Orderer
		testChaincode chaincode
	)

	BeforeEach(func() {
		By("setting up the network")
		network = initThreeOrgsSetup(false)

		By("disabling pvtdata pull/dissemination/reconciliation on all peers except for enabling dissemination on org1 peers")
		for _, p := range network.Peers {
			core := network.ReadPeerConfig(p)
			// disble pvtdata pulling on all peers by setting PullRetryThreshold to 0
			core.Peer.Gossip.PvtData.PullRetryThreshold = 0
			// disable pvtdata reconciliation on all peers
			core.Peer.Gossip.PvtData.ReconciliationEnabled = false
			// set timeout to 10s to prevent test flake
			core.Peer.Gossip.DialTimeout = 10 * time.Second
			core.Peer.Gossip.ConnTimeout = 10 * time.Second
			if p.Organization == "Org1" {
				// enable dissemination on org1 peers
				core.Peer.Gossip.PvtData.ImplicitCollDisseminationPolicy.RequiredPeerCount = 1
				core.Peer.Gossip.PvtData.ImplicitCollDisseminationPolicy.MaxPeerCount = 3
				// set timeout to 10s to prevent test flake
				core.Peer.Gossip.PvtData.PushAckTimeout = 10 * time.Second
			} else {
				// disable dissemination  on non-org1 peers
				core.Peer.Gossip.PvtData.ImplicitCollDisseminationPolicy.RequiredPeerCount = 0
				core.Peer.Gossip.PvtData.ImplicitCollDisseminationPolicy.MaxPeerCount = 0
			}
			network.WritePeerConfig(p, core)
		}

		By("starting the network")
		process, orderer = startNetwork(network)

		By("deploying new lifecycle chaincode")
		testChaincode = chaincode{
			Chaincode: nwo.Chaincode{
				Name:        "kvexecutor",
				Version:     "1.0",
				Path:        components.Build("github.com/hyperledger/fabric/integration/chaincode/kvexecutor/cmd"),
				Lang:        "binary",
				PackageFile: filepath.Join(network.RootDir, "kvexcutor.tar.gz"),
				Label:       "kvexcutor",
				Sequence:    "1",
			},
			isLegacy: false,
		}
		nwo.EnableCapabilities(network, channelID, "Application", "V2_0", orderer, network.Peers...)
		deployChaincode(network, orderer, testChaincode)
	})

	AfterEach(func() {
		testCleanup(network, process)
	})

	It("disseminates pvtdata of implicit collection for the peer's own org but not implicit collection for another org", func() {
		By("writing private data to org1's and org2's implicit collections")
		peer1 := network.Peer("Org1", "peer0")
		peer2 := network.Peer("Org2", "peer0")
		writeInput := []kvexecutor.KVData{
			{Collection: "_implicit_org_Org1MSP", Key: "org1_key1", Value: "org1_value1"},
			{Collection: "_implicit_org_Org2MSP", Key: "org2_key1", Value: "org2_value1"},
		}
		writeImplicitCollection(network, orderer, testChaincode.Name, writeInput, peer1, peer2)

		By("querying org1.peer0 for _implicit_org_Org1MSP collection data, expecting pvtdata")
		readInput1 := []kvexecutor.KVData{{Collection: "_implicit_org_Org1MSP", Key: "org1_key1"}}
		expectedMsg1, err := json.Marshal(writeInput[:1])
		Expect(err).NotTo(HaveOccurred())
		readImplicitCollection(network, network.Peer("Org1", "peer0"), testChaincode.Name, readInput1, string(expectedMsg1), true)

		// org1.peer1 should have _implicit_org_Org1MSP pvtdata because dissemination is enabled on org1 peers
		By("querying org1.peer1 for _implicit_org_Org1MSP collection data, expecting pvtdata")
		readImplicitCollection(network, network.Peer("Org1", "peer1"), testChaincode.Name, readInput1, string(expectedMsg1), true)

		By("querying org2.peer0 for _implicit_org_Org1MSP collection data, expecting error")
		readImplicitCollection(network, network.Peer("Org2", "peer0"), testChaincode.Name, readInput1,
			"private data matching public hash version is not available", false)

		By("querying org2.peer1 for _implicit_org_Org1MSP collection data, expecting error")
		readImplicitCollection(network, network.Peer("Org2", "peer1"), testChaincode.Name, readInput1,
			"private data matching public hash version is not available", false)

		By("querying org2.peer0 for _implicit_org_Org2MSP collection data, expecting pvtdata")
		readInput2 := []kvexecutor.KVData{{Collection: "_implicit_org_Org2MSP", Key: "org2_key1"}}
		expectedMsg2, err := json.Marshal(writeInput[1:])
		Expect(err).NotTo(HaveOccurred())
		readImplicitCollection(network, network.Peer("Org2", "peer0"), testChaincode.Name, readInput2, string(expectedMsg2), true)

		// org2.peer1 should have no _implicit_org_Org2MSP pvtdata because pull/dissemination/reconciliation are disabled on org2 peers
		By("querying org2.peer1 for _implicit_org_Org2MSP collection data, expecting error")
		readImplicitCollection(network, network.Peer("Org2", "peer1"), testChaincode.Name, readInput2,
			"private data matching public hash version is not available", false)

		By("querying org1.peer0 for _implicit_org_Org2MSP collection data, expecting error")
		readImplicitCollection(network, network.Peer("Org1", "peer0"), testChaincode.Name, readInput2,
			"private data matching public hash version is not available", false)

		By("querying org1.peer1 for _implicit_org_Org2MSP collection data, expecting error")
		readImplicitCollection(network, network.Peer("Org1", "peer1"), testChaincode.Name, readInput2,
			"private data matching public hash version is not available", false)
	})
})

func writeImplicitCollection(n *nwo.Network, orderer *nwo.Orderer, chaincodeName string, writeInput []kvexecutor.KVData, peers ...*nwo.Peer) {
	writeInputBytes, err := json.Marshal(writeInput)
	Expect(err).NotTo(HaveOccurred())
	writeInputBase64 := base64.StdEncoding.EncodeToString(writeInputBytes)

	peerAddresses := make([]string, 0)
	for _, peer := range peers {
		peerAddresses = append(peerAddresses, n.PeerAddress(peer, nwo.ListenPort))
	}
	command := commands.ChaincodeInvoke{
		ChannelID:     channelID,
		Orderer:       n.OrdererAddress(orderer, nwo.ListenPort),
		Name:          chaincodeName,
		Ctor:          fmt.Sprintf(`{"Args":["readWriteKVs","%s","%s"]}`, "", writeInputBase64),
		PeerAddresses: peerAddresses,
		WaitForEvent:  true,
	}
	invokeChaincode(n, peers[0], command)
	nwo.WaitUntilEqualLedgerHeight(n, channelID, nwo.GetLedgerHeight(n, peers[0], channelID), n.Peers...)
}

func readImplicitCollection(n *nwo.Network, peer *nwo.Peer, chaincodeName string, readInput []kvexecutor.KVData, expectedMsg string, expectSuccess bool) {
	readInputBytes, err := json.Marshal(readInput)
	Expect(err).NotTo(HaveOccurred())
	readInputBase64 := base64.StdEncoding.EncodeToString(readInputBytes)

	command := commands.ChaincodeQuery{
		ChannelID: channelID,
		Name:      chaincodeName,
		Ctor:      fmt.Sprintf(`{"Args":["readWriteKVs","%s","%s"]}`, readInputBase64, ""),
	}
	queryChaincode(n, peer, command, expectedMsg, expectSuccess)
}
<commit_msg>[FAB-17611] IT: discover all peers before endorsement<commit_after>/*
Copyright IBM Corp All Rights Reserved.

SPDX-License-Identifier: Apache-2.0
*/

package pvtdata

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"path/filepath"
	"time"

	"github.com/hyperledger/fabric/integration/chaincode/kvexecutor"
	"github.com/hyperledger/fabric/integration/nwo"
	"github.com/hyperledger/fabric/integration/nwo/commands"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/tedsuo/ifrit"
)

var _ bool = Describe("Pvtdata dissemination for implicit collection", func() {
	var (
		network       *nwo.Network
		process       ifrit.Process
		orderer       *nwo.Orderer
		testChaincode chaincode
	)

	BeforeEach(func() {
		By("setting up the network")
		network = initThreeOrgsSetup(false)

		By("disabling pvtdata pull/dissemination/reconciliation on all peers except for enabling dissemination on org1 peers")
		for _, p := range network.Peers {
			core := network.ReadPeerConfig(p)
			core.Peer.Gossip.PvtData.PullRetryThreshold = 0
			core.Peer.Gossip.PvtData.ReconciliationEnabled = false
			// set timeout and reconnect interval to prevent test flake
			core.Peer.Gossip.DialTimeout = 5 * time.Second
			core.Peer.Gossip.ConnTimeout = 5 * time.Second
			core.Peer.Gossip.ReconnectInterval = 7 * time.Second
			if p.Organization == "Org1" {
				// enable dissemination on org1 peers
				core.Peer.Gossip.PvtData.ImplicitCollDisseminationPolicy.RequiredPeerCount = 1
				core.Peer.Gossip.PvtData.ImplicitCollDisseminationPolicy.MaxPeerCount = 3
				core.Peer.Gossip.PvtData.PushAckTimeout = 10 * time.Second
			} else {
				// disable dissemination on non-org1 peers
				core.Peer.Gossip.PvtData.ImplicitCollDisseminationPolicy.RequiredPeerCount = 0
				core.Peer.Gossip.PvtData.ImplicitCollDisseminationPolicy.MaxPeerCount = 0
			}
			network.WritePeerConfig(p, core)
		}

		By("starting the network")
		process, orderer = startNetwork(network)

		By("deploying new lifecycle chaincode")
		testChaincode = chaincode{
			Chaincode: nwo.Chaincode{
				Name:        "kvexecutor",
				Version:     "1.0",
				Path:        components.Build("github.com/hyperledger/fabric/integration/chaincode/kvexecutor/cmd"),
				Lang:        "binary",
				PackageFile: filepath.Join(network.RootDir, "kvexcutor.tar.gz"),
				Label:       "kvexcutor",
				Sequence:    "1",
			},
			isLegacy: false,
		}
		nwo.EnableCapabilities(network, channelID, "Application", "V2_0", orderer, network.Peers...)

		By("verifying org1.peer0 discovers all peers to ensure that gossip has been initialized")
		discoverAllPeers(network, network.Peer("Org1", "peer0"), channelID, 3, 5*time.Second)

		By("verifying org1.peer1 discovers all peers to ensure that gossip has been initialized")
		discoverAllPeers(network, network.Peer("Org1", "peer1"), channelID, 3, 5*time.Second)

		By("deploying chaincode to all peers")
		deployChaincode(network, orderer, testChaincode)
	})

	AfterEach(func() {
		testCleanup(network, process)
	})

	It("disseminates pvtdata of implicit collection for the peer's own org but not implicit collection for another org", func() {
		org1peer0 := network.Peer("Org1", "peer0")
		org1peer1 := network.Peer("Org1", "peer1")
		org2peer0 := network.Peer("Org2", "peer0")
		org2peer1 := network.Peer("Org2", "peer1")

		By("writing private data to org1's and org2's implicit collections")
		writeInput := []kvexecutor.KVData{
			{Collection: "_implicit_org_Org1MSP", Key: "org1_key1", Value: "org1_value1"},
			{Collection: "_implicit_org_Org2MSP", Key: "org2_key1", Value: "org2_value1"},
		}
		writeImplicitCollection(network, orderer, testChaincode.Name, writeInput, org1peer0, org2peer0)

		By("querying org1.peer0 for _implicit_org_Org1MSP collection data, expecting pvtdata")
		readInput1 := []kvexecutor.KVData{{Collection: "_implicit_org_Org1MSP", Key: "org1_key1"}}
		expectedMsg1, err := json.Marshal(writeInput[:1])
		Expect(err).NotTo(HaveOccurred())
		readImplicitCollection(network, org1peer0, testChaincode.Name, readInput1, string(expectedMsg1), true)

		// org1.peer1 should have _implicit_org_Org1MSP pvtdata because dissemination is enabled on org1 peers
		By("querying org1.peer1 for _implicit_org_Org1MSP collection data, expecting pvtdata")
		readImplicitCollection(network, org1peer1, testChaincode.Name, readInput1, string(expectedMsg1), true)

		By("querying org2.peer0 for _implicit_org_Org1MSP collection data, expecting error")
		readImplicitCollection(network, org2peer0, testChaincode.Name, readInput1,
			"private data matching public hash version is not available", false)

		By("querying org2.peer1 for _implicit_org_Org1MSP collection data, expecting error")
		readImplicitCollection(network, org2peer1, testChaincode.Name, readInput1,
			"private data matching public hash version is not available", false)

		By("querying org2.peer0 for _implicit_org_Org2MSP collection data, expecting pvtdata")
		readInput2 := []kvexecutor.KVData{{Collection: "_implicit_org_Org2MSP", Key: "org2_key1"}}
		expectedMsg2, err := json.Marshal(writeInput[1:])
		Expect(err).NotTo(HaveOccurred())
		readImplicitCollection(network, org2peer0, testChaincode.Name, readInput2, string(expectedMsg2), true)

		// org2.peer1 should have no _implicit_org_Org2MSP pvtdata because pull/dissemination/reconciliation are disabled on org2 peers
		By("querying org2.peer1 for _implicit_org_Org2MSP collection data, expecting error")
		readImplicitCollection(network, org2peer1, testChaincode.Name, readInput2,
			"private data matching public hash version is not available", false)

		By("querying org1.peer0 for _implicit_org_Org2MSP collection data, expecting error")
		readImplicitCollection(network, org1peer0, testChaincode.Name, readInput2,
			"private data matching public hash version is not available", false)

		By("querying org1.peer1 for _implicit_org_Org2MSP collection data, expecting error")
		readImplicitCollection(network, org1peer1, testChaincode.Name, readInput2,
			"private data matching public hash version is not available", false)
	})
})

func writeImplicitCollection(n *nwo.Network, orderer *nwo.Orderer, chaincodeName string, writeInput []kvexecutor.KVData, peers ...*nwo.Peer) {
	writeInputBytes, err := json.Marshal(writeInput)
	Expect(err).NotTo(HaveOccurred())
	writeInputBase64 := base64.StdEncoding.EncodeToString(writeInputBytes)

	peerAddresses := make([]string, 0)
	for _, peer := range peers {
		peerAddresses = append(peerAddresses, n.PeerAddress(peer, nwo.ListenPort))
	}
	command := commands.ChaincodeInvoke{
		ChannelID:     channelID,
		Orderer:       n.OrdererAddress(orderer, nwo.ListenPort),
		Name:          chaincodeName,
		Ctor:          fmt.Sprintf(`{"Args":["readWriteKVs","%s","%s"]}`, "", writeInputBase64),
		PeerAddresses: peerAddresses,
		WaitForEvent:  true,
	}
	invokeChaincode(n, peers[0], command)
	nwo.WaitUntilEqualLedgerHeight(n, channelID, nwo.GetLedgerHeight(n, peers[0], channelID), n.Peers...)
}

func readImplicitCollection(n *nwo.Network, peer *nwo.Peer, chaincodeName string, readInput []kvexecutor.KVData, expectedMsg string, expectSuccess bool) {
	readInputBytes, err := json.Marshal(readInput)
	Expect(err).NotTo(HaveOccurred())
	readInputBase64 := base64.StdEncoding.EncodeToString(readInputBytes)

	command := commands.ChaincodeQuery{
		ChannelID: channelID,
		Name:      chaincodeName,
		Ctor:      fmt.Sprintf(`{"Args":["readWriteKVs","%s","%s"]}`, readInputBase64, ""),
	}
	queryChaincode(n, peer, command, expectedMsg, expectSuccess)
}

func discoverAllPeers(n *nwo.Network, peer *nwo.Peer, channelID string, retries int, retryInterval time.Duration) {
	var discoveredPeers []nwo.DiscoveredPeer
	numPeers := len(n.Peers)
	for i := 0; i < retries; i++ {
		discoveredPeers = nwo.DiscoverPeers(n, peer, "User1", channelID)()
		if len(discoveredPeers) == numPeers || i == retries-1 {
			break
		}
		time.Sleep(retryInterval)
	}
	Expect(discoveredPeers).To(HaveLen(numPeers))
}
<|endoftext|>


<commit_before>// +build linux

package devmapper // import "github.com/docker/docker/daemon/graphdriver/devmapper"

import (
	"fmt"
	"os"
	"os/exec"
	"syscall"
	"testing"
	"time"

	"github.com/docker/docker/daemon/graphdriver"
	"github.com/docker/docker/daemon/graphdriver/graphtest"
	"github.com/docker/docker/pkg/parsers/kernel"
	"golang.org/x/sys/unix"
)

func init() {
	// Reduce the size of the base fs and loopback for the tests
	defaultDataLoopbackSize = 300 * 1024 * 1024
	defaultMetaDataLoopbackSize = 200 * 1024 * 1024
	defaultBaseFsSize = 300 * 1024 * 1024
	defaultUdevSyncOverride = true
	if err := initLoopbacks(); err != nil {
		panic(err)
	}
}

// initLoopbacks ensures that the loopback devices are properly created within
// the system running the device mapper tests.
func initLoopbacks() error {
	statT, err := getBaseLoopStats()
	if err != nil {
		return err
	}
	// create at least 8 loopback files, ya, that is a good number
	for i := 0; i < 8; i++ {
		loopPath := fmt.Sprintf("/dev/loop%d", i)
		// only create new loopback files if they don't exist
		if _, err := os.Stat(loopPath); err != nil {
			if mkerr := syscall.Mknod(loopPath,
				uint32(statT.Mode|syscall.S_IFBLK), int((7<<8)|(i&0xff)|((i&0xfff00)<<12))); mkerr != nil { // nolint: unconvert
				return mkerr
			}
			os.Chown(loopPath, int(statT.Uid), int(statT.Gid))
		}
	}
	return nil
}

// getBaseLoopStats inspects /dev/loop0 to collect uid,gid, and mode for the
// loop0 device on the system.  If it does not exist we assume 0,0,0660 for the
// stat data
func getBaseLoopStats() (*syscall.Stat_t, error) {
	loop0, err := os.Stat("/dev/loop0")
	if err != nil {
		if os.IsNotExist(err) {
			return &syscall.Stat_t{
				Uid:  0,
				Gid:  0,
				Mode: 0660,
			}, nil
		}
		return nil, err
	}
	return loop0.Sys().(*syscall.Stat_t), nil
}

// This avoids creating a new driver for each test if all tests are run
// Make sure to put new tests between TestDevmapperSetup and TestDevmapperTeardown
func TestDevmapperSetup(t *testing.T) {
	graphtest.GetDriver(t, "devicemapper")
}

func TestDevmapperCreateEmpty(t *testing.T) {
	graphtest.DriverTestCreateEmpty(t, "devicemapper")
}

func TestDevmapperCreateBase(t *testing.T) {
	graphtest.DriverTestCreateBase(t, "devicemapper")
}

func TestDevmapperCreateSnap(t *testing.T) {
	graphtest.DriverTestCreateSnap(t, "devicemapper")
}

func TestDevmapperTeardown(t *testing.T) {
	graphtest.PutDriver(t)
}

func TestDevmapperReduceLoopBackSize(t *testing.T) {
	tenMB := int64(10 * 1024 * 1024)
	testChangeLoopBackSize(t, -tenMB, defaultDataLoopbackSize, defaultMetaDataLoopbackSize)
}

func TestDevmapperIncreaseLoopBackSize(t *testing.T) {
	tenMB := int64(10 * 1024 * 1024)
	testChangeLoopBackSize(t, tenMB, defaultDataLoopbackSize+tenMB, defaultMetaDataLoopbackSize+tenMB)
}

func testChangeLoopBackSize(t *testing.T, delta, expectDataSize, expectMetaDataSize int64) {
	driver := graphtest.GetDriver(t, "devicemapper").(*graphtest.Driver).Driver.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver)
	defer graphtest.PutDriver(t)
	// make sure data or metadata loopback size are the default size
	if s := driver.DeviceSet.Status(); s.Data.Total != uint64(defaultDataLoopbackSize) || s.Metadata.Total != uint64(defaultMetaDataLoopbackSize) {
		t.Fatal("data or metadata loop back size is incorrect")
	}
	if err := driver.Cleanup(); err != nil {
		t.Fatal(err)
	}
	//Reload
	d, err := Init(driver.home, []string{
		fmt.Sprintf("dm.loopdatasize=%d", defaultDataLoopbackSize+delta),
		fmt.Sprintf("dm.loopmetadatasize=%d", defaultMetaDataLoopbackSize+delta),
	}, nil, nil)
	if err != nil {
		t.Fatalf("error creating devicemapper driver: %v", err)
	}
	driver = d.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver)
	if s := driver.DeviceSet.Status(); s.Data.Total != uint64(expectDataSize) || s.Metadata.Total != uint64(expectMetaDataSize) {
		t.Fatal("data or metadata loop back size is incorrect")
	}
	if err := driver.Cleanup(); err != nil {
		t.Fatal(err)
	}
}

// Make sure devices.Lock() has been release upon return from cleanupDeletedDevices() function
func TestDevmapperLockReleasedDeviceDeletion(t *testing.T) {
	driver := graphtest.GetDriver(t, "devicemapper").(*graphtest.Driver).Driver.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver)
	defer graphtest.PutDriver(t)

	// Call cleanupDeletedDevices() and after the call take and release
	// DeviceSet Lock. If lock has not been released, this will hang.
	driver.DeviceSet.cleanupDeletedDevices()

	doneChan := make(chan bool)

	go func() {
		driver.DeviceSet.Lock()
		defer driver.DeviceSet.Unlock()
		doneChan <- true
	}()

	select {
	case <-time.After(time.Second * 5):
		// Timer expired. That means lock was not released upon
		// function return and we are deadlocked. Release lock
		// here so that cleanup could succeed and fail the test.
		driver.DeviceSet.Unlock()
		t.Fatal("Could not acquire devices lock after call to cleanupDeletedDevices()")
	case <-doneChan:
	}
}

// Ensure that mounts aren't leakedriver. It's non-trivial for us to test the full
// reproducer of #34573 in a unit test, but we can at least make sure that a
// simple command run in a new namespace doesn't break things horribly.
func TestDevmapperMountLeaks(t *testing.T) {
	if !kernel.CheckKernelVersion(3, 18, 0) {
		t.Skipf("kernel version <3.18.0 and so is missing torvalds/linux@8ed936b5671bfb33d89bc60bdcc7cf0470ba52fe.")
	}

	driver := graphtest.GetDriver(t, "devicemapper", "dm.use_deferred_removal=false", "dm.use_deferred_deletion=false").(*graphtest.Driver).Driver.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver)
	defer graphtest.PutDriver(t)

	// We need to create a new (dummy) device.
	if err := driver.Create("some-layer", "", nil); err != nil {
		t.Fatalf("setting up some-layer: %v", err)
	}

	// Mount the device.
	_, err := driver.Get("some-layer", "")
	if err != nil {
		t.Fatalf("mounting some-layer: %v", err)
	}

	// Create a new subprocess which will inherit our mountpoint, then
	// intentionally leak it and stick around. We can't do this entirely within
	// Go because forking and namespaces in Go are really not handled well at
	// all.
	cmd := exec.Cmd{
		Path: "/bin/sh",
		Args: []string{
			"/bin/sh", "-c",
			"mount --make-rprivate / && sleep 1000s",
		},
		SysProcAttr: &syscall.SysProcAttr{
			Unshareflags: syscall.CLONE_NEWNS,
		},
	}
	if err := cmd.Start(); err != nil {
		t.Fatalf("starting sub-command: %v", err)
	}
	defer func() {
		unix.Kill(cmd.Process.Pid, unix.SIGKILL)
		cmd.Wait()
	}()

	// Now try to "drop" the device.
	if err := driver.Put("some-layer"); err != nil {
		t.Fatalf("unmounting some-layer: %v", err)
	}
}
<commit_msg>devmapper: fix unit test<commit_after>// +build linux

package devmapper // import "github.com/docker/docker/daemon/graphdriver/devmapper"

import (
	"fmt"
	"os"
	"os/exec"
	"syscall"
	"testing"
	"time"

	"github.com/docker/docker/daemon/graphdriver"
	"github.com/docker/docker/daemon/graphdriver/graphtest"
	"github.com/docker/docker/pkg/parsers/kernel"
	"golang.org/x/sys/unix"
)

func init() {
	// Reduce the size of the base fs and loopback for the tests
	defaultDataLoopbackSize = 300 * 1024 * 1024
	defaultMetaDataLoopbackSize = 200 * 1024 * 1024
	defaultBaseFsSize = 300 * 1024 * 1024
	defaultUdevSyncOverride = true
	if err := initLoopbacks(); err != nil {
		panic(err)
	}
}

// initLoopbacks ensures that the loopback devices are properly created within
// the system running the device mapper tests.
func initLoopbacks() error {
	statT, err := getBaseLoopStats()
	if err != nil {
		return err
	}
	// create at least 128 loopback files, since a few first ones
	// might be already in use by the host OS
	for i := 0; i < 128; i++ {
		loopPath := fmt.Sprintf("/dev/loop%d", i)
		// only create new loopback files if they don't exist
		if _, err := os.Stat(loopPath); err != nil {
			if mkerr := syscall.Mknod(loopPath,
				uint32(statT.Mode|syscall.S_IFBLK), int((7<<8)|(i&0xff)|((i&0xfff00)<<12))); mkerr != nil { // nolint: unconvert
				return mkerr
			}
			os.Chown(loopPath, int(statT.Uid), int(statT.Gid))
		}
	}
	return nil
}

// getBaseLoopStats inspects /dev/loop0 to collect uid,gid, and mode for the
// loop0 device on the system.  If it does not exist we assume 0,0,0660 for the
// stat data
func getBaseLoopStats() (*syscall.Stat_t, error) {
	loop0, err := os.Stat("/dev/loop0")
	if err != nil {
		if os.IsNotExist(err) {
			return &syscall.Stat_t{
				Uid:  0,
				Gid:  0,
				Mode: 0660,
			}, nil
		}
		return nil, err
	}
	return loop0.Sys().(*syscall.Stat_t), nil
}

// This avoids creating a new driver for each test if all tests are run
// Make sure to put new tests between TestDevmapperSetup and TestDevmapperTeardown
func TestDevmapperSetup(t *testing.T) {
	graphtest.GetDriver(t, "devicemapper")
}

func TestDevmapperCreateEmpty(t *testing.T) {
	graphtest.DriverTestCreateEmpty(t, "devicemapper")
}

func TestDevmapperCreateBase(t *testing.T) {
	graphtest.DriverTestCreateBase(t, "devicemapper")
}

func TestDevmapperCreateSnap(t *testing.T) {
	graphtest.DriverTestCreateSnap(t, "devicemapper")
}

func TestDevmapperTeardown(t *testing.T) {
	graphtest.PutDriver(t)
}

func TestDevmapperReduceLoopBackSize(t *testing.T) {
	tenMB := int64(10 * 1024 * 1024)
	testChangeLoopBackSize(t, -tenMB, defaultDataLoopbackSize, defaultMetaDataLoopbackSize)
}

func TestDevmapperIncreaseLoopBackSize(t *testing.T) {
	tenMB := int64(10 * 1024 * 1024)
	testChangeLoopBackSize(t, tenMB, defaultDataLoopbackSize+tenMB, defaultMetaDataLoopbackSize+tenMB)
}

func testChangeLoopBackSize(t *testing.T, delta, expectDataSize, expectMetaDataSize int64) {
	driver := graphtest.GetDriver(t, "devicemapper").(*graphtest.Driver).Driver.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver)
	defer graphtest.PutDriver(t)
	// make sure data or metadata loopback size are the default size
	if s := driver.DeviceSet.Status(); s.Data.Total != uint64(defaultDataLoopbackSize) || s.Metadata.Total != uint64(defaultMetaDataLoopbackSize) {
		t.Fatal("data or metadata loop back size is incorrect")
	}
	if err := driver.Cleanup(); err != nil {
		t.Fatal(err)
	}
	//Reload
	d, err := Init(driver.home, []string{
		fmt.Sprintf("dm.loopdatasize=%d", defaultDataLoopbackSize+delta),
		fmt.Sprintf("dm.loopmetadatasize=%d", defaultMetaDataLoopbackSize+delta),
	}, nil, nil)
	if err != nil {
		t.Fatalf("error creating devicemapper driver: %v", err)
	}
	driver = d.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver)
	if s := driver.DeviceSet.Status(); s.Data.Total != uint64(expectDataSize) || s.Metadata.Total != uint64(expectMetaDataSize) {
		t.Fatal("data or metadata loop back size is incorrect")
	}
	if err := driver.Cleanup(); err != nil {
		t.Fatal(err)
	}
}

// Make sure devices.Lock() has been release upon return from cleanupDeletedDevices() function
func TestDevmapperLockReleasedDeviceDeletion(t *testing.T) {
	driver := graphtest.GetDriver(t, "devicemapper").(*graphtest.Driver).Driver.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver)
	defer graphtest.PutDriver(t)

	// Call cleanupDeletedDevices() and after the call take and release
	// DeviceSet Lock. If lock has not been released, this will hang.
	driver.DeviceSet.cleanupDeletedDevices()

	doneChan := make(chan bool)

	go func() {
		driver.DeviceSet.Lock()
		defer driver.DeviceSet.Unlock()
		doneChan <- true
	}()

	select {
	case <-time.After(time.Second * 5):
		// Timer expired. That means lock was not released upon
		// function return and we are deadlocked. Release lock
		// here so that cleanup could succeed and fail the test.
		driver.DeviceSet.Unlock()
		t.Fatal("Could not acquire devices lock after call to cleanupDeletedDevices()")
	case <-doneChan:
	}
}

// Ensure that mounts aren't leakedriver. It's non-trivial for us to test the full
// reproducer of #34573 in a unit test, but we can at least make sure that a
// simple command run in a new namespace doesn't break things horribly.
func TestDevmapperMountLeaks(t *testing.T) {
	if !kernel.CheckKernelVersion(3, 18, 0) {
		t.Skipf("kernel version <3.18.0 and so is missing torvalds/linux@8ed936b5671bfb33d89bc60bdcc7cf0470ba52fe.")
	}

	driver := graphtest.GetDriver(t, "devicemapper", "dm.use_deferred_removal=false", "dm.use_deferred_deletion=false").(*graphtest.Driver).Driver.(*graphdriver.NaiveDiffDriver).ProtoDriver.(*Driver)
	defer graphtest.PutDriver(t)

	// We need to create a new (dummy) device.
	if err := driver.Create("some-layer", "", nil); err != nil {
		t.Fatalf("setting up some-layer: %v", err)
	}

	// Mount the device.
	_, err := driver.Get("some-layer", "")
	if err != nil {
		t.Fatalf("mounting some-layer: %v", err)
	}

	// Create a new subprocess which will inherit our mountpoint, then
	// intentionally leak it and stick around. We can't do this entirely within
	// Go because forking and namespaces in Go are really not handled well at
	// all.
	cmd := exec.Cmd{
		Path: "/bin/sh",
		Args: []string{
			"/bin/sh", "-c",
			"mount --make-rprivate / && sleep 1000s",
		},
		SysProcAttr: &syscall.SysProcAttr{
			Unshareflags: syscall.CLONE_NEWNS,
		},
	}
	if err := cmd.Start(); err != nil {
		t.Fatalf("starting sub-command: %v", err)
	}
	defer func() {
		unix.Kill(cmd.Process.Pid, unix.SIGKILL)
		cmd.Wait()
	}()

	// Now try to "drop" the device.
	if err := driver.Put("some-layer"); err != nil {
		t.Fatalf("unmounting some-layer: %v", err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/csv"
	"flag"
	"log"
	"os"

	"github.com/cumulodev/nimbusec"
)

func main() {
	domain := flag.String("domain", "ALL", "define specific domain or ALL to lookup over all domains and resources")
	url := flag.String("url", nimbusec.DefaultAPI, "url to nimbusec API")
	key := flag.String("key", "", "nimbusec API key")
	secret := flag.String("secret", "", "nimbusec API secret")
	humanReadable := flag.Bool("humanreadable", true, "default true: return human readable cms name; set false for internal cpeID")
	outdated := flag.Bool("outdated", true, "default true: show only domains with outdated cms versions; false: show all")
	flag.Parse()

	api, err := nimbusec.NewAPI(*url, *key, *secret)
	if err != nil {
		log.Fatal(err)
	}

	// find domains
	var domains []nimbusec.Domain
	if *domain != "ALL" {
		obj, err := api.GetDomainByName(*domain)
		if err != nil {
			log.Fatal(err)
		}

		domains = []nimbusec.Domain{*obj}
	} else {
		domains, err = api.FindDomains(nimbusec.EmptyFilter)
		if err != nil {
			log.Fatal(err)
		}
	}

	writer := csv.NewWriter(os.Stdout)
	for _, domain := range domains {
		cms, err := api.GetDomainCMS(domain.Id)
		if err != nil {
			log.Fatal(err)
		}

		for _, elem := range cms {
			if !*outdated || elem.LatestStable != "" {
				currcms := elem.CMS
				latest := elem.LatestStable
				if *humanReadable {
					currcms, err = api.GetCMSName(elem.CMS)
					if err != nil {
						log.Fatal(err)
					}
					if elem.LatestStable != "" {
						latest, err = api.GetCMSName(elem.LatestStable)
						if err != nil {
							log.Fatal(err)
						}
					}
				}
				writer.Write([]string{domain.Name, currcms, latest})
				writer.Flush()
			}
		}
	}

}
<commit_msg>removed broken tool<commit_after><|endoftext|>


<commit_before>package gcs

import (
	"fmt"
	"os"
	"strings"
	"testing"

	"github.com/hashicorp/terraform/backend"
	"github.com/hashicorp/terraform/state/remote"
)

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

	cases := []struct {
		prefix           string
		defaultStateFile string
		name             string
		wantStateFile    string
		wantLockFile     string
	}{
		{"state", "", "default", "state/default.tfstate", "state/default.tflock"},
		{"state", "", "test", "state/test.tfstate", "state/test.tflock"},
		{"state", "legacy.tfstate", "default", "legacy.tfstate", "legacy.tflock"},
		{"state", "legacy.tfstate", "test", "state/test.tfstate", "state/test.tflock"},
		{"state", "legacy.state", "default", "legacy.state", "legacy.state.tflock"},
		{"state", "legacy.state", "test", "state/test.tfstate", "state/test.tflock"},
	}
	for _, c := range cases {
		b := &gcsBackend{
			prefix:           c.prefix,
			defaultStateFile: c.defaultStateFile,
		}

		if got := b.stateFile(c.name); got != c.wantStateFile {
			t.Errorf("stateFile(%q) = %q, want %q", c.name, got, c.wantStateFile)
		}

		if got := b.lockFile(c.name); got != c.wantLockFile {
			t.Errorf("lockFile(%q) = %q, want %q", c.name, got, c.wantLockFile)
		}
	}
}

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

	be := testBackend(t)

	ss, err := be.State(backend.DefaultStateName)
	if err != nil {
		t.Fatalf("be.State(%q) = %v", backend.DefaultStateName, err)
	}

	rs, ok := ss.(*remote.State)
	if !ok {
		t.Fatalf("be.State(): got a %T, want a *remote.State", ss)
	}

	remote.TestClient(t, rs.Client)

	cleanBackend(t, be)
}

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

	be := testBackend(t)

	remoteClient := func() (remote.Client, error) {
		ss, err := be.State(backend.DefaultStateName)
		if err != nil {
			return nil, err
		}

		rs, ok := ss.(*remote.State)
		if !ok {
			return nil, fmt.Errorf("be.State(): got a %T, want a *remote.State", ss)
		}

		return rs.Client, nil
	}

	c0, err := remoteClient()
	if err != nil {
		t.Fatalf("remoteClient(0) = %v", err)
	}
	c1, err := remoteClient()
	if err != nil {
		t.Fatalf("remoteClient(1) = %v", err)
	}

	remote.TestRemoteLocks(t, c0, c1)

	cleanBackend(t, be)
}

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

	be0 := testBackend(t)
	be1 := testBackend(t)

	// clean up all states left behind by previous runs --
	// backend.TestBackend() will complain about any non-default states.
	cleanBackend(t, be0)

	backend.TestBackend(t, be0, be1)

	cleanBackend(t, be0)
}

// testBackend returns a new GCS backend.
// This creates a bucket in GCS and populates it. Since this may incur costs,
// it will only run if the GOOGLE_PROJECT environment variable is set.
func testBackend(t *testing.T) backend.Backend {
	t.Helper()

	projectID := os.Getenv("GOOGLE_PROJECT")
	if projectID == "" {
		t.Skip("skipping; set GOOGLE_PROJECT to activate")
	}

	config := map[string]interface{}{
		"project": projectID,
		"bucket":  strings.ToLower(t.Name()),
		"prefix":  "",
	}

	if creds := os.Getenv("GOOGLE_CREDENTIALS"); creds != "" {
		config["credentials"] = creds
		t.Logf("using credentials from %q", creds)
	} else {
		t.Log("using default credentials; set GOOGLE_CREDENTIALS for custom credentials")
	}

	return backend.TestBackendConfig(t, New(), config)
}

// cleanBackend deletes all states from be except the default state.
func cleanBackend(t *testing.T, be backend.Backend) {
	t.Helper()

	states, err := be.States()
	if err != nil {
		t.Fatalf("be.States() = %v; manual clean-up may be required", err)
	}
	for _, st := range states {
		if st == backend.DefaultStateName {
			continue
		}
		if err := be.DeleteState(st); err != nil {
			t.Fatalf("be.DeleteState(%q) = %v; manual clean-up may be required", st, err)
		}
	}
}
<commit_msg>backend/remote-state/gcs: Require TF_ACC for tests using the network.<commit_after>package gcs

import (
	"fmt"
	"os"
	"strings"
	"testing"

	"github.com/hashicorp/terraform/backend"
	"github.com/hashicorp/terraform/state/remote"
)

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

	cases := []struct {
		prefix           string
		defaultStateFile string
		name             string
		wantStateFile    string
		wantLockFile     string
	}{
		{"state", "", "default", "state/default.tfstate", "state/default.tflock"},
		{"state", "", "test", "state/test.tfstate", "state/test.tflock"},
		{"state", "legacy.tfstate", "default", "legacy.tfstate", "legacy.tflock"},
		{"state", "legacy.tfstate", "test", "state/test.tfstate", "state/test.tflock"},
		{"state", "legacy.state", "default", "legacy.state", "legacy.state.tflock"},
		{"state", "legacy.state", "test", "state/test.tfstate", "state/test.tflock"},
	}
	for _, c := range cases {
		b := &gcsBackend{
			prefix:           c.prefix,
			defaultStateFile: c.defaultStateFile,
		}

		if got := b.stateFile(c.name); got != c.wantStateFile {
			t.Errorf("stateFile(%q) = %q, want %q", c.name, got, c.wantStateFile)
		}

		if got := b.lockFile(c.name); got != c.wantLockFile {
			t.Errorf("lockFile(%q) = %q, want %q", c.name, got, c.wantLockFile)
		}
	}
}

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

	be := testBackend(t)

	ss, err := be.State(backend.DefaultStateName)
	if err != nil {
		t.Fatalf("be.State(%q) = %v", backend.DefaultStateName, err)
	}

	rs, ok := ss.(*remote.State)
	if !ok {
		t.Fatalf("be.State(): got a %T, want a *remote.State", ss)
	}

	remote.TestClient(t, rs.Client)

	cleanBackend(t, be)
}

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

	be := testBackend(t)

	remoteClient := func() (remote.Client, error) {
		ss, err := be.State(backend.DefaultStateName)
		if err != nil {
			return nil, err
		}

		rs, ok := ss.(*remote.State)
		if !ok {
			return nil, fmt.Errorf("be.State(): got a %T, want a *remote.State", ss)
		}

		return rs.Client, nil
	}

	c0, err := remoteClient()
	if err != nil {
		t.Fatalf("remoteClient(0) = %v", err)
	}
	c1, err := remoteClient()
	if err != nil {
		t.Fatalf("remoteClient(1) = %v", err)
	}

	remote.TestRemoteLocks(t, c0, c1)

	cleanBackend(t, be)
}

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

	be0 := testBackend(t)
	be1 := testBackend(t)

	// clean up all states left behind by previous runs --
	// backend.TestBackend() will complain about any non-default states.
	cleanBackend(t, be0)

	backend.TestBackend(t, be0, be1)

	cleanBackend(t, be0)
}

// testBackend returns a new GCS backend.
func testBackend(t *testing.T) backend.Backend {
	t.Helper()

	projectID := os.Getenv("GOOGLE_PROJECT")
	if projectID == "" || os.Getenv("TF_ACC") == "" {
		t.Skip("This test creates a bucket in GCS and populates it. " +
			"Since this may incur costs, it will only run if " +
			"the TF_ACC and GOOGLE_PROJECT environment variables are set.")
	}

	config := map[string]interface{}{
		"project": projectID,
		"bucket":  strings.ToLower(t.Name()),
		"prefix":  "",
	}

	if creds := os.Getenv("GOOGLE_CREDENTIALS"); creds != "" {
		config["credentials"] = creds
		t.Logf("using credentials from %q", creds)
	} else {
		t.Log("using default credentials; set GOOGLE_CREDENTIALS for custom credentials")
	}

	return backend.TestBackendConfig(t, New(), config)
}

// cleanBackend deletes all states from be except the default state.
func cleanBackend(t *testing.T, be backend.Backend) {
	t.Helper()

	states, err := be.States()
	if err != nil {
		t.Fatalf("be.States() = %v; manual clean-up may be required", err)
	}
	for _, st := range states {
		if st == backend.DefaultStateName {
			continue
		}
		if err := be.DeleteState(st); err != nil {
			t.Fatalf("be.DeleteState(%q) = %v; manual clean-up may be required", st, err)
		}
	}
}
<|endoftext|>


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

// +build !ebitengl

package glfw

// #cgo CFLAGS: -x objective-c
// #cgo LDFLAGS: -framework Foundation
//
// #import <Foundation/Foundation.h>
//
// static int getMacOSMinorVersion() {
//   NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
//   return (int)version.minorVersion;
// }
import "C"

import (
	"github.com/hajimehoshi/ebiten/v2/internal/driver"
	"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/metal"
	"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/metal/mtl"
	"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl"
)

var graphics driver.Graphics

func supportsMetal() bool {
	// On old mac devices like iMac 2011, Metal is not supported (#779).
	if _, err := mtl.CreateSystemDefaultDevice(); err != nil {
		return false
	}
	// On macOS 10.11 El Capitan, there is a rendering issue on Metal (#781).
	// Use the OpenGL in macOS 10.11 or older.
	if C.getMacOSMinorVersion() <= 11 {
		return false
	}
	return true
}

func init() {
	if supportsMetal() {
		graphics = metal.Get()
		return
	}
	graphics = opengl.Get()
}

func (*UserInterface) Graphics() driver.Graphics {
	return graphics
}
<commit_msg>uidriver/glfw: Bug fix: OpenGL was adopted unexpectedly on macOS Big Sur<commit_after>// Copyright 2018 The Ebiten Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// +build !ebitengl

package glfw

// #cgo CFLAGS: -x objective-c
// #cgo LDFLAGS: -framework Foundation
//
// #import <Foundation/Foundation.h>
//
// static int getMacOSMajorVersion() {
//   NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
//   return (int)version.majorVersion;
// }
//
// static int getMacOSMinorVersion() {
//   NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
//   return (int)version.minorVersion;
// }
import "C"

import (
	"github.com/hajimehoshi/ebiten/v2/internal/driver"
	"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/metal"
	"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/metal/mtl"
	"github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver/opengl"
)

var graphics driver.Graphics

func supportsMetal() bool {
	// On old mac devices like iMac 2011, Metal is not supported (#779).
	if _, err := mtl.CreateSystemDefaultDevice(); err != nil {
		return false
	}

	// On macOS 10.11 El Capitan, there is a rendering issue on Metal (#781).
	// Use the OpenGL in macOS 10.11 or older.
	if C.getMacOSMajorVersion() <= 10 && C.getMacOSMinorVersion() <= 11 {
		return false
	}
	return true
}

func init() {
	if supportsMetal() {
		graphics = metal.Get()
		return
	}
	graphics = opengl.Get()
}

func (*UserInterface) Graphics() driver.Graphics {
	return graphics
}
<|endoftext|>


<commit_before>// Copyright © 2017 Circonus, Inc. <support@circonus.com>
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//

package server

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/circonus-labs/circonus-agent/internal/config"
	"github.com/circonus-labs/circonus-agent/internal/plugins"
	"github.com/circonus-labs/circonus-agent/internal/server/receiver"
	cgm "github.com/circonus-labs/circonus-gometrics"
	"github.com/rs/zerolog/log"
	"github.com/spf13/viper"
)

// run handles requests to execute plugins and return metrics emitted
// handles /, /run, or /run/plugin_name
func (s *Server) run(w http.ResponseWriter, r *http.Request) {
	plugin := ""

	if strings.HasPrefix(r.URL.Path, "/run/") { // run specific plugin
		plugin = strings.Replace(r.URL.Path, "/run/", "", -1)
		if plugin != "" {
			if !s.plugins.IsInternal(plugin) && !s.plugins.IsValid(plugin) {
				s.logger.Warn().
					Str("plugin", plugin).
					Msg("Unknown plugin requested")
				http.NotFound(w, r)
				return
			}
		}
	}

	lastMeticsmu.Lock()
	defer lastMeticsmu.Unlock()

	metrics := &map[string]interface{}{}

	if plugin == "" || !s.plugins.IsInternal(plugin) {
		// NOTE: errors are ignored from plugins.Run
		//       1. errors are already logged by Run
		//       2. do not expose execution state to callers
		s.plugins.Run(plugin)
		metrics = s.plugins.Flush(plugin)
	}

	if plugin == "" || plugin == "write" {
		receiverMetrics := receiver.Flush()
		for metricGroup, value := range *receiverMetrics {
			(*metrics)[metricGroup] = value
		}
	}

	if plugin == "" || plugin == "statsd" {
		if s.statsdSvr != nil {
			statsdMetrics := s.statsdSvr.Flush()
			if statsdMetrics != nil {
				(*metrics)[viper.GetString(config.KeyStatsdHostCategory)] = *statsdMetrics
			}
		}
	}

	lastMetrics.metrics = metrics
	lastMetrics.ts = time.Now()

	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(metrics); err != nil {
		s.logger.Error().
			Err(err).
			Msg("Writing metrics to response")
	}
}

// promOutput returns the last metrics in prom format
func (s *Server) promOutput(w http.ResponseWriter, r *http.Request) {
	if lastMetrics.metrics == nil {
		w.WriteHeader(http.StatusNoContent)
		return
	}

	ms := lastMetrics.ts.UnixNano() / int64(time.Millisecond)

	for group, data := range *lastMetrics.metrics {
		metricsToPromFormat(w, group, ms, data)
	}
}

func metricsToPromFormat(w http.ResponseWriter, prefix string, ts int64, val interface{}) {
	switch t := val.(type) {
	case cgm.Metric:
		metric := val.(cgm.Metric)
		s := fmt.Sprintf("%v", metric.Value)
		switch metric.Type {
		case "i":
			fallthrough
		case "I":
			fallthrough
		case "l":
			fallthrough
		case "L":
			v, err := strconv.ParseInt(s, 10, 64)
			if err != nil {
				log.Error().Err(err).Msg("conv int64")
				return
			}
			w.Write([]byte(fmt.Sprintf("%s %d %d\n", prefix, v, ts)))
		case "n":
			if strings.Contains(s, "[H[") {
				w.Write([]byte(fmt.Sprintf("#HISTOGRAM %s %s %d\n", prefix, s, ts)))
			} else {
				v, err := strconv.ParseFloat(s, 64)
				if err != nil {
					log.Error().Err(err).Msg("conv float64")
					return
				}
				w.Write([]byte(fmt.Sprintf("%s %f %d\n", prefix, v, ts)))
			}
		default:
			w.Write([]byte(fmt.Sprintf("#TEXT %s %s %d\n", prefix, s, ts)))
		}
	case cgm.Metrics:
		metrics, ok := val.(cgm.Metrics)
		if !ok {
			st := fmt.Sprintf("%T", t)
			log.Warn().Interface("val", val).Str("target_type", st).Str("pkg", "prom export").Msg("unable to coerce")
			return
		}
		for pfx, metric := range metrics {
			name := prefix
			if pfx != "" {
				name += "`" + pfx
			}
			metricsToPromFormat(w, name, ts, metric)
		}
	case *plugins.Metrics:
		metrics, ok := val.(*plugins.Metrics)
		if !ok {
			st := fmt.Sprintf("%T", t)
			log.Warn().Interface("val", val).Str("target_type", st).Str("pkg", "prom export").Msg("unable to coerce")
			return
		}
		for pfx, metric := range *metrics {
			name := prefix
			if pfx != "" {
				name += "`" + pfx
			}
			metricsToPromFormat(w, name, ts, cgm.Metric(metric))
		}
	default:
		w.Write([]byte(fmt.Sprintf("#UNHANDLED TYPE(%T) %v = %#v\n", t, prefix, val)))
	}
}

// inventory returns the current, active plugin inventory
func (s *Server) inventory(w http.ResponseWriter, r *http.Request) {
	inventory := s.plugins.Inventory()
	if inventory == nil {
		inventory = []byte(`{"error": "empty inventory"}`)
		s.logger.Error().Msg("inventory is nil/empty...")
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(inventory)
}

// write handles PUT/POST requests with a JSON playload containing "freeform"
// metrics. No validation is applied to the "format" of the metrics beyond k/v.
// Where 'key' is the metric name and 'value' is the metric value as either a
// simple value (e.g. {"name": 1, "foo": "bar", ...}) or a structured value
// representation (e.g. {"foo": {_type: "i", _value: 1}, ...}).
func (s *Server) write(w http.ResponseWriter, r *http.Request) {
	id := strings.Replace(r.URL.Path, "/write/", "", -1)

	log.Debug().Str("path", r.URL.Path).Str("id", id).Msg("write request")
	// a write request *MUST* include a metric group id to act as a namespace.
	// in other words, a "plugin name", all metrics for that write will appear
	// _under_ the metric group id (aka plugin name)
	if id == "" {
		http.NotFound(w, r)
		return
	}

	if err := receiver.Parse(id, r.Body); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	w.WriteHeader(http.StatusNoContent)
}
<commit_msg>prom: add header and use io.Writer for testing<commit_after>// Copyright © 2017 Circonus, Inc. <support@circonus.com>
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//

package server

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/circonus-labs/circonus-agent/internal/config"
	"github.com/circonus-labs/circonus-agent/internal/plugins"
	"github.com/circonus-labs/circonus-agent/internal/server/receiver"
	cgm "github.com/circonus-labs/circonus-gometrics"
	"github.com/rs/zerolog/log"
	"github.com/spf13/viper"
)

// run handles requests to execute plugins and return metrics emitted
// handles /, /run, or /run/plugin_name
func (s *Server) run(w http.ResponseWriter, r *http.Request) {
	plugin := ""

	if strings.HasPrefix(r.URL.Path, "/run/") { // run specific plugin
		plugin = strings.Replace(r.URL.Path, "/run/", "", -1)
		if plugin != "" {
			if !s.plugins.IsInternal(plugin) && !s.plugins.IsValid(plugin) {
				s.logger.Warn().
					Str("plugin", plugin).
					Msg("Unknown plugin requested")
				http.NotFound(w, r)
				return
			}
		}
	}

	lastMeticsmu.Lock()
	defer lastMeticsmu.Unlock()

	metrics := &map[string]interface{}{}

	if plugin == "" || !s.plugins.IsInternal(plugin) {
		// NOTE: errors are ignored from plugins.Run
		//       1. errors are already logged by Run
		//       2. do not expose execution state to callers
		s.plugins.Run(plugin)
		metrics = s.plugins.Flush(plugin)
	}

	if plugin == "" || plugin == "write" {
		receiverMetrics := receiver.Flush()
		for metricGroup, value := range *receiverMetrics {
			(*metrics)[metricGroup] = value
		}
	}

	if plugin == "" || plugin == "statsd" {
		if s.statsdSvr != nil {
			statsdMetrics := s.statsdSvr.Flush()
			if statsdMetrics != nil {
				(*metrics)[viper.GetString(config.KeyStatsdHostCategory)] = *statsdMetrics
			}
		}
	}

	lastMetrics.metrics = metrics
	lastMetrics.ts = time.Now()

	w.Header().Set("Content-Type", "application/json")
	if err := json.NewEncoder(w).Encode(metrics); err != nil {
		s.logger.Error().
			Err(err).
			Msg("Writing metrics to response")
	}
}

// inventory returns the current, active plugin inventory
func (s *Server) inventory(w http.ResponseWriter, r *http.Request) {
	inventory := s.plugins.Inventory()
	if inventory == nil {
		inventory = []byte(`{"error": "empty inventory"}`)
		s.logger.Error().Msg("inventory is nil/empty...")
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write(inventory)
}

// write handles PUT/POST requests with a JSON playload containing "freeform"
// metrics. No validation is applied to the "format" of the metrics beyond k/v.
// Where 'key' is the metric name and 'value' is the metric value as either a
// simple value (e.g. {"name": 1, "foo": "bar", ...}) or a structured value
// representation (e.g. {"foo": {_type: "i", _value: 1}, ...}).
func (s *Server) write(w http.ResponseWriter, r *http.Request) {
	id := strings.Replace(r.URL.Path, "/write/", "", -1)

	log.Debug().Str("path", r.URL.Path).Str("id", id).Msg("write request")
	// a write request *MUST* include a metric group id to act as a namespace.
	// in other words, a "plugin name", all metrics for that write will appear
	// _under_ the metric group id (aka plugin name)
	if id == "" {
		http.NotFound(w, r)
		return
	}

	if err := receiver.Parse(id, r.Body); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	w.WriteHeader(http.StatusNoContent)
}

// promOutput returns the last metrics in prom format
func (s *Server) promOutput(w http.ResponseWriter, r *http.Request) {
	if lastMetrics.metrics == nil || len(*lastMetrics.metrics) == 0 {
		w.WriteHeader(http.StatusNoContent)
		return
	}

	ms := lastMetrics.ts.UnixNano() / int64(time.Millisecond)

	w.Header().Set("Content-Type", "text/plain")
	w.WriteHeader(http.StatusOK)
	for group, data := range *lastMetrics.metrics {
		metricsToPromFormat(w, group, ms, data)
	}
}

func metricsToPromFormat(w io.Writer, prefix string, ts int64, val interface{}) {
	switch t := val.(type) {
	case cgm.Metric:
		metric := val.(cgm.Metric)
		s := fmt.Sprintf("%v", metric.Value)
		switch metric.Type {
		case "i":
			fallthrough
		case "I":
			fallthrough
		case "l":
			fallthrough
		case "L":
			v, err := strconv.ParseInt(s, 10, 64)
			if err != nil {
				log.Error().Err(err).Msg("conv int64")
				return
			}
			if _, err := w.Write([]byte(fmt.Sprintf("%s %d %d\n", prefix, v, ts))); err != nil {
				log.Error().Err(err).Msg("writing prom output")
			}
		case "n":
			if strings.Contains(s, "[H[") {
				if _, err := w.Write([]byte(fmt.Sprintf("#HISTOGRAM %s %s %d\n", prefix, s, ts))); err != nil {
					log.Error().Err(err).Msg("writing prom output")
				}
			} else {
				v, err := strconv.ParseFloat(s, 64)
				if err != nil {
					log.Error().Err(err).Msg("conv float64")
					return
				}
				if _, err := w.Write([]byte(fmt.Sprintf("%s %f %d\n", prefix, v, ts))); err != nil {
					log.Error().Err(err).Msg("writing prom output")
				}
			}
		default:
			if _, err := w.Write([]byte(fmt.Sprintf("#TEXT %s %s %d\n", prefix, s, ts))); err != nil {
				log.Error().Err(err).Msg("writing prom output")
			}
		}
	case cgm.Metrics:
		metrics, ok := val.(cgm.Metrics)
		if !ok {
			st := fmt.Sprintf("%T", t)
			log.Warn().Interface("val", val).Str("target_type", st).Str("pkg", "prom export").Msg("unable to coerce")
			return
		}
		for pfx, metric := range metrics {
			name := prefix
			if pfx != "" {
				name += "`" + pfx
			}
			metricsToPromFormat(w, name, ts, metric)
		}
	case *plugins.Metrics:
		metrics, ok := val.(*plugins.Metrics)
		if !ok {
			st := fmt.Sprintf("%T", t)
			log.Warn().Interface("val", val).Str("target_type", st).Str("pkg", "prom export").Msg("unable to coerce")
			return
		}
		for pfx, metric := range *metrics {
			name := prefix
			if pfx != "" {
				name += "`" + pfx
			}
			metricsToPromFormat(w, name, ts, cgm.Metric(metric))
		}
	default:
		if _, err := w.Write([]byte(fmt.Sprintf("#UNHANDLED TYPE(%T) %v = %#v\n", t, prefix, val))); err != nil {
			log.Error().Err(err).Msg("writing prom output")
		}
	}
}
<|endoftext|>


<commit_before>package template

var (
	Plugin = `package main
{{if .Plugins}}
import ({{range .Plugins}}
	_ "github.com/micro/go-plugins/{{.}}"{{end}}
){{end}}
`
)
<commit_msg>plugin: upgrade to v2 (#1083)<commit_after>package template

var (
	Plugin = `package main
{{if .Plugins}}
import ({{range .Plugins}}
	_ "github.com/micro/go-plugins/{{.}}/v2"{{end}}
){{end}}
`
)
<|endoftext|>


<commit_before>package rotator

import (
	"github.com/stretchr/testify/assert"
	"os"
	"testing"
	"time"
)

func TestFileOutput(t *testing.T) {

	path := "test_daily.log"

	_, err := os.Lstat(path)
	if err == os.ErrNotExist {
		os.Create(path)
	}

	file, err := os.OpenFile(path, os.O_CREATE, 0644)
	if err != nil {
		panic(err)
	}
	defer file.Close()

	rotator := NewDailyRotator(path)
	defer rotator.Close()

	rotator.WriteString("SAMPLE LOG")

	b := make([]byte, 10)
	file.Read(b)
	assert.Equal(t, "SAMPLE LOG", string(b))

	rotator.WriteString("\nNEXT LOG")
	rotator.WriteString("\nLAST LOG")

	b = make([]byte, 28)
	file.ReadAt(b, 0)

	assert.Equal(t, "SAMPLE LOG\nNEXT LOG\nLAST LOG", string(b))

}

func TestDailyRotationOnce(t *testing.T) {

	path := "test_daily.log"

	stat, _ := os.Lstat(path)
	if stat != nil {
		os.Remove(path)
	}

	now := time.Now()

	rotator := NewDailyRotator(path)
	defer rotator.Close()

	rotator.Now = now
	rotator.WriteString("SAMPLE LOG")

	// simulate next day
	rotator.Now = time.Unix(now.Unix()+86400, 0)
	rotator.WriteString("NEXT LOG")

	stat, _ = os.Lstat(path + "." + now.Format(dateFormat))

	assert.NotNil(t, stat)

	os.Remove(path)
}

func TestDailyRotationAtOpen(t *testing.T) {

	path := "test_daily.log"

	stat, _ := os.Lstat(path)
	if stat != nil {
		os.Remove(path)
	}

	rotator := NewDailyRotator(path)
	rotator.WriteString("FIRST LOG")
	rotator.Close()

	now := time.Now()

	// simulate next day
	rotator = NewDailyRotator(path)
	defer rotator.Close()

	rotator.Now = time.Unix(now.Unix()+86400, 0)
	rotator.WriteString("NEXT LOG")

	stat, _ = os.Lstat(path + "." + now.Format(dateFormat))

	assert.NotNil(t, stat)

	os.Remove(path)

}
<commit_msg>Add more tests for daily_rotator<commit_after>package rotator

import (
	"github.com/stretchr/testify/assert"
	"os"
	"testing"
	"time"
)

func TestFileOutput(t *testing.T) {

	path := "test_daily.log"

	_, err := os.Lstat(path)
	if err != nil {
		os.Remove(path)
	}

	file, err := os.OpenFile(path, os.O_CREATE, 0644)
	if err != nil {
		panic(err)
	}
	defer file.Close()

	rotator := NewDailyRotator(path)
	defer rotator.Close()

	rotator.WriteString("SAMPLE LOG")

	b := make([]byte, 10)
	file.Read(b)
	assert.Equal(t, "SAMPLE LOG", string(b))

	rotator.WriteString("\nNEXT LOG")
	rotator.WriteString("\nLAST LOG")

	b = make([]byte, 28)
	file.ReadAt(b, 0)

	assert.Equal(t, "SAMPLE LOG\nNEXT LOG\nLAST LOG", string(b))

}

func TestDailyRotationOnce(t *testing.T) {

	path := "test_daily.log"

	stat, _ := os.Lstat(path)
	if stat != nil {
		os.Remove(path)
	}

	now := time.Now()

	rotator := NewDailyRotator(path)
	defer rotator.Close()

	rotator.Now = now
	rotator.WriteString("SAMPLE LOG")

	// simulate next day
	rotator.Now = time.Unix(now.Unix()+86400, 0)
	rotator.WriteString("NEXT LOG")

	stat, _ = os.Lstat(path + "." + now.Format(dateFormat))

	assert.NotNil(t, stat)

	os.Remove(path)
	os.Remove(path + "." + now.Format(dateFormat))
}

func TestDailyRotationAtOpen(t *testing.T) {

	path := "test_daily.log"

	stat, _ := os.Lstat(path)
	if stat != nil {
		os.Remove(path)
	}

	rotator := NewDailyRotator(path)
	rotator.WriteString("FIRST LOG")
	rotator.Close()

	now := time.Now()

	// simulate next day
	rotator = NewDailyRotator(path)
	defer rotator.Close()

	rotator.Now = time.Unix(now.Unix()+86400, 0)
	rotator.WriteString("NEXT LOG")

	stat, _ = os.Lstat(path + "." + now.Format(dateFormat))

	assert.NotNil(t, stat)

	os.Remove(path)
	os.Remove(path + "." + now.Format(dateFormat))
}

func TestDailyRotationError(t *testing.T) {

	path := "test_daily.log"

	stat, _ := os.Lstat(path)
	if stat != nil {
		os.Remove(path)
	}

	now := time.Now()

	rotator := NewDailyRotator(path)
	rotator.WriteString("FIRST LOG")
	// Simulate rotation
	rotator.Now = time.Unix(now.Unix()+86400, 0)
	rotator.WriteString("SECOND LOG")
	rotator.Close()

	rotator = NewDailyRotator(path)
	defer rotator.Close()
	rotator.WriteString("FIRST LOG")
	// Simulate rotation twice
	rotator.Now = time.Unix(now.Unix()+86400, 0)
	_, err := rotator.WriteString("SECOND LOG")

	assert.Nil(t, err)

	os.Remove(path)
	os.Remove(path + "." + now.Format(dateFormat))

}
<|endoftext|>


<commit_before>package main

import (
	"fmt"

	"github.com/spf13/cobra"

	"github.com/NebulousLabs/Sia/modules"
)

var (
	minerCmd = &cobra.Command{
		Use:   "miner",
		Short: "Perform miner actions",
		Long:  "Start mining, stop mining, or view the current mining status, including number of threads, deposit address, and more.",
		Run:   wrap(minerstatuscmd),
	}

	minerStartCmd = &cobra.Command{
		Use:   "start [threads]",
		Short: "Start mining on 'threads' threads",
		Long:  "Start mining on a specified number of threads. If the miner is already running, the number of threads is adjusted.",
		Run:   wrap(minerstartcmd),
	}

	minerStatusCmd = &cobra.Command{
		Use:   "status",
		Short: "View miner status",
		Long:  "View the current mining status, including number of threads, deposit address, and more.",
		Run:   wrap(minerstatuscmd),
	}

	minerStopCmd = &cobra.Command{
		Use:   "stop",
		Short: "Stop mining",
		Long:  "Stop mining (this may take a few moments).",
		Run:   wrap(minerstopcmd),
	}
)

func minerstartcmd(threads string) {
	err := post("/miner/start", "threads="+threads)
	if err != nil {
		fmt.Println("Could not start miner:", err)
		return
	}
	fmt.Println("Now mining on " + threads + " threads.")
}

func minerstatuscmd() {
	status := new(modules.MinerInfo)
	err := getAPI("/miner/status", status)
	if err != nil {
		fmt.Println("Could not get miner status:", err)
		return
	}
	fmt.Printf(`Miner status:
State:   %s
Threads: %d (%d active)
Address: %x
`, status.State, status.Threads, status.RunningThreads, status.Address)
}

func minerstopcmd() {
	err := post("/miner/stop", "")
	if err != nil {
		fmt.Println("Could not stop miner:", err)
		return
	}
	fmt.Println("Stopped mining.")
}
<commit_msg>add missing miner info to siac<commit_after>package main

import (
	"fmt"

	"github.com/spf13/cobra"

	"github.com/NebulousLabs/Sia/modules"
)

var (
	minerCmd = &cobra.Command{
		Use:   "miner",
		Short: "Perform miner actions",
		Long:  "Start mining, stop mining, or view the current mining status, including number of threads, deposit address, and more.",
		Run:   wrap(minerstatuscmd),
	}

	minerStartCmd = &cobra.Command{
		Use:   "start [threads]",
		Short: "Start mining on 'threads' threads",
		Long:  "Start mining on a specified number of threads. If the miner is already running, the number of threads is adjusted.",
		Run:   wrap(minerstartcmd),
	}

	minerStatusCmd = &cobra.Command{
		Use:   "status",
		Short: "View miner status",
		Long:  "View the current mining status, including number of threads, deposit address, and more.",
		Run:   wrap(minerstatuscmd),
	}

	minerStopCmd = &cobra.Command{
		Use:   "stop",
		Short: "Stop mining",
		Long:  "Stop mining (this may take a few moments).",
		Run:   wrap(minerstopcmd),
	}
)

func minerstartcmd(threads string) {
	err := post("/miner/start", "threads="+threads)
	if err != nil {
		fmt.Println("Could not start miner:", err)
		return
	}
	fmt.Println("Now mining on " + threads + " threads.")
}

func minerstatuscmd() {
	status := new(modules.MinerInfo)
	err := getAPI("/miner/status", status)
	if err != nil {
		fmt.Println("Could not get miner status:", err)
		return
	}
	fmt.Printf(`Miner status:
State:   %s
Threads: %d (%d active)
Address: %x

Hash Rate:    %0.2f MH/s (est. %0.2f blocks per week)
Blocks Mined: %d (%d orphans)
`, status.State, status.Threads, status.RunningThreads, status.Address,
		float64(status.HashRate)/1e6, status.BlocksPerWeek, status.BlocksMined, status.OrphansMined)
}

func minerstopcmd() {
	err := post("/miner/stop", "")
	if err != nil {
		fmt.Println("Could not stop miner:", err)
		return
	}
	fmt.Println("Stopped mining.")
}
<|endoftext|>


<commit_before>package sigctx

import (
	"context"
	"os"
	"os/signal"
	"syscall"

	"github.com/SentimensRG/ctx"
)

var c ctx.C

func init() {
	dc := make(chan struct{})
	c = dc

	ch := make(chan os.Signal, 1)
	signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		select {
		case <-ch:
			close(dc)
		case <-c.Done():
		}
	}()
}

// New signal-bound ctx.C that terminates when either SIGINT or SIGTERM
// is caught.
func New() ctx.C {
	return c
}

// NewContext calls New and wraps the result in a context.Context.  The result
// is a context that fires when either SIGINT or SIGTERM is caught.
func NewContext() context.Context {
	return ctx.AsContext(New())
}
<commit_msg>Revert "Eager-load"<commit_after>package sigctx

import (
	"context"
	"os"
	"os/signal"
	"sync"
	"syscall"

	"github.com/SentimensRG/ctx"
)

var (
	c    ctx.C
	once sync.Once
)

// New signal-bound ctx.C that terminates when either SIGINT or SIGTERM
// is caught.
func New() ctx.C {
	once.Do(func() {
		dc := make(chan struct{})
		c = dc

		ch := make(chan os.Signal, 1)
		signal.Notify(ch, syscall.SIGINT, syscall.SIGTERM)

		go func() {
			select {
			case <-ch:
				close(dc)
			case <-c.Done():
			}
		}()
	})

	return c
}

// NewContext calls New and wraps the result in a context.Context.  The result
// is a context that fires when either SIGINT or SIGTERM is caught.
func NewContext() context.Context {
	return ctx.AsContext(New())
}
<|endoftext|>


<commit_before>package jsonrpc2

import (
	"context"
	"log"
)

// HandlerWithError implements Handler by calling the func for each
// request and handling returned errors and results.
type HandlerWithError func(context.Context, *Conn, *Request) (result interface{}, err error)

// Handle implements Handler.
func (h HandlerWithError) Handle(ctx context.Context, conn *Conn, req *Request) {
	result, err := h(ctx, conn, req)
	if req.Notif {
		if err != nil {
			log.Printf("jsonrpc2 handler: notification %q handling error: %s", req.Method, err)
		}
		return
	}

	resp := &Response{ID: req.ID}
	if err == nil {
		if result == nil {
			result = struct{}{}
		}
		err = resp.SetResult(result)
	}
	if err != nil {
		if e, ok := err.(*Error); ok {
			resp.Error = e
		} else {
			resp.Error = &Error{Message: err.Error()}
		}
	}

	if !req.Notif {
		if err := conn.SendResponse(ctx, resp); err != nil {
			log.Printf("jsonrpc2 handler: sending response %d: %s", resp.ID, err)
		}
	}
}
<commit_msg>Send something over the wire for responses<commit_after>package jsonrpc2

import (
	"context"
	"log"
	"reflect"
)

// HandlerWithError implements Handler by calling the func for each
// request and handling returned errors and results.
type HandlerWithError func(context.Context, *Conn, *Request) (result interface{}, err error)

// Handle implements Handler.
func (h HandlerWithError) Handle(ctx context.Context, conn *Conn, req *Request) {
	result, err := h(ctx, conn, req)
	if req.Notif {
		if err != nil {
			log.Printf("jsonrpc2 handler: notification %q handling error: %s", req.Method, err)
		}
		return
	}

	resp := &Response{ID: req.ID}
	if err == nil {
		if isNilValue(result) {
			result = struct{}{}
		}
		err = resp.SetResult(result)
	}
	if err != nil {
		if e, ok := err.(*Error); ok {
			resp.Error = e
		} else {
			resp.Error = &Error{Message: err.Error()}
		}
	}

	if !req.Notif {
		if err := conn.SendResponse(ctx, resp); err != nil {
			log.Printf("jsonrpc2 handler: sending response %d: %s", resp.ID, err)
		}
	}
}

// isNilValue tests if an interface is empty, because an empty interface does
// not encode any information, we can't encode it in JSON so that the proxy
// knows it's a response, not a request.
func isNilValue(resp interface{}) bool {
	if resp == nil {
		return true
	}
	kind := reflect.TypeOf(resp).Kind()
	value := reflect.ValueOf(resp)
	nilPtr := kind == reflect.Ptr && value.IsNil()
	nilSlice := kind == reflect.Slice && value.IsNil()
	return nilPtr || nilSlice
}
<|endoftext|>


<commit_before>package simple

import (
	"context"
	log "github.com/Sirupsen/logrus"
	"github.com/loadimpact/speedboat/lib"
	"net"
	"net/http"
	"net/url"
	"time"
)

type Runner struct {
	URL       *url.URL
	Transport *http.Transport
}

func New(rawurl string) (*Runner, error) {
	u, err := url.Parse(rawurl)
	if err != nil {
		return nil, err
	}

	return &Runner{
		URL: u,
		Transport: &http.Transport{
			Proxy: http.ProxyFromEnvironment,
			DialContext: (&net.Dialer{
				Timeout:   10 * time.Second,
				KeepAlive: 60 * time.Second,
				DualStack: true,
			}).DialContext,
		},
	}, nil
}

func (r *Runner) NewVU() (lib.VU, error) {
	return &VU{
		Runner: r,
		Request: http.Request{
			Method: "GET",
			URL:    r.URL,
		},
		Client: http.Client{
			Transport: r.Transport,
		},
	}, nil
}

type VU struct {
	Runner *Runner
	ID     int64

	Request http.Request
	Client  http.Client
}

func (u *VU) RunOnce(ctx context.Context) error {
	log.WithField("id", u.ID).Info("Running")
	return nil
}

func (u *VU) Reconfigure(id int64) error {
	u.ID = id
	return nil
}
<commit_msg>[fix] Less spammy dummy runner<commit_after>package simple

import (
	"context"
	log "github.com/Sirupsen/logrus"
	"github.com/loadimpact/speedboat/lib"
	"net"
	"net/http"
	"net/url"
	"time"
)

type Runner struct {
	URL       *url.URL
	Transport *http.Transport
}

func New(rawurl string) (*Runner, error) {
	u, err := url.Parse(rawurl)
	if err != nil {
		return nil, err
	}

	return &Runner{
		URL: u,
		Transport: &http.Transport{
			Proxy: http.ProxyFromEnvironment,
			DialContext: (&net.Dialer{
				Timeout:   10 * time.Second,
				KeepAlive: 60 * time.Second,
				DualStack: true,
			}).DialContext,
		},
	}, nil
}

func (r *Runner) NewVU() (lib.VU, error) {
	return &VU{
		Runner: r,
		Request: http.Request{
			Method: "GET",
			URL:    r.URL,
		},
		Client: http.Client{
			Transport: r.Transport,
		},
	}, nil
}

type VU struct {
	Runner *Runner
	ID     int64

	Request http.Request
	Client  http.Client
}

func (u *VU) RunOnce(ctx context.Context) error {
	log.WithField("id", u.ID).Debug("Running")
	time.Sleep(1 * time.Second)
	return nil
}

func (u *VU) Reconfigure(id int64) error {
	u.ID = id
	return nil
}
<|endoftext|>


<commit_before>package main

import (
  "bufio"
  "flag"
  "fmt"
  "io"
  "log"
  "net"
  "os"
  "path"
  "strings"
)

const ClError = "3"
const ClInfo = "i"
const ClDirectory = "1"
const ClBinary = "9"

const IndexFN = "index.cat"

var extensions = map[string]string{
  ".txt": "0",
  ".diz": "0",
  ".nfo": "0",
  ".gif": "g",
  ".jpg": "I",
  ".png": "I",
  ".mp3": "s",
  ".wav": "s",
  ".mid": "s",
}

var host *string = flag.String("host", "127.0.0.1", "Bind to specified address")
var port *string = flag.String("port", "70", "Bind to specified port")
var base *string = flag.String("base", ".", "Directory to serve files from")

func main() {
  flag.Parse()

  log.Printf("Starting Gopher at %s:%s using %s", *host, *port, *base)

  if listener, e := net.Listen("tcp", fmt.Sprintf("%s:%s", *host, *port)); e != nil {
    log.Fatalf("Can't create listener: %s", e.Error())
  } else {
    log.Printf("Waiting for client connections...")
    for {
      if client, e := listener.Accept(); e != nil {
        log.Printf("Failed to accept client: %s", e.Error())
      } else {
        go gopher(client)
      }
    }
  }

}

func gopher(sck net.Conn) {
  defer sck.Close()

  if selector, e := bufio.NewReader(sck).ReadString('\n'); e != nil {
    log.Printf("Can't read selector string: %s", e.Error())
  } else {
    selector = strings.Trim(selector, "\n\r\t ")

    fso := path.Join(*base, selector)

    if stat, e := os.Stat(fso); e != nil {
      log.Printf("Can't get stats of %s: %s", fso, e.Error())
    } else {

      if stat.IsDir() == true {
        gopher_index(path.Join(fso, IndexFN), sck)
      } else {
        if strings.HasSuffix(fso, IndexFN) {
          gopher_index(fso, sck)
        } else {
          gopher_send(fso, sck)
        }
      }

    }

  }

}

func gopher_index(fileName string, sck net.Conn) {
  if indexFile, e := os.Open(fileName); e != nil {
    log.Printf("Can't read Index %s: %s", fileName, e.Error())
    gopher_error(e.Error(), sck)
  } else {
    defer indexFile.Close()

    scanner := bufio.NewScanner(indexFile)

    for scanner.Scan() {
      record := strings.Split(scanner.Text(), "\t")

      switch len(record) {
      case 0:
        gopher_entry(ClInfo, "", "", sck)
      case 1:
        gopher_entry(ClInfo, record[0], "", sck)
      case 2:
        gopher_entry(getClass(fileName, record[1]), record[0], record[1], sck)
      }

    }

  }
}

func getClass(base, selector string) string {
  var fileName = path.Join(path.Dir(base), selector)
  if stat, e := os.Stat(fileName); e != nil {
    log.Printf("Can't get stats of %s: %s", fileName, e.Error())
    return ClInfo
  } else {
    if stat.IsDir() {
      return ClDirectory
    } else {
      if class, e := extensions[strings.ToLower(path.Ext(fileName))]; e != true {
        return ClBinary
      } else {
        return class
      }
    }
  }
}

func gopher_generate() {}

func gopher_send(fileName string, sck net.Conn) {
  if file, e := os.Open(fileName); e != nil {
    log.Printf("Can't read file %s: %s", fileName, e.Error())
    gopher_error(e.Error(), sck)
  } else {
    if _, e := io.Copy(sck, file); e != nil {
      log.Printf("Failed to send file %s: %s", fileName, e.Error())
    }
  }
}

func gopher_error(message string, sck net.Conn) {
  gopher_entry(ClError, message, "", sck)
}

func gopher_entry(class, text, selector string, sck net.Conn) {
  sck.Write([]byte(fmt.Sprintf("%s%s\t%s\t%s\t%d\n", class, text, selector, host, port)))
}
<commit_msg>Read selector fix<commit_after>package main

import (
  "bufio"
  "flag"
  "fmt"
  "io"
  "log"
  "net"
  "os"
  "path"
  "path/filepath"
  "strings"
)

const ClError = "3"
const ClInfo = "i"
const ClDirectory = "1"
const ClBinary = "9"

const IndexFN = "index.cat"

var extensions = map[string]string{
  ".txt": "0",
  ".diz": "0",
  ".nfo": "0",
  ".gif": "g",
  ".jpg": "I",
  ".png": "I",
  ".mp3": "s",
  ".wav": "s",
  ".mid": "s",
}

var host *string = flag.String("host", "127.0.0.1", "Host name or IP address to listen")
var port *string = flag.String("port", "70",        "Port number for incoming connections, usually 70")
var base *string = flag.String("base", ".",         "Directory to be published")

func main() {
  flag.Parse()
  *base, _ = filepath.Abs(*base)

  log.Printf("Starting Gopher at %s:%s using %s", *host, *port, *base)

  if listener, e := net.Listen("tcp", fmt.Sprintf("%s:%s", *host, *port)); e != nil {
    log.Fatalf("Can't create listener: %s", e.Error())
  } else {
    log.Printf("Waiting for client connections...")
    for {
      if client, e := listener.Accept(); e != nil {
        log.Printf("Failed to accept client: %s", e.Error())
      } else {
        go gopher(client)
      }
    }
  }

}

func gopher(sck net.Conn) {
  defer sck.Close()

  raw := make([]byte, 255)

  if _, e := sck.Read(raw); e != nil {
    log.Printf("Can't read selector: %s", e.Error())
  } else {
    selector := strings.Trim(string(raw), "\n\r\x00 ")
    request, _ := filepath.Abs(path.Join(*base, selector))

    if strings.Contains(request, "\t") == false {

      // Simple file request

      if strings.HasPrefix(request, *base) == false {  // Check if requested object is inside base directory
        // Access violation
      } else {
        // Ok, we can serve
        if stat, e := os.Stat(request); e != nil {
          log.Printf("Can't get attributes of %s: %s", request, e.Error())
        } else {
          if stat.IsDir() {
            // Serve Index
          } else {
            gopher_send(request, sck)
          }
        }
      }

    } else {
      // Search query
    }

  }

}

func gopher_index(fileName string, sck net.Conn) {
  if indexFile, e := os.Open(fileName); e != nil {
    log.Printf("Can't read Index %s: %s", fileName, e.Error())
    gopher_error(e.Error(), sck)
  } else {
    defer indexFile.Close()

    scanner := bufio.NewScanner(indexFile)

    for scanner.Scan() {
      record := strings.Split(scanner.Text(), "\t")

      switch len(record) {
      case 0:
        gopher_entry(ClInfo, "", "", sck)
      case 1:
        gopher_entry(ClInfo, record[0], "", sck)
      case 2:
        gopher_entry(getClass(fileName, record[1]), record[0], record[1], sck)
      }

    }

  }
}

func getClass(base, selector string) string {
  var fileName = path.Join(path.Dir(base), selector)
  if stat, e := os.Stat(fileName); e != nil {
    log.Printf("Can't get stats of %s: %s", fileName, e.Error())
    return ClInfo
  } else {
    if stat.IsDir() {
      return ClDirectory
    } else {
      if class, e := extensions[strings.ToLower(path.Ext(fileName))]; e != true {
        return ClBinary
      } else {
        return class
      }
    }
  }
}

func gopher_generate() {}

func gopher_send(fileName string, sck net.Conn) {
  if file, e := os.Open(fileName); e != nil {
    log.Printf("Can't read file %s: %s", fileName, e.Error())
    gopher_error(e.Error(), sck)
  } else {
    if _, e := io.Copy(sck, file); e != nil {
      log.Printf("Failed to send file %s: %s", fileName, e.Error())
    }
  }
}

func gopher_error(message string, sck net.Conn) {
  gopher_entry(ClError, message, "", sck)
}

func gopher_entry(class, text, selector string, sck net.Conn) {
  sck.Write([]byte(fmt.Sprintf("%s%s\t%s\t%s\t%d\n", class, text, selector, host, port)))
}
<|endoftext|>


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

// +build linux,!appengine

// Package terminal provides support functions for dealing with terminals, as
// commonly found on UNIX systems.
//
// Putting a terminal into raw mode is the most common requirement:
//
// 	oldState, err := terminal.MakeRaw(0)
// 	if err != nil {
// 	        panic(err)
// 	}
// 	defer terminal.Restore(0, oldState)
package terminal

import (
	"io"
	"syscall"
	"unsafe"
)

// State contains the state of a terminal.
type State struct {
	termios syscall.Termios
}

// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
	var termios syscall.Termios
	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
	return err == 0
}

// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd int) (*State, error) {
	var oldState State
	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
		return nil, err
	}

	newState := oldState.termios
	newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF
	newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
		return nil, err
	}

	return &oldState, nil
}

// Restore restores the terminal connected to the given file descriptor to a
// previous state.
func Restore(fd int, state *State) error {
	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0)
	return err
}

// GetSize returns the dimensions of the given terminal.
func GetSize(fd int) (width, height int, err error) {
	var dimensions [4]uint16

	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 {
		return -1, -1, err
	}
	return int(dimensions[1]), int(dimensions[0]), nil
}

// ReadPassword reads a line of input from a terminal without local echo.  This
// is commonly used for inputting passwords and other sensitive data. The slice
// returned does not include the \n.
func ReadPassword(fd int) ([]byte, error) {
	var oldState syscall.Termios
	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 {
		return nil, err
	}

	newState := oldState
	newState.Lflag &^= syscall.ECHO
	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
		return nil, err
	}

	defer func() {
		syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&oldState)), 0, 0, 0)
	}()

	var buf [16]byte
	var ret []byte
	for {
		n, err := syscall.Read(fd, buf[:])
		if err != nil {
			return nil, err
		}
		if n == 0 {
			if len(ret) == 0 {
				return nil, io.EOF
			}
			break
		}
		if buf[n-1] == '\n' {
			n--
		}
		ret = append(ret, buf[:n]...)
		if n < len(buf) {
			break
		}
	}

	return ret, nil
}
<commit_msg>ssh/terminal: add GetState and make ReadPassword work in raw mode.<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build linux,!appengine

// Package terminal provides support functions for dealing with terminals, as
// commonly found on UNIX systems.
//
// Putting a terminal into raw mode is the most common requirement:
//
// 	oldState, err := terminal.MakeRaw(0)
// 	if err != nil {
// 	        panic(err)
// 	}
// 	defer terminal.Restore(0, oldState)
package terminal

import (
	"io"
	"syscall"
	"unsafe"
)

// State contains the state of a terminal.
type State struct {
	termios syscall.Termios
}

// IsTerminal returns true if the given file descriptor is a terminal.
func IsTerminal(fd int) bool {
	var termios syscall.Termios
	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&termios)), 0, 0, 0)
	return err == 0
}

// MakeRaw put the terminal connected to the given file descriptor into raw
// mode and returns the previous state of the terminal so that it can be
// restored.
func MakeRaw(fd int) (*State, error) {
	var oldState State
	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
		return nil, err
	}

	newState := oldState.termios
	newState.Iflag &^= syscall.ISTRIP | syscall.INLCR | syscall.ICRNL | syscall.IGNCR | syscall.IXON | syscall.IXOFF
	newState.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.ISIG
	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
		return nil, err
	}

	return &oldState, nil
}

// GetState returns the current state of a terminal which may be useful to
// restore the terminal after a signal.
func GetState(fd int) (*State, error) {
	var oldState State
	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&oldState.termios)), 0, 0, 0); err != 0 {
		return nil, err
	}

	return &oldState, nil
}

// Restore restores the terminal connected to the given file descriptor to a
// previous state.
func Restore(fd int, state *State) error {
	_, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&state.termios)), 0, 0, 0)
	return err
}

// GetSize returns the dimensions of the given terminal.
func GetSize(fd int) (width, height int, err error) {
	var dimensions [4]uint16

	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(&dimensions)), 0, 0, 0); err != 0 {
		return -1, -1, err
	}
	return int(dimensions[1]), int(dimensions[0]), nil
}

// ReadPassword reads a line of input from a terminal without local echo.  This
// is commonly used for inputting passwords and other sensitive data. The slice
// returned does not include the \n.
func ReadPassword(fd int) ([]byte, error) {
	var oldState syscall.Termios
	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCGETS), uintptr(unsafe.Pointer(&oldState)), 0, 0, 0); err != 0 {
		return nil, err
	}

	newState := oldState
	newState.Lflag &^= syscall.ECHO
	newState.Lflag |= syscall.ICANON | syscall.ISIG
	newState.Iflag |= syscall.ICRNL
	if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
		return nil, err
	}

	defer func() {
		syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), uintptr(syscall.TCSETS), uintptr(unsafe.Pointer(&oldState)), 0, 0, 0)
	}()

	var buf [16]byte
	var ret []byte
	for {
		n, err := syscall.Read(fd, buf[:])
		if err != nil {
			return nil, err
		}
		if n == 0 {
			if len(ret) == 0 {
				return nil, io.EOF
			}
			break
		}
		if buf[n-1] == '\n' {
			n--
		}
		ret = append(ret, buf[:n]...)
		if n < len(buf) {
			break
		}
	}

	return ret, nil
}
<|endoftext|>