<commit_before>/*
Copyright 2019 The Skaffold Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package integration

import (
	"context"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
	"testing"
	"time"

	"github.com/GoogleContainerTools/skaffold/integration/skaffold"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
	"github.com/GoogleContainerTools/skaffold/proto"
	"github.com/GoogleContainerTools/skaffold/testutil"
	"github.com/sirupsen/logrus"
	"k8s.io/apimachinery/pkg/util/wait"
)

func TestDev(t *testing.T) {
	tests := []struct {
		description string
		trigger     string
	}{
		{
			description: "dev with polling trigger",
			trigger:     "polling",
		},
		{
			description: "dev with notify trigger",
			trigger:     "notify",
		},
	}
	for _, test := range tests {
		t.Run(test.description, func(t *testing.T) {
			if testing.Short() {
				t.Skip("skipping integration test")
			}
			if ShouldRunGCPOnlyTests() {
				t.Skip("skipping test that is not gcp only")
			}

			Run(t, "testdata/dev", "sh", "-c", "echo foo > foo")
			defer Run(t, "testdata/dev", "rm", "foo")

			// Run skaffold build first to fail quickly on a build failure
			skaffold.Build().InDir("testdata/dev").RunOrFail(t)

			ns, client, deleteNs := SetupNamespace(t)
			defer deleteNs()

			stop := skaffold.Dev("--trigger", test.trigger).InDir("testdata/dev").InNs(ns.Name).RunBackground(t)
			defer stop()

			dep := client.GetDeployment("test-dev")

			// Make a change to foo so that dev is forced to delete the Deployment and redeploy
			Run(t, "testdata/dev", "sh", "-c", "echo bar > foo")

			// Make sure the old Deployment and the new Deployment are different
			err := wait.PollImmediate(time.Millisecond*500, 10*time.Minute, func() (bool, error) {
				newDep := client.GetDeployment("test-dev")
				return dep.GetGeneration() != newDep.GetGeneration(), nil
			})
			testutil.CheckError(t, false, err)
		})
	}
}

func TestDevAPITriggers(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping integration test")
	}
	if ShouldRunGCPOnlyTests() {
		t.Skip("skipping test that is not gcp only")
	}

	Run(t, "testdata/dev", "sh", "-c", "echo foo > foo")
	defer Run(t, "testdata/dev", "rm", "foo")

	// Run skaffold build first to fail quickly on a build failure
	skaffold.Build().InDir("testdata/dev").RunOrFail(t)

	ns, k8sClient, deleteNs := SetupNamespace(t)
	defer deleteNs()

	rpcAddr := randomPort()

	stop := skaffold.Dev("--auto-build=false", "--auto-sync=false", "--auto-deploy=false", "--rpc-port", rpcAddr).InDir("testdata/dev").InNs(ns.Name).RunBackground(t)
	defer stop()

	client, shutdown := setupRPCClient(t, rpcAddr)
	defer shutdown()

	stream, err := readEventAPIStream(client, t, readRetries)
	if stream == nil {
		t.Fatalf("error retrieving event log: %v\n", err)
	}

	// throw away first 5 entries of log (from first run of dev loop)
	for i := 0; i < 5; i++ {
		stream.Recv()
	}

	// read entries from the log
	entries := make(chan *proto.LogEntry)
	go func() {
		for {
			entry, _ := stream.Recv()
			if entry != nil {
				entries <- entry
			}
		}
	}()

	dep := k8sClient.GetDeployment("test-dev")

	// Make a change to foo
	Run(t, "testdata/dev", "sh", "-c", "echo bar > foo")

	// Issue a build trigger
	client.Execute(context.Background(), &proto.UserIntentRequest{
		Intent: &proto.Intent{
			Build: true,
		},
	})

	// Ensure we see a build triggered in the event log
	err = wait.PollImmediate(time.Millisecond*500, 2*time.Minute, func() (bool, error) {
		e := <-entries
		return e.GetEvent().GetBuildEvent().GetArtifact() == "gcr.io/k8s-skaffold/test-dev", nil
	})
	testutil.CheckError(t, false, err)

	// Issue a deploy trigger
	client.Execute(context.Background(), &proto.UserIntentRequest{
		Intent: &proto.Intent{
			Deploy: true,
		},
	})

	// Ensure we see a deploy triggered in the event log
	err = wait.PollImmediate(time.Millisecond*500, 2*time.Minute, func() (bool, error) {
		e := <-entries
		return e.GetEvent().GetDeployEvent().GetStatus() == "In Progress", nil
	})
	testutil.CheckError(t, false, err)

	// Make sure the old Deployment and the new Deployment are different
	err = wait.PollImmediate(time.Millisecond*500, 10*time.Minute, func() (bool, error) {
		newDep := k8sClient.GetDeployment("test-dev")
		return dep.GetGeneration() != newDep.GetGeneration(), nil
	})
	testutil.CheckError(t, false, err)
}

func TestDevPortForward(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping integration test")
	}
	if ShouldRunGCPOnlyTests() {
		t.Skip("skipping test that is not gcp only")
	}

	// Run skaffold build first to fail quickly on a build failure
	skaffold.Build("--cache-artifacts=true").InDir("examples/microservices").RunOrFail(t)

	ns, _, deleteNs := SetupNamespace(t)
	defer deleteNs()

	rpcAddr := randomPort()
	env := []string{fmt.Sprintf("TEST_NS=%s", ns.Name)}
	cmd := skaffold.Dev("--port-forward", "--rpc-port", rpcAddr, "--cache-artifacts=true").InDir("examples/microservices").InNs(ns.Name).WithEnv(env)
	stop := cmd.RunBackground(t)
	defer stop()

	client, shutdown := setupRPCClient(t, rpcAddr)
	defer shutdown()

	// create a grpc connection. Increase number of reties for helm.
	stream, err := readEventAPIStream(client, t, 20)
	if stream == nil {
		t.Fatalf("error retrieving event log: %v\n", err)
	}

	// read entries from the log
	entries := make(chan *proto.LogEntry)
	go func() {
		for {
			entry, _ := stream.Recv()
			if entry != nil {
				entries <- entry
			}
		}
	}()

	originalResponse := "leeroooooy app!!"
	replacementResponse := "test string"

	waitForPortForwardEvent(t, entries, "leeroy-app", "service", originalResponse+"\n", ns.Name)

	original, perms, fErr := replaceInFile(originalResponse, replacementResponse, "examples/microservices/leeroy-app/app.go")
	if fErr != nil {
		t.Error(fErr)
	}
	defer func() {
		if original != nil {
			ioutil.WriteFile("examples/microservices/leeroy-app/app.go", original, perms)
		}
	}()

	waitForPortForwardEvent(t, entries, "leeroy-app", "service", replacementResponse+"\n", ns.Name)
}

func TestDevPortForwardGKELoadBalancer(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping integration test")
	}
	if !ShouldRunGCPOnlyTests() {
		t.Skip("skipping test that is not gcp only")
	}

	// Run skaffold build first to fail quickly on a build failure
	skaffold.Build().InDir("testdata/gke_loadbalancer").RunOrFail(t)

	ns, _, deleteNs := SetupNamespace(t)
	defer deleteNs()

	rpcAddr := randomPort()
	env := []string{fmt.Sprintf("TEST_NS=%s", ns.Name)}
	cmd := skaffold.Dev("--port-forward", "--rpc-port", rpcAddr).InDir("testdata/gke_loadbalancer").InNs(ns.Name).WithEnv(env)
	stop := cmd.RunBackground(t)
	defer stop()

	client, shutdown := setupRPCClient(t, rpcAddr)
	defer shutdown()

	// create a grpc connection. Increase number of reties for helm.
	stream, err := readEventAPIStream(client, t, 20)
	if stream == nil {
		t.Fatalf("error retrieving event log: %v\n", err)
	}

	// read entries from the log
	entries := make(chan *proto.LogEntry)
	go func() {
		for {
			entry, _ := stream.Recv()
			if entry != nil {
				entries <- entry
			}
		}
	}()

	waitForPortForwardEvent(t, entries, "gke-loadbalancer", "service", "hello!!\n", ns.Name)
}

func getLocalPortFromPortForwardEvent(t *testing.T, entries chan *proto.LogEntry, resourceName, resourceType, namespace string) int {
	timeout := time.After(1 * time.Minute)
	for {
		select {
		case <-timeout:
			t.Fatalf("timed out waiting for port forwarding event")
		case e := <-entries:
			switch e.Event.GetEventType().(type) {
			case *proto.Event_PortEvent:
				t.Logf("event received %v", e)
				if e.Event.GetPortEvent().ResourceName == resourceName &&
					e.Event.GetPortEvent().ResourceType == resourceType &&
					e.Event.GetPortEvent().Namespace == namespace {
					port := e.Event.GetPortEvent().LocalPort
					t.Logf("Detected %s/%s is forwarded to port %d", resourceType, resourceName, port)
					return int(port)
				}
			default:
				t.Logf("event received %v", e)
			}
		}
	}
}

func waitForPortForwardEvent(t *testing.T, entries chan *proto.LogEntry, resourceName, resourceType, namespace, expected string) {
	port := getLocalPortFromPortForwardEvent(t, entries, resourceName, resourceType, namespace)
	assertResponseFromPort(t, port, expected)
}

// assertResponseFromPort waits for two minutes for the expected response at port.
func assertResponseFromPort(t *testing.T, port int, expected string) {
	logrus.Infof("Waiting for response %s from port %d", expected, port)
	ctx, cancelTimeout := context.WithTimeout(context.Background(), 2*time.Minute)
	defer cancelTimeout()

	for {
		select {
		case <-ctx.Done():
			t.Fatalf("Timed out waiting for response from port %d", port)
		case <-time.After(1 * time.Second):
			resp, err := http.Get(fmt.Sprintf("http://%s:%d", util.Loopback, port))
			if err != nil {
				logrus.Infof("error getting response from port %d: %v", port, err)
				continue
			}
			defer resp.Body.Close()
			body, err := ioutil.ReadAll(resp.Body)
			if err != nil {
				logrus.Infof("error reading response: %v", err)
				continue
			}
			if string(body) == expected {
				return
			}
			logrus.Infof("didn't get expected response from port. got: %s, expected: %s", string(body), expected)
		}
	}
}

func replaceInFile(target, replacement, filepath string) ([]byte, os.FileMode, error) {
	fInfo, err := os.Stat(filepath)
	if err != nil {
		return nil, 0, err
	}
	original, err := ioutil.ReadFile(filepath)
	if err != nil {
		return nil, 0, err
	}

	newContents := strings.Replace(string(original), target, replacement, -1)

	err = ioutil.WriteFile(filepath, []byte(newContents), 0)

	return original, fInfo.Mode(), err
}

func readEventAPIStream(client proto.SkaffoldServiceClient, t *testing.T, retries int) (proto.SkaffoldService_EventLogClient, error) {
	t.Helper()
	// read the event log stream from the skaffold grpc server
	var stream proto.SkaffoldService_EventLogClient
	var err error
	for i := 0; i < retries; i++ {
		stream, err = client.EventLog(context.Background())
		if err != nil {
			t.Logf("waiting for connection...")
			time.Sleep(waitTime)
			continue
		}
	}
	return stream, err
}
<commit_msg>put namespace in correct place in function call<commit_after>/*
Copyright 2019 The Skaffold Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package integration

import (
	"context"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"strings"
	"testing"
	"time"

	"github.com/GoogleContainerTools/skaffold/integration/skaffold"
	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/util"
	"github.com/GoogleContainerTools/skaffold/proto"
	"github.com/GoogleContainerTools/skaffold/testutil"
	"github.com/sirupsen/logrus"
	"k8s.io/apimachinery/pkg/util/wait"
)

func TestDev(t *testing.T) {
	tests := []struct {
		description string
		trigger     string
	}{
		{
			description: "dev with polling trigger",
			trigger:     "polling",
		},
		{
			description: "dev with notify trigger",
			trigger:     "notify",
		},
	}
	for _, test := range tests {
		t.Run(test.description, func(t *testing.T) {
			if testing.Short() {
				t.Skip("skipping integration test")
			}
			if ShouldRunGCPOnlyTests() {
				t.Skip("skipping test that is not gcp only")
			}

			Run(t, "testdata/dev", "sh", "-c", "echo foo > foo")
			defer Run(t, "testdata/dev", "rm", "foo")

			// Run skaffold build first to fail quickly on a build failure
			skaffold.Build().InDir("testdata/dev").RunOrFail(t)

			ns, client, deleteNs := SetupNamespace(t)
			defer deleteNs()

			stop := skaffold.Dev("--trigger", test.trigger).InDir("testdata/dev").InNs(ns.Name).RunBackground(t)
			defer stop()

			dep := client.GetDeployment("test-dev")

			// Make a change to foo so that dev is forced to delete the Deployment and redeploy
			Run(t, "testdata/dev", "sh", "-c", "echo bar > foo")

			// Make sure the old Deployment and the new Deployment are different
			err := wait.PollImmediate(time.Millisecond*500, 10*time.Minute, func() (bool, error) {
				newDep := client.GetDeployment("test-dev")
				return dep.GetGeneration() != newDep.GetGeneration(), nil
			})
			testutil.CheckError(t, false, err)
		})
	}
}

func TestDevAPITriggers(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping integration test")
	}
	if ShouldRunGCPOnlyTests() {
		t.Skip("skipping test that is not gcp only")
	}

	Run(t, "testdata/dev", "sh", "-c", "echo foo > foo")
	defer Run(t, "testdata/dev", "rm", "foo")

	// Run skaffold build first to fail quickly on a build failure
	skaffold.Build().InDir("testdata/dev").RunOrFail(t)

	ns, k8sClient, deleteNs := SetupNamespace(t)
	defer deleteNs()

	rpcAddr := randomPort()

	stop := skaffold.Dev("--auto-build=false", "--auto-sync=false", "--auto-deploy=false", "--rpc-port", rpcAddr).InDir("testdata/dev").InNs(ns.Name).RunBackground(t)
	defer stop()

	client, shutdown := setupRPCClient(t, rpcAddr)
	defer shutdown()

	stream, err := readEventAPIStream(client, t, readRetries)
	if stream == nil {
		t.Fatalf("error retrieving event log: %v\n", err)
	}

	// throw away first 5 entries of log (from first run of dev loop)
	for i := 0; i < 5; i++ {
		stream.Recv()
	}

	// read entries from the log
	entries := make(chan *proto.LogEntry)
	go func() {
		for {
			entry, _ := stream.Recv()
			if entry != nil {
				entries <- entry
			}
		}
	}()

	dep := k8sClient.GetDeployment("test-dev")

	// Make a change to foo
	Run(t, "testdata/dev", "sh", "-c", "echo bar > foo")

	// Issue a build trigger
	client.Execute(context.Background(), &proto.UserIntentRequest{
		Intent: &proto.Intent{
			Build: true,
		},
	})

	// Ensure we see a build triggered in the event log
	err = wait.PollImmediate(time.Millisecond*500, 2*time.Minute, func() (bool, error) {
		e := <-entries
		return e.GetEvent().GetBuildEvent().GetArtifact() == "gcr.io/k8s-skaffold/test-dev", nil
	})
	testutil.CheckError(t, false, err)

	// Issue a deploy trigger
	client.Execute(context.Background(), &proto.UserIntentRequest{
		Intent: &proto.Intent{
			Deploy: true,
		},
	})

	// Ensure we see a deploy triggered in the event log
	err = wait.PollImmediate(time.Millisecond*500, 2*time.Minute, func() (bool, error) {
		e := <-entries
		return e.GetEvent().GetDeployEvent().GetStatus() == "In Progress", nil
	})
	testutil.CheckError(t, false, err)

	// Make sure the old Deployment and the new Deployment are different
	err = wait.PollImmediate(time.Millisecond*500, 10*time.Minute, func() (bool, error) {
		newDep := k8sClient.GetDeployment("test-dev")
		return dep.GetGeneration() != newDep.GetGeneration(), nil
	})
	testutil.CheckError(t, false, err)
}

func TestDevPortForward(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping integration test")
	}
	if ShouldRunGCPOnlyTests() {
		t.Skip("skipping test that is not gcp only")
	}

	// Run skaffold build first to fail quickly on a build failure
	skaffold.Build("--cache-artifacts=true").InDir("examples/microservices").RunOrFail(t)

	ns, _, deleteNs := SetupNamespace(t)
	defer deleteNs()

	rpcAddr := randomPort()
	env := []string{fmt.Sprintf("TEST_NS=%s", ns.Name)}
	cmd := skaffold.Dev("--port-forward", "--rpc-port", rpcAddr, "--cache-artifacts=true").InDir("examples/microservices").InNs(ns.Name).WithEnv(env)
	stop := cmd.RunBackground(t)
	defer stop()

	client, shutdown := setupRPCClient(t, rpcAddr)
	defer shutdown()

	// create a grpc connection. Increase number of reties for helm.
	stream, err := readEventAPIStream(client, t, 20)
	if stream == nil {
		t.Fatalf("error retrieving event log: %v\n", err)
	}

	// read entries from the log
	entries := make(chan *proto.LogEntry)
	go func() {
		for {
			entry, _ := stream.Recv()
			if entry != nil {
				entries <- entry
			}
		}
	}()

	originalResponse := "leeroooooy app!!"
	replacementResponse := "test string"

	waitForPortForwardEvent(t, entries, "leeroy-app", "service", ns.Name, originalResponse+"\n")

	original, perms, fErr := replaceInFile(originalResponse, replacementResponse, "examples/microservices/leeroy-app/app.go")
	if fErr != nil {
		t.Error(fErr)
	}
	defer func() {
		if original != nil {
			ioutil.WriteFile("examples/microservices/leeroy-app/app.go", original, perms)
		}
	}()

	waitForPortForwardEvent(t, entries, "leeroy-app", "service", ns.Name, replacementResponse+"\n")
}

func TestDevPortForwardGKELoadBalancer(t *testing.T) {
	if testing.Short() {
		t.Skip("skipping integration test")
	}
	if !ShouldRunGCPOnlyTests() {
		t.Skip("skipping test that is not gcp only")
	}

	// Run skaffold build first to fail quickly on a build failure
	skaffold.Build().InDir("testdata/gke_loadbalancer").RunOrFail(t)

	ns, _, deleteNs := SetupNamespace(t)
	defer deleteNs()

	rpcAddr := randomPort()
	env := []string{fmt.Sprintf("TEST_NS=%s", ns.Name)}
	cmd := skaffold.Dev("--port-forward", "--rpc-port", rpcAddr).InDir("testdata/gke_loadbalancer").InNs(ns.Name).WithEnv(env)
	stop := cmd.RunBackground(t)
	defer stop()

	client, shutdown := setupRPCClient(t, rpcAddr)
	defer shutdown()

	// create a grpc connection. Increase number of reties for helm.
	stream, err := readEventAPIStream(client, t, 20)
	if stream == nil {
		t.Fatalf("error retrieving event log: %v\n", err)
	}

	// read entries from the log
	entries := make(chan *proto.LogEntry)
	go func() {
		for {
			entry, _ := stream.Recv()
			if entry != nil {
				entries <- entry
			}
		}
	}()

	waitForPortForwardEvent(t, entries, "gke-loadbalancer", "service", ns.Name, "hello!!\n")
}

func getLocalPortFromPortForwardEvent(t *testing.T, entries chan *proto.LogEntry, resourceName, resourceType, namespace string) int {
	timeout := time.After(1 * time.Minute)
	for {
		select {
		case <-timeout:
			t.Fatalf("timed out waiting for port forwarding event")
		case e := <-entries:
			switch e.Event.GetEventType().(type) {
			case *proto.Event_PortEvent:
				t.Logf("event received %v", e)
				if e.Event.GetPortEvent().ResourceName == resourceName &&
					e.Event.GetPortEvent().ResourceType == resourceType &&
					e.Event.GetPortEvent().Namespace == namespace {
					port := e.Event.GetPortEvent().LocalPort
					t.Logf("Detected %s/%s is forwarded to port %d", resourceType, resourceName, port)
					return int(port)
				}
			default:
				t.Logf("event received %v", e)
			}
		}
	}
}

func waitForPortForwardEvent(t *testing.T, entries chan *proto.LogEntry, resourceName, resourceType, namespace, expected string) {
	port := getLocalPortFromPortForwardEvent(t, entries, resourceName, resourceType, namespace)
	assertResponseFromPort(t, port, expected)
}

// assertResponseFromPort waits for two minutes for the expected response at port.
func assertResponseFromPort(t *testing.T, port int, expected string) {
	logrus.Infof("Waiting for response %s from port %d", expected, port)
	ctx, cancelTimeout := context.WithTimeout(context.Background(), 2*time.Minute)
	defer cancelTimeout()

	for {
		select {
		case <-ctx.Done():
			t.Fatalf("Timed out waiting for response from port %d", port)
		case <-time.After(1 * time.Second):
			resp, err := http.Get(fmt.Sprintf("http://%s:%d", util.Loopback, port))
			if err != nil {
				logrus.Infof("error getting response from port %d: %v", port, err)
				continue
			}
			defer resp.Body.Close()
			body, err := ioutil.ReadAll(resp.Body)
			if err != nil {
				logrus.Infof("error reading response: %v", err)
				continue
			}
			if string(body) == expected {
				return
			}
			logrus.Infof("didn't get expected response from port. got: %s, expected: %s", string(body), expected)
		}
	}
}

func replaceInFile(target, replacement, filepath string) ([]byte, os.FileMode, error) {
	fInfo, err := os.Stat(filepath)
	if err != nil {
		return nil, 0, err
	}
	original, err := ioutil.ReadFile(filepath)
	if err != nil {
		return nil, 0, err
	}

	newContents := strings.Replace(string(original), target, replacement, -1)

	err = ioutil.WriteFile(filepath, []byte(newContents), 0)

	return original, fInfo.Mode(), err
}

func readEventAPIStream(client proto.SkaffoldServiceClient, t *testing.T, retries int) (proto.SkaffoldService_EventLogClient, error) {
	t.Helper()
	// read the event log stream from the skaffold grpc server
	var stream proto.SkaffoldService_EventLogClient
	var err error
	for i := 0; i < retries; i++ {
		stream, err = client.EventLog(context.Background())
		if err != nil {
			t.Logf("waiting for connection...")
			time.Sleep(waitTime)
			continue
		}
	}
	return stream, err
}
<|endoftext|>


<commit_before>package rps

import (
	"math/rand"
	"reflect"
	"testing"
	"time"
)

func TestRandomHand(t *testing.T) {
	rand.Seed(time.Now().UnixNano())
	v := RandomHand()
	vt := reflect.TypeOf(v)
	if vt.Kind() != reflect.Int {
		t.Error("expected an int, got", v)
	}
}

func TestPlay(t *testing.T) {
	var testcases = []struct {
		p1, p2   int
		expected int
	}{
		// tie
		{Rock, Rock, Tie},
		{Paper, Paper, Tie},
		{Scissors, Scissors, Tie},

		// p1 wins
		{Rock, Scissors, WinP1},
		{Paper, Rock, WinP1},
		{Scissors, Paper, WinP1},

		// p2 wins
		{Rock, Paper, WinP2},
		{Paper, Scissors, WinP2},
		{Scissors, Rock, WinP2},
	}

	for _, c := range testcases {
		r := Play(c.p1, c.p2)
		if r != c.expected {
			t.Errorf("expected: %v, got: %v", c.expected, r)
		}
	}
}
<commit_msg>Simplify TestRandomHand()<commit_after>package rps

import (
	"math/rand"
	"testing"
	"time"
)

func TestRandomHand(t *testing.T) {
	rand.Seed(time.Now().UnixNano())
	if v := RandomHand(); v > 2 || v < 0 {
		t.Error("expected an int value between 0 and 2, got", v)
	}
}

func TestPlay(t *testing.T) {
	var testcases = []struct {
		p1, p2   int
		expected int
	}{
		// tie
		{Rock, Rock, Tie},
		{Paper, Paper, Tie},
		{Scissors, Scissors, Tie},

		// p1 wins
		{Rock, Scissors, WinP1},
		{Paper, Rock, WinP1},
		{Scissors, Paper, WinP1},

		// p2 wins
		{Rock, Paper, WinP2},
		{Paper, Scissors, WinP2},
		{Scissors, Rock, WinP2},
	}

	for _, c := range testcases {
		r := Play(c.p1, c.p2)
		if r != c.expected {
			t.Errorf("expected: %v, got: %v", c.expected, r)
		}
	}
}
<|endoftext|>


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

// Package kubernetes listens to Kubernetes for policy updates.
package kubernetes

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/golang/glog"
	"github.com/romana/core/common"
	"github.com/romana/core/tenant"
	"net/http"
	"strings"

	"k8s.io/client-go/1.5/kubernetes"
	"k8s.io/client-go/1.5/tools/cache"
	"k8s.io/client-go/1.5/tools/clientcmd"
)

type networkPolicyAction int

const (
	networkPolicyActionDelete networkPolicyAction = iota
	networkPolicyActionAdd
	networkPolicyActionModify
)

const (
	HttpGetParamWatch           = "watch=true"
	HttpGetParamResourceVersion = "resourceVersion"
)

// kubeListener is a Service that listens to updates
// from Kubernetes by connecting to the endpoints specified
// and consuming chunked JSON documents. The endpoints are
// constructed from kubeURL and the following paths:
// 1. namespaceNotificationPath for namespace additions/deletions
// 2. policyNotificationPathPrefix + <namespace name> + policyNotificationPathPostfix
//    for policy additions/deletions.
type kubeListener struct {
	config                        common.ServiceConfig
	restClient                    *common.RestClient
	kubeURL                       string
	namespaceNotificationPath     string
	policyNotificationPathPrefix  string
	policyNotificationPathPostfix string
	segmentLabelName              string
	lastEventPerNamespace         map[string]uint64
	namespaceBufferSize           uint64

	kubeClient		      *kubernetes.Clientset
	Watchers		      map[string]cache.ListerWatcher
}

// Routes returns various routes used in the service.
func (l *kubeListener) Routes() common.Routes {
	routes := common.Routes{}
	return routes
}

// Name implements method of Service interface.
func (l *kubeListener) Name() string {
	return "kubernetesListener"
}

// SetConfig implements SetConfig function of the Service interface.
func (l *kubeListener) SetConfig(config common.ServiceConfig) error {
	m := config.ServiceSpecific
	if m["kubernetes_url"] == "" {
		return errors.New("kubernetes_url required")
	}
	l.kubeURL = m["kubernetes_url"].(string)

	if m["namespace_notification_path"] == "" {
		return errors.New("namespace_notification_path required")
	}
	l.namespaceNotificationPath = m["namespace_notification_path"].(string)

	if m["policy_notification_path_prefix"] == "" {
		return errors.New("policy_notification_path_prefix required")
	}
	l.policyNotificationPathPrefix = m["policy_notification_path_prefix"].(string)

	if m["policy_notification_path_postfix"] == "" {
		return errors.New("policy_notification_path_postfix required")
	}
	l.policyNotificationPathPostfix = m["policy_notification_path_postfix"].(string)

	if m["segment_label_name"] == "" {
		return errors.New("segment_label_name required")
	}
	l.segmentLabelName = m["segment_label_name"].(string)

	// TODO, what is `wait_for_iface_try` and why namespaceBufferSize is set instead ? Stas.
	if m["wait_for_iface_try"] == nil {
		l.namespaceBufferSize = 10
	} else {
		l.namespaceBufferSize = uint64(m["namespace_buffer_size"].(float64))
	}
	l.namespaceBufferSize = 1000

	if m["kubernetes_config"] == nil {
		m["kubernetes_config"] = "/etc/romana/kubeconfig"
	}

	// TODO, this loads kubernetes config from flags provided in main
	// should be loading from path provided by romana-root. Stas.
	kubeClientConfig, err := clientcmd.BuildConfigFromFlags("", m["kubernetes_config"].(string))
	if err != nil {
		return errors.New(fmt.Sprintf("Failed to load kubernetes kubeClientConfig %s", err))
	}
	clientset, err := kubernetes.NewForConfig(kubeClientConfig)
	if err != nil {
		return errors.New(fmt.Sprintf("Failed to make kubernetes client %s", err))
	}
	l.kubeClient = clientset

	// TODO, find a better place to initialize
	// the translator. Stas.
	PTranslator.Init(l.restClient, l.segmentLabelName)
	tc := PTranslator.GetClient()
	if tc == nil {
		glog.Fatal("DEBUG Translator has nil client after Init")
	}

	return nil
}

// TODO there should be a better way to introduce translator
// then global variable like this one.
var PTranslator Translator

// Run configures and runs listener service.
func Run(rootServiceURL string, cred *common.Credential) (*common.RestServiceInfo, error) {
	clientConfig := common.GetDefaultRestClientConfig(rootServiceURL)
	clientConfig.Credential = cred
	client, err := common.NewRestClient(clientConfig)
	if err != nil {
		return nil, err
	}
	kubeListener := &kubeListener{}
	kubeListener.restClient = client

	config, err := client.GetServiceConfig(kubeListener.Name())
	if err != nil {
		return nil, err
	}
	return common.InitializeService(kubeListener, *config)
}

// getOrAddSegment finds a segment (based on segment selector).
// If not found, it adds one.
func (l *kubeListener) getOrAddSegment(namespace string, kubeSegmentName string) (*tenant.Segment, error) {
	ten := &tenant.Tenant{}
	ten.Name = namespace
	// TODO this should be changed to find EXACTLY one after deletion functionality is implemented
	err := l.restClient.Find(ten, common.FindLast)
	if err != nil {
		return nil, err
	}

	seg := &tenant.Segment{}
	seg.Name = kubeSegmentName
	seg.TenantID = ten.ID
	err = l.restClient.Find(seg, common.FindExactlyOne)
	if err == nil {
		return seg, nil
	}

	switch err := err.(type) {
	case common.HttpError:
		if err.StatusCode == http.StatusNotFound {
			// Not found, so let's create a segment.
			segreq := tenant.Segment{Name: kubeSegmentName, TenantID: ten.ID}
			segURL, err2 := l.restClient.GetServiceUrl("tenant")
			if err2 != nil {
				return nil, err2
			}
			segURL = fmt.Sprintf("%s/tenants/%d/segments", segURL, ten.ID)
			err2 = l.restClient.Post(segURL, segreq, seg)
			if err2 == nil {
				// Successful creation.
				return seg, nil
			}
			// Creation of non-existing segment gave an error.
			switch err2 := err2.(type) {
			case common.HttpError:
				// Maybe someone else just created a segment between the original
				// lookup and now?
				if err2.StatusCode == http.StatusConflict {
					switch details := err2.Details.(type) {
					case tenant.Segment:
						// We expect the existing segment to be returned in the details field.
						return &details, nil
					default:
						// This is unexpected...
						return nil, err
					}
				}
				// Any other HTTP error other than a Conflict here - return it.
				return nil, err2
			default:
				// Any other error - return it
				return nil, err2
			}
		}
		// Any other HTTP error other than a Not found here - return it
		return nil, err
	default:
		// Any other error - return it
		return nil, err
	}
}

// resolveTenantByName retrieves tenant information from romana.
func (l *kubeListener) resolveTenantByName(tenantName string) (*tenant.Tenant, error) {
	t := &tenant.Tenant{Name: tenantName}
	err := l.restClient.Find(t, common.FindLast)
	if err != nil {
		return t, err
	}
	return t, nil
}

// translateNetworkPolicy translates a Kubernetes policy into
// Romana policy (see common.Policy) with the following rules:
// 1. Kubernetes Namespace corresponds to Romana Tenant
// 2. If Romana Tenant does not exist it is an error (a tenant should
//    automatically have been created when the namespace was added)
func (l *kubeListener) translateNetworkPolicy(kubePolicy *KubeObject) (common.Policy, error) {
	policyName := kubePolicy.Metadata.Name
	romanaPolicy := &common.Policy{Direction: common.PolicyDirectionIngress, Name: policyName, ExternalID: kubePolicy.Metadata.Uid}
	ns := kubePolicy.Metadata.Namespace
	// TODO actually look up tenant K8S ID.
	t, err := l.resolveTenantByName(ns)
	if err != nil {
		return *romanaPolicy, err
	}
	glog.Infof("translateNetworkPolicy(): For namespace %s got %+v / %+v", ns, t, err)
	tenantID := t.ID
	tenantExternalID := t.ExternalID

	kubeSegmentID := kubePolicy.Spec.PodSelector.MatchLabels[l.segmentLabelName]
	if kubeSegmentID == "" {
		return *romanaPolicy, common.NewError("Expected segment to be specified in podSelector part as '%s'", l.segmentLabelName)
	}

	segment, err := l.getOrAddSegment(ns, kubeSegmentID)
	//	log.Printf("XXXX getOrAddSegment %s %s: %+v %v", ns, kubeSegmentID, segment, err)
	if err != nil {
		return *romanaPolicy, err
	}
	segmentID := segment.ID
	appliedTo := common.Endpoint{TenantID: tenantID, SegmentID: segmentID}
	//	log.Printf("XXXX 0 %+v %d %d", appliedTo, tenantID, segmentID)
	//	log.Printf("XXXX 1 %+v", romanaPolicy.AppliedTo)
	romanaPolicy.AppliedTo = make([]common.Endpoint, 1)
	romanaPolicy.AppliedTo[0] = appliedTo
	//	log.Printf("XXXX 2 %+v %d expecting %+v", romanaPolicy.AppliedTo, len(romanaPolicy.AppliedTo), appliedTo)
	romanaPolicy.Peers = make([]common.Endpoint, 0)
	romanaPolicy.Rules = make([]common.Rule, 0)
	// TODO range
	// from := kubePolicy.Spec.Ingress[0].From
	// This is subject to change once the network specification in Kubernetes is finalized.
	// Right now it is a work in progress.
	glog.Infof("YYYYY For %s processing %+v", kubePolicy.Metadata.Name, kubePolicy.Spec.Ingress)
	for _, ingress := range kubePolicy.Spec.Ingress {
		for _, entry := range ingress.From {
			pods := entry.Pods
			fromKubeSegmentID := pods.MatchLabels[l.segmentLabelName]
			if fromKubeSegmentID == "" {
				return *romanaPolicy, common.NewError("Expected segment to be specified in podSelector part as '%s'", l.segmentLabelName)
			}
			fromSegment, err := l.getOrAddSegment(ns, fromKubeSegmentID)
			if err != nil {
				return *romanaPolicy, err
			}
			peer := common.Endpoint{TenantID: tenantID, TenantExternalID: tenantExternalID, SegmentID: fromSegment.ID, SegmentExternalID: fromSegment.ExternalID}
			romanaPolicy.Peers = append(romanaPolicy.Peers, peer)
		}
		for _, toPort := range ingress.ToPorts {
			proto := strings.ToLower(toPort.Protocol)
			ports := []uint{toPort.Port}
			rule := common.Rule{Protocol: proto, Ports: ports}
			romanaPolicy.Rules = append(romanaPolicy.Rules, rule)
			glog.Infof("YYYYY %+v", romanaPolicy.Rules)
		}
	}
	glog.Infof("translateNetworkPolicy(): Validating %+v", romanaPolicy)
	err = romanaPolicy.Validate()
	if err != nil {
		return *romanaPolicy, err
	}
	return *romanaPolicy, nil
}

func (l *kubeListener) applyNetworkPolicy(action networkPolicyAction, romanaNetworkPolicy common.Policy) error {
	policyURL, err := l.restClient.GetServiceUrl("policy")
	if err != nil {
		return err
	}
	policyURL = fmt.Sprintf("%s/policies", policyURL)
	policyStr, _ := json.Marshal(romanaNetworkPolicy)
	switch action {
	case networkPolicyActionAdd:
		glog.Infof("Applying policy %s", policyStr)
		err := l.restClient.Post(policyURL, romanaNetworkPolicy, &romanaNetworkPolicy)
		if err != nil {
			return err
		}
	case networkPolicyActionDelete:
		glog.Infof("Deleting policy policy %s", policyStr)
		err := l.restClient.Delete(policyURL, romanaNetworkPolicy, &romanaNetworkPolicy)
		if err != nil {
			return err
		}
	default:
		return errors.New("Unsupported operation")
	}
	return nil
}

func (l *kubeListener) Initialize() error {
	l.lastEventPerNamespace = make(map[string]uint64)
	glog.Infof("%s: Starting server", l.Name())
	nsURL, err := common.CleanURL(fmt.Sprintf("%s/%s/?%s", l.kubeURL, l.namespaceNotificationPath, HttpGetParamWatch))
	if err != nil {
		return err
	}
	glog.Infof("Starting to listen on %s", nsURL)
	done := make(chan struct{})
	eventc, err := l.nsWatch(done, nsURL)
	if err != nil {
		glog.Fatal("Namespace watcher failed to start", err)
	}

	// events := l.conductor(nsEvents, done)
	l.process(eventc, done)

	ProduceNewPolicyEvents(eventc, done, l)

	glog.Infoln("All routines started")
	return nil
}

// CreateSchema is placeholder for now.
func CreateSchema(rootServiceURL string, overwrite bool) error {
	return nil
}
<commit_msg>Change default config path<commit_after>// Copyright (c) 2016 Pani Networks
// All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

// Package kubernetes listens to Kubernetes for policy updates.
package kubernetes

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/golang/glog"
	"github.com/romana/core/common"
	"github.com/romana/core/tenant"
	"net/http"
	"strings"

	"k8s.io/client-go/1.5/kubernetes"
	"k8s.io/client-go/1.5/tools/cache"
	"k8s.io/client-go/1.5/tools/clientcmd"
)

type networkPolicyAction int

const (
	networkPolicyActionDelete networkPolicyAction = iota
	networkPolicyActionAdd
	networkPolicyActionModify
)

const (
	HttpGetParamWatch           = "watch=true"
	HttpGetParamResourceVersion = "resourceVersion"
)

// kubeListener is a Service that listens to updates
// from Kubernetes by connecting to the endpoints specified
// and consuming chunked JSON documents. The endpoints are
// constructed from kubeURL and the following paths:
// 1. namespaceNotificationPath for namespace additions/deletions
// 2. policyNotificationPathPrefix + <namespace name> + policyNotificationPathPostfix
//    for policy additions/deletions.
type kubeListener struct {
	config                        common.ServiceConfig
	restClient                    *common.RestClient
	kubeURL                       string
	namespaceNotificationPath     string
	policyNotificationPathPrefix  string
	policyNotificationPathPostfix string
	segmentLabelName              string
	lastEventPerNamespace         map[string]uint64
	namespaceBufferSize           uint64

	kubeClient		      *kubernetes.Clientset
	Watchers		      map[string]cache.ListerWatcher
}

// Routes returns various routes used in the service.
func (l *kubeListener) Routes() common.Routes {
	routes := common.Routes{}
	return routes
}

// Name implements method of Service interface.
func (l *kubeListener) Name() string {
	return "kubernetesListener"
}

// SetConfig implements SetConfig function of the Service interface.
func (l *kubeListener) SetConfig(config common.ServiceConfig) error {
	m := config.ServiceSpecific
	if m["kubernetes_url"] == "" {
		return errors.New("kubernetes_url required")
	}
	l.kubeURL = m["kubernetes_url"].(string)

	if m["namespace_notification_path"] == "" {
		return errors.New("namespace_notification_path required")
	}
	l.namespaceNotificationPath = m["namespace_notification_path"].(string)

	if m["policy_notification_path_prefix"] == "" {
		return errors.New("policy_notification_path_prefix required")
	}
	l.policyNotificationPathPrefix = m["policy_notification_path_prefix"].(string)

	if m["policy_notification_path_postfix"] == "" {
		return errors.New("policy_notification_path_postfix required")
	}
	l.policyNotificationPathPostfix = m["policy_notification_path_postfix"].(string)

	if m["segment_label_name"] == "" {
		return errors.New("segment_label_name required")
	}
	l.segmentLabelName = m["segment_label_name"].(string)

	// TODO, what is `wait_for_iface_try` and why namespaceBufferSize is set instead ? Stas.
	if m["wait_for_iface_try"] == nil {
		l.namespaceBufferSize = 10
	} else {
		l.namespaceBufferSize = uint64(m["namespace_buffer_size"].(float64))
	}
	l.namespaceBufferSize = 1000

	if m["kubernetes_config"] == nil {
		m["kubernetes_config"] = "/home/ubuntu/.kube/config""
	}

	// TODO, this loads kubernetes config from flags provided in main
	// should be loading from path provided by romana-root. Stas.
	kubeClientConfig, err := clientcmd.BuildConfigFromFlags("", m["kubernetes_config"].(string))
	if err != nil {
		return errors.New(fmt.Sprintf("Failed to load kubernetes kubeClientConfig %s", err))
	}
	clientset, err := kubernetes.NewForConfig(kubeClientConfig)
	if err != nil {
		return errors.New(fmt.Sprintf("Failed to make kubernetes client %s", err))
	}
	l.kubeClient = clientset

	// TODO, find a better place to initialize
	// the translator. Stas.
	PTranslator.Init(l.restClient, l.segmentLabelName)
	tc := PTranslator.GetClient()
	if tc == nil {
		glog.Fatal("DEBUG Translator has nil client after Init")
	}

	return nil
}

// TODO there should be a better way to introduce translator
// then global variable like this one.
var PTranslator Translator

// Run configures and runs listener service.
func Run(rootServiceURL string, cred *common.Credential) (*common.RestServiceInfo, error) {
	clientConfig := common.GetDefaultRestClientConfig(rootServiceURL)
	clientConfig.Credential = cred
	client, err := common.NewRestClient(clientConfig)
	if err != nil {
		return nil, err
	}
	kubeListener := &kubeListener{}
	kubeListener.restClient = client

	config, err := client.GetServiceConfig(kubeListener.Name())
	if err != nil {
		return nil, err
	}
	return common.InitializeService(kubeListener, *config)
}

// getOrAddSegment finds a segment (based on segment selector).
// If not found, it adds one.
func (l *kubeListener) getOrAddSegment(namespace string, kubeSegmentName string) (*tenant.Segment, error) {
	ten := &tenant.Tenant{}
	ten.Name = namespace
	// TODO this should be changed to find EXACTLY one after deletion functionality is implemented
	err := l.restClient.Find(ten, common.FindLast)
	if err != nil {
		return nil, err
	}

	seg := &tenant.Segment{}
	seg.Name = kubeSegmentName
	seg.TenantID = ten.ID
	err = l.restClient.Find(seg, common.FindExactlyOne)
	if err == nil {
		return seg, nil
	}

	switch err := err.(type) {
	case common.HttpError:
		if err.StatusCode == http.StatusNotFound {
			// Not found, so let's create a segment.
			segreq := tenant.Segment{Name: kubeSegmentName, TenantID: ten.ID}
			segURL, err2 := l.restClient.GetServiceUrl("tenant")
			if err2 != nil {
				return nil, err2
			}
			segURL = fmt.Sprintf("%s/tenants/%d/segments", segURL, ten.ID)
			err2 = l.restClient.Post(segURL, segreq, seg)
			if err2 == nil {
				// Successful creation.
				return seg, nil
			}
			// Creation of non-existing segment gave an error.
			switch err2 := err2.(type) {
			case common.HttpError:
				// Maybe someone else just created a segment between the original
				// lookup and now?
				if err2.StatusCode == http.StatusConflict {
					switch details := err2.Details.(type) {
					case tenant.Segment:
						// We expect the existing segment to be returned in the details field.
						return &details, nil
					default:
						// This is unexpected...
						return nil, err
					}
				}
				// Any other HTTP error other than a Conflict here - return it.
				return nil, err2
			default:
				// Any other error - return it
				return nil, err2
			}
		}
		// Any other HTTP error other than a Not found here - return it
		return nil, err
	default:
		// Any other error - return it
		return nil, err
	}
}

// resolveTenantByName retrieves tenant information from romana.
func (l *kubeListener) resolveTenantByName(tenantName string) (*tenant.Tenant, error) {
	t := &tenant.Tenant{Name: tenantName}
	err := l.restClient.Find(t, common.FindLast)
	if err != nil {
		return t, err
	}
	return t, nil
}

// translateNetworkPolicy translates a Kubernetes policy into
// Romana policy (see common.Policy) with the following rules:
// 1. Kubernetes Namespace corresponds to Romana Tenant
// 2. If Romana Tenant does not exist it is an error (a tenant should
//    automatically have been created when the namespace was added)
func (l *kubeListener) translateNetworkPolicy(kubePolicy *KubeObject) (common.Policy, error) {
	policyName := kubePolicy.Metadata.Name
	romanaPolicy := &common.Policy{Direction: common.PolicyDirectionIngress, Name: policyName, ExternalID: kubePolicy.Metadata.Uid}
	ns := kubePolicy.Metadata.Namespace
	// TODO actually look up tenant K8S ID.
	t, err := l.resolveTenantByName(ns)
	if err != nil {
		return *romanaPolicy, err
	}
	glog.Infof("translateNetworkPolicy(): For namespace %s got %+v / %+v", ns, t, err)
	tenantID := t.ID
	tenantExternalID := t.ExternalID

	kubeSegmentID := kubePolicy.Spec.PodSelector.MatchLabels[l.segmentLabelName]
	if kubeSegmentID == "" {
		return *romanaPolicy, common.NewError("Expected segment to be specified in podSelector part as '%s'", l.segmentLabelName)
	}

	segment, err := l.getOrAddSegment(ns, kubeSegmentID)
	//	log.Printf("XXXX getOrAddSegment %s %s: %+v %v", ns, kubeSegmentID, segment, err)
	if err != nil {
		return *romanaPolicy, err
	}
	segmentID := segment.ID
	appliedTo := common.Endpoint{TenantID: tenantID, SegmentID: segmentID}
	//	log.Printf("XXXX 0 %+v %d %d", appliedTo, tenantID, segmentID)
	//	log.Printf("XXXX 1 %+v", romanaPolicy.AppliedTo)
	romanaPolicy.AppliedTo = make([]common.Endpoint, 1)
	romanaPolicy.AppliedTo[0] = appliedTo
	//	log.Printf("XXXX 2 %+v %d expecting %+v", romanaPolicy.AppliedTo, len(romanaPolicy.AppliedTo), appliedTo)
	romanaPolicy.Peers = make([]common.Endpoint, 0)
	romanaPolicy.Rules = make([]common.Rule, 0)
	// TODO range
	// from := kubePolicy.Spec.Ingress[0].From
	// This is subject to change once the network specification in Kubernetes is finalized.
	// Right now it is a work in progress.
	glog.Infof("YYYYY For %s processing %+v", kubePolicy.Metadata.Name, kubePolicy.Spec.Ingress)
	for _, ingress := range kubePolicy.Spec.Ingress {
		for _, entry := range ingress.From {
			pods := entry.Pods
			fromKubeSegmentID := pods.MatchLabels[l.segmentLabelName]
			if fromKubeSegmentID == "" {
				return *romanaPolicy, common.NewError("Expected segment to be specified in podSelector part as '%s'", l.segmentLabelName)
			}
			fromSegment, err := l.getOrAddSegment(ns, fromKubeSegmentID)
			if err != nil {
				return *romanaPolicy, err
			}
			peer := common.Endpoint{TenantID: tenantID, TenantExternalID: tenantExternalID, SegmentID: fromSegment.ID, SegmentExternalID: fromSegment.ExternalID}
			romanaPolicy.Peers = append(romanaPolicy.Peers, peer)
		}
		for _, toPort := range ingress.ToPorts {
			proto := strings.ToLower(toPort.Protocol)
			ports := []uint{toPort.Port}
			rule := common.Rule{Protocol: proto, Ports: ports}
			romanaPolicy.Rules = append(romanaPolicy.Rules, rule)
			glog.Infof("YYYYY %+v", romanaPolicy.Rules)
		}
	}
	glog.Infof("translateNetworkPolicy(): Validating %+v", romanaPolicy)
	err = romanaPolicy.Validate()
	if err != nil {
		return *romanaPolicy, err
	}
	return *romanaPolicy, nil
}

func (l *kubeListener) applyNetworkPolicy(action networkPolicyAction, romanaNetworkPolicy common.Policy) error {
	policyURL, err := l.restClient.GetServiceUrl("policy")
	if err != nil {
		return err
	}
	policyURL = fmt.Sprintf("%s/policies", policyURL)
	policyStr, _ := json.Marshal(romanaNetworkPolicy)
	switch action {
	case networkPolicyActionAdd:
		glog.Infof("Applying policy %s", policyStr)
		err := l.restClient.Post(policyURL, romanaNetworkPolicy, &romanaNetworkPolicy)
		if err != nil {
			return err
		}
	case networkPolicyActionDelete:
		glog.Infof("Deleting policy policy %s", policyStr)
		err := l.restClient.Delete(policyURL, romanaNetworkPolicy, &romanaNetworkPolicy)
		if err != nil {
			return err
		}
	default:
		return errors.New("Unsupported operation")
	}
	return nil
}

func (l *kubeListener) Initialize() error {
	l.lastEventPerNamespace = make(map[string]uint64)
	glog.Infof("%s: Starting server", l.Name())
	nsURL, err := common.CleanURL(fmt.Sprintf("%s/%s/?%s", l.kubeURL, l.namespaceNotificationPath, HttpGetParamWatch))
	if err != nil {
		return err
	}
	glog.Infof("Starting to listen on %s", nsURL)
	done := make(chan struct{})
	eventc, err := l.nsWatch(done, nsURL)
	if err != nil {
		glog.Fatal("Namespace watcher failed to start", err)
	}

	// events := l.conductor(nsEvents, done)
	l.process(eventc, done)

	ProduceNewPolicyEvents(eventc, done, l)

	glog.Infoln("All routines started")
	return nil
}

// CreateSchema is placeholder for now.
func CreateSchema(rootServiceURL string, overwrite bool) error {
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"time"
)

// Roll rolls n dice with values in the range [1,d], and returns
// their values in the order they were rolled.
func roll(n, d int) []int {
	dice := make([]int, n)
	for i := range dice {
		dice[i] = rand.Intn(d) + 1
	}
	return dice
}

func main() {
	rand.Seed(time.Now().UnixNano())

	if len(os.Args) < 3 {
		println("Not enough arguments")
		return
	}

	n, err := strconv.Atoi(os.Args[1])
	if err != nil || n < 0 {
		println("First argument must be non-negative integer")
		return
	}

	f, err := strconv.Atoi(os.Args[2])
	if err != nil || f <= 0 {
		println("Second argument must be positive integer")
		return
	}

	// fmt.Printf("Rolling %dd%d+%d\n", n, f, s)

	dice := roll(n, f)

	if len(os.Args) > 3 {
		s, err := strconv.Atoi(os.Args[3])
		if err != nil {
			println("Third argument must be integer")
			return
		}

		for i := range dice {
			s += dice[i]
		}
		fmt.Println(s)
	} else {
		for i := range dice {
			fmt.Println(dice[i])
		}
	}
}
<commit_msg>More detailed usage and errors<commit_after>package main

import (
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"time"
)

// Roll rolls n dice with values in the range [1,d], and returns
// their values in the order they were rolled.
func roll(n, d int) []int {
	dice := make([]int, n)
	for i := range dice {
		dice[i] = rand.Intn(d) + 1
	}
	return dice
}

func main() {
	rand.Seed(time.Now().UnixNano())

	if len(os.Args) < 3 {
        println("  Usage:")
        println("      rolldice <num> <faces> [modifier]")
        println("  Rolls <num> dice, each with <faces> number of faces in range [1, <faces>].\n")

        println("  If [modifier] is not given, the dice are printed, one per line.")
        println("  If [modifier] is given, the sum of all the dice, plus the modifier, is")
        println("  printed. The individual rolls will not be printed.\n")

		println("  <num> must be a non-negative integer. <faces> must be a positive integer.")
        println("  [modifier] must be an integer (can be any sign, or zero).")

		return
	}

	n, err := strconv.Atoi(os.Args[1])
	if err != nil || n < 0 {
		println("<num> must be non-negative integer")
		return
	}

	f, err := strconv.Atoi(os.Args[2])
	if err != nil || f <= 0 {
		println("<faces> must be positive integer")
		return
	}

	dice := roll(n, f)

	if len(os.Args) > 3 {
		s, err := strconv.Atoi(os.Args[3])
		if err != nil {
			println("[modifier] must be integer")
			return
		}

		for i := range dice {
			s += dice[i]
		}
		fmt.Println(s)
	} else {
		for i := range dice {
			fmt.Println(dice[i])
		}
	}
}
<|endoftext|>


<commit_before>package btconn

import (
	"bytes"
	"net"
	"time"

	"github.com/cenkalti/rain/internal/logger"
	"github.com/cenkalti/rain/internal/mse"
)

func Dial(
	addr net.Addr,
	enableEncryption,
	forceEncryption bool,
	ourExtensions [8]byte,
	ih [20]byte,
	ourID [20]byte) (
	conn net.Conn, cipher mse.CryptoMethod, peerExtensions [8]byte, peerID [20]byte, err error) {

	log := logger.New("conn -> " + addr.String())

	// First connection
	log.Debug("Connecting to peer...")
	conn, err = net.DialTimeout(addr.Network(), addr.String(), handshakeDeadline)
	if err != nil {
		return
	}
	log.Debug("Connected")
	defer func() {
		if err != nil {
			cerr := conn.Close()
			if cerr != nil {
				log.Debugln("error while closing connection:", cerr)
			}
		}
	}()

	out := bytes.NewBuffer(make([]byte, 0, 68))
	err = writeHandshake(out, ih, ourID, ourExtensions)
	if err != nil {
		return
	}

	if enableEncryption {
		sKey := make([]byte, 20)
		copy(sKey, ih[:])

		provide := mse.RC4
		if !forceEncryption {
			provide |= mse.PlainText
		}

		// Try encryption handshake
		encConn := mse.WrapConn(conn)
		cipher, err = encConn.HandshakeOutgoing(sKey, provide, out.Bytes())
		if err != nil {
			log.Debugln("Encrytpion handshake has failed: ", err)
			if forceEncryption {
				log.Debug("Will not try again because ougoing encryption is forced.")
				err = errNotEncrypted
				return
			}
			// TODO close unencrypted conn
			// Connect again and try w/o encryption
			log.Debug("Connecting again without encryption...")
			conn, err = net.DialTimeout(addr.Network(), addr.String(), handshakeDeadline)
			if err != nil {
				return
			}
			log.Debug("Connected")
			// Send BT handshake
			if err = conn.SetWriteDeadline(time.Now().Add(handshakeDeadline)); err != nil {
				return
			}
			if _, err = conn.Write(out.Bytes()); err != nil {
				return
			}
		} else {
			log.Debugf("Encryption handshake is successfull. Selected cipher: %d", cipher)
			conn = encConn
			if forceEncryption && cipher == mse.PlainText {
				err = errNotEncrypted
				return
			}
		}
	} else {
		// Send BT handshake
		if err = conn.SetWriteDeadline(time.Now().Add(handshakeDeadline)); err != nil {
			return
		}
		if _, err = conn.Write(out.Bytes()); err != nil {
			return
		}
	}

	// Read BT handshake
	if err = conn.SetReadDeadline(time.Now().Add(handshakeDeadline)); err != nil {
		return
	}

	var ihRead [20]byte
	peerExtensions, ihRead, err = readHandshake1(conn)
	if err != nil {
		return
	}
	if ihRead != ih {
		err = errInvalidInfoHash
		return
	}

	peerID, err = readHandshake2(conn)
	if err != nil {
		return
	}
	if peerID == ourID {
		err = ErrOwnConnection
		return
	}

	err = conn.SetDeadline(time.Time{})
	return
}
<commit_msg>close previous connection in handshake retry<commit_after>package btconn

import (
	"bytes"
	"net"
	"time"

	"github.com/cenkalti/rain/internal/logger"
	"github.com/cenkalti/rain/internal/mse"
)

func Dial(
	addr net.Addr,
	enableEncryption,
	forceEncryption bool,
	ourExtensions [8]byte,
	ih [20]byte,
	ourID [20]byte) (
	conn net.Conn, cipher mse.CryptoMethod, peerExtensions [8]byte, peerID [20]byte, err error) {

	log := logger.New("conn -> " + addr.String())

	// First connection
	log.Debug("Connecting to peer...")
	conn, err = net.DialTimeout(addr.Network(), addr.String(), handshakeDeadline)
	if err != nil {
		return
	}
	log.Debug("Connected")
	defer func() {
		if err != nil {
			cerr := conn.Close()
			if cerr != nil {
				log.Debugln("error while closing connection:", cerr)
			}
		}
	}()

	out := bytes.NewBuffer(make([]byte, 0, 68))
	err = writeHandshake(out, ih, ourID, ourExtensions)
	if err != nil {
		return
	}

	if enableEncryption {
		sKey := make([]byte, 20)
		copy(sKey, ih[:])

		provide := mse.RC4
		if !forceEncryption {
			provide |= mse.PlainText
		}

		// Try encryption handshake
		encConn := mse.WrapConn(conn)
		cipher, err = encConn.HandshakeOutgoing(sKey, provide, out.Bytes())
		if err != nil {
			log.Debugln("Encrytpion handshake has failed: ", err)
			if forceEncryption {
				log.Debug("Will not try again because ougoing encryption is forced.")
				err = errNotEncrypted
				return
			}
			// Close current connection
			err = conn.Close()
			if err != nil {
				return
			}
			// Connect again and try w/o encryption
			log.Debug("Connecting again without encryption...")
			conn, err = net.DialTimeout(addr.Network(), addr.String(), handshakeDeadline)
			if err != nil {
				return
			}
			log.Debug("Connected")
			// Send BT handshake
			if err = conn.SetWriteDeadline(time.Now().Add(handshakeDeadline)); err != nil {
				return
			}
			if _, err = conn.Write(out.Bytes()); err != nil {
				return
			}
		} else {
			log.Debugf("Encryption handshake is successfull. Selected cipher: %d", cipher)
			conn = encConn
			if forceEncryption && cipher == mse.PlainText {
				err = errNotEncrypted
				return
			}
		}
	} else {
		// Send BT handshake
		if err = conn.SetWriteDeadline(time.Now().Add(handshakeDeadline)); err != nil {
			return
		}
		if _, err = conn.Write(out.Bytes()); err != nil {
			return
		}
	}

	// Read BT handshake
	if err = conn.SetReadDeadline(time.Now().Add(handshakeDeadline)); err != nil {
		return
	}

	var ihRead [20]byte
	peerExtensions, ihRead, err = readHandshake1(conn)
	if err != nil {
		return
	}
	if ihRead != ih {
		err = errInvalidInfoHash
		return
	}

	peerID, err = readHandshake2(conn)
	if err != nil {
		return
	}
	if peerID == ourID {
		err = ErrOwnConnection
		return
	}

	err = conn.SetDeadline(time.Time{})
	return
}
<|endoftext|>


<commit_before>package cache

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"time"

	"github.com/pkg/errors"
	"github.com/restic/restic/internal/debug"
	"github.com/restic/restic/internal/fs"
	"github.com/restic/restic/internal/restic"
)

// Cache manages a local cache.
type Cache struct {
	path    string
	Base    string
	Created bool
}

const dirMode = 0700
const fileMode = 0644

func readVersion(dir string) (v uint, err error) {
	buf, err := ioutil.ReadFile(filepath.Join(dir, "version"))
	if errors.Is(err, os.ErrNotExist) {
		return 0, nil
	}

	if err != nil {
		return 0, errors.Wrap(err, "readVersion")
	}

	ver, err := strconv.ParseUint(string(buf), 10, 32)
	if err != nil {
		return 0, errors.Wrap(err, "readVersion")
	}

	return uint(ver), nil
}

const cacheVersion = 1

var cacheLayoutPaths = map[restic.FileType]string{
	restic.PackFile:     "data",
	restic.SnapshotFile: "snapshots",
	restic.IndexFile:    "index",
}

const cachedirTagSignature = "Signature: 8a477f597d28d172789f06886806bc55\n"

func writeCachedirTag(dir string) error {
	if err := fs.MkdirAll(dir, dirMode); err != nil {
		return errors.WithStack(err)
	}

	tagfile := filepath.Join(dir, "CACHEDIR.TAG")
	_, err := fs.Lstat(tagfile)
	if err != nil && !errors.Is(err, os.ErrNotExist) {
		return errors.WithStack(err)
	}

	f, err := fs.OpenFile(tagfile, os.O_CREATE|os.O_EXCL|os.O_WRONLY, fileMode)
	if err != nil {
		if errors.Is(err, os.ErrExist) {
			return nil
		}

		return errors.WithStack(err)
	}

	debug.Log("Create CACHEDIR.TAG at %v", dir)
	if _, err := f.Write([]byte(cachedirTagSignature)); err != nil {
		_ = f.Close()
		return errors.WithStack(err)
	}

	return errors.WithStack(f.Close())
}

// New returns a new cache for the repo ID at basedir. If basedir is the empty
// string, the default cache location (according to the XDG standard) is used.
//
// For partial files, the complete file is loaded and stored in the cache when
// performReadahead returns true.
func New(id string, basedir string) (c *Cache, err error) {
	if basedir == "" {
		basedir, err = DefaultDir()
		if err != nil {
			return nil, err
		}
	}

	err = fs.MkdirAll(basedir, 0700)
	if err != nil {
		return nil, errors.WithStack(err)
	}

	// create base dir and tag it as a cache directory
	if err = writeCachedirTag(basedir); err != nil {
		return nil, err
	}

	cachedir := filepath.Join(basedir, id)
	debug.Log("using cache dir %v", cachedir)

	v, err := readVersion(cachedir)
	if err != nil {
		return nil, err
	}

	if v > cacheVersion {
		return nil, errors.New("cache version is newer")
	}

	// create the repo cache dir if it does not exist yet
	var created bool
	_, err = fs.Lstat(cachedir)
	if errors.Is(err, os.ErrNotExist) {
		err = fs.MkdirAll(cachedir, dirMode)
		if err != nil {
			return nil, errors.WithStack(err)
		}
		created = true
	}

	// update the timestamp so that we can detect old cache dirs
	err = updateTimestamp(cachedir)
	if err != nil {
		return nil, err
	}

	if v < cacheVersion {
		err = ioutil.WriteFile(filepath.Join(cachedir, "version"), []byte(fmt.Sprintf("%d", cacheVersion)), fileMode)
		if err != nil {
			return nil, errors.WithStack(err)
		}
	}

	for _, p := range cacheLayoutPaths {
		if err = fs.MkdirAll(filepath.Join(cachedir, p), dirMode); err != nil {
			return nil, errors.WithStack(err)
		}
	}

	c = &Cache{
		path:    cachedir,
		Base:    basedir,
		Created: created,
	}

	return c, nil
}

// updateTimestamp sets the modification timestamp (mtime and atime) for the
// directory d to the current time.
func updateTimestamp(d string) error {
	t := time.Now()
	return fs.Chtimes(d, t, t)
}

// MaxCacheAge is the default age (30 days) after which cache directories are considered old.
const MaxCacheAge = 30 * 24 * time.Hour

func validCacheDirName(s string) bool {
	r := regexp.MustCompile(`^[a-fA-F0-9]{64}$|^restic-check-cache-[0-9]+$`)
	return r.MatchString(s)
}

// listCacheDirs returns the list of cache directories.
func listCacheDirs(basedir string) ([]os.FileInfo, error) {
	f, err := fs.Open(basedir)
	if err != nil {
		if errors.Is(err, os.ErrNotExist) {
			err = nil
		}
		return nil, err
	}

	entries, err := f.Readdir(-1)
	if err != nil {
		return nil, err
	}

	err = f.Close()
	if err != nil {
		return nil, err
	}

	result := make([]os.FileInfo, 0, len(entries))
	for _, entry := range entries {
		if !entry.IsDir() {
			continue
		}

		if !validCacheDirName(entry.Name()) {
			continue
		}

		result = append(result, entry)
	}

	return result, nil
}

// All returns a list of cache directories.
func All(basedir string) (dirs []os.FileInfo, err error) {
	return listCacheDirs(basedir)
}

// OlderThan returns the list of cache directories older than max.
func OlderThan(basedir string, max time.Duration) ([]os.FileInfo, error) {
	entries, err := listCacheDirs(basedir)
	if err != nil {
		return nil, err
	}

	var oldCacheDirs []os.FileInfo
	for _, fi := range entries {
		if !IsOld(fi.ModTime(), max) {
			continue
		}

		oldCacheDirs = append(oldCacheDirs, fi)
	}

	debug.Log("%d old cache dirs found", len(oldCacheDirs))

	return oldCacheDirs, nil
}

// Old returns a list of cache directories with a modification time of more
// than 30 days ago.
func Old(basedir string) ([]os.FileInfo, error) {
	return OlderThan(basedir, MaxCacheAge)
}

// IsOld returns true if the timestamp is considered old.
func IsOld(t time.Time, maxAge time.Duration) bool {
	oldest := time.Now().Add(-maxAge)
	return t.Before(oldest)
}

// Wrap returns a backend with a cache.
func (c *Cache) Wrap(be restic.Backend) restic.Backend {
	return newBackend(be, c)
}

// BaseDir returns the base directory.
func (c *Cache) BaseDir() string {
	return c.Base
}
<commit_msg>cache: Don't Lstat before creating the tag file<commit_after>package cache

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"time"

	"github.com/pkg/errors"
	"github.com/restic/restic/internal/debug"
	"github.com/restic/restic/internal/fs"
	"github.com/restic/restic/internal/restic"
)

// Cache manages a local cache.
type Cache struct {
	path    string
	Base    string
	Created bool
}

const dirMode = 0700
const fileMode = 0644

func readVersion(dir string) (v uint, err error) {
	buf, err := ioutil.ReadFile(filepath.Join(dir, "version"))
	if errors.Is(err, os.ErrNotExist) {
		return 0, nil
	}

	if err != nil {
		return 0, errors.Wrap(err, "readVersion")
	}

	ver, err := strconv.ParseUint(string(buf), 10, 32)
	if err != nil {
		return 0, errors.Wrap(err, "readVersion")
	}

	return uint(ver), nil
}

const cacheVersion = 1

var cacheLayoutPaths = map[restic.FileType]string{
	restic.PackFile:     "data",
	restic.SnapshotFile: "snapshots",
	restic.IndexFile:    "index",
}

const cachedirTagSignature = "Signature: 8a477f597d28d172789f06886806bc55\n"

func writeCachedirTag(dir string) error {
	if err := fs.MkdirAll(dir, dirMode); err != nil {
		return errors.WithStack(err)
	}

	tagfile := filepath.Join(dir, "CACHEDIR.TAG")
	f, err := fs.OpenFile(tagfile, os.O_CREATE|os.O_EXCL|os.O_WRONLY, fileMode)
	if err != nil {
		if errors.Is(err, os.ErrExist) {
			return nil
		}

		return errors.WithStack(err)
	}

	debug.Log("Create CACHEDIR.TAG at %v", dir)
	if _, err := f.Write([]byte(cachedirTagSignature)); err != nil {
		_ = f.Close()
		return errors.WithStack(err)
	}

	return errors.WithStack(f.Close())
}

// New returns a new cache for the repo ID at basedir. If basedir is the empty
// string, the default cache location (according to the XDG standard) is used.
//
// For partial files, the complete file is loaded and stored in the cache when
// performReadahead returns true.
func New(id string, basedir string) (c *Cache, err error) {
	if basedir == "" {
		basedir, err = DefaultDir()
		if err != nil {
			return nil, err
		}
	}

	err = fs.MkdirAll(basedir, 0700)
	if err != nil {
		return nil, errors.WithStack(err)
	}

	// create base dir and tag it as a cache directory
	if err = writeCachedirTag(basedir); err != nil {
		return nil, err
	}

	cachedir := filepath.Join(basedir, id)
	debug.Log("using cache dir %v", cachedir)

	v, err := readVersion(cachedir)
	if err != nil {
		return nil, err
	}

	if v > cacheVersion {
		return nil, errors.New("cache version is newer")
	}

	// create the repo cache dir if it does not exist yet
	var created bool
	_, err = fs.Lstat(cachedir)
	if errors.Is(err, os.ErrNotExist) {
		err = fs.MkdirAll(cachedir, dirMode)
		if err != nil {
			return nil, errors.WithStack(err)
		}
		created = true
	}

	// update the timestamp so that we can detect old cache dirs
	err = updateTimestamp(cachedir)
	if err != nil {
		return nil, err
	}

	if v < cacheVersion {
		err = ioutil.WriteFile(filepath.Join(cachedir, "version"), []byte(fmt.Sprintf("%d", cacheVersion)), fileMode)
		if err != nil {
			return nil, errors.WithStack(err)
		}
	}

	for _, p := range cacheLayoutPaths {
		if err = fs.MkdirAll(filepath.Join(cachedir, p), dirMode); err != nil {
			return nil, errors.WithStack(err)
		}
	}

	c = &Cache{
		path:    cachedir,
		Base:    basedir,
		Created: created,
	}

	return c, nil
}

// updateTimestamp sets the modification timestamp (mtime and atime) for the
// directory d to the current time.
func updateTimestamp(d string) error {
	t := time.Now()
	return fs.Chtimes(d, t, t)
}

// MaxCacheAge is the default age (30 days) after which cache directories are considered old.
const MaxCacheAge = 30 * 24 * time.Hour

func validCacheDirName(s string) bool {
	r := regexp.MustCompile(`^[a-fA-F0-9]{64}$|^restic-check-cache-[0-9]+$`)
	return r.MatchString(s)
}

// listCacheDirs returns the list of cache directories.
func listCacheDirs(basedir string) ([]os.FileInfo, error) {
	f, err := fs.Open(basedir)
	if err != nil {
		if errors.Is(err, os.ErrNotExist) {
			err = nil
		}
		return nil, err
	}

	entries, err := f.Readdir(-1)
	if err != nil {
		return nil, err
	}

	err = f.Close()
	if err != nil {
		return nil, err
	}

	result := make([]os.FileInfo, 0, len(entries))
	for _, entry := range entries {
		if !entry.IsDir() {
			continue
		}

		if !validCacheDirName(entry.Name()) {
			continue
		}

		result = append(result, entry)
	}

	return result, nil
}

// All returns a list of cache directories.
func All(basedir string) (dirs []os.FileInfo, err error) {
	return listCacheDirs(basedir)
}

// OlderThan returns the list of cache directories older than max.
func OlderThan(basedir string, max time.Duration) ([]os.FileInfo, error) {
	entries, err := listCacheDirs(basedir)
	if err != nil {
		return nil, err
	}

	var oldCacheDirs []os.FileInfo
	for _, fi := range entries {
		if !IsOld(fi.ModTime(), max) {
			continue
		}

		oldCacheDirs = append(oldCacheDirs, fi)
	}

	debug.Log("%d old cache dirs found", len(oldCacheDirs))

	return oldCacheDirs, nil
}

// Old returns a list of cache directories with a modification time of more
// than 30 days ago.
func Old(basedir string) ([]os.FileInfo, error) {
	return OlderThan(basedir, MaxCacheAge)
}

// IsOld returns true if the timestamp is considered old.
func IsOld(t time.Time, maxAge time.Duration) bool {
	oldest := time.Now().Add(-maxAge)
	return t.Before(oldest)
}

// Wrap returns a backend with a cache.
func (c *Cache) Wrap(be restic.Backend) restic.Backend {
	return newBackend(be, c)
}

// BaseDir returns the base directory.
func (c *Cache) BaseDir() string {
	return c.Base
}
<|endoftext|>


<commit_before>package main

import (
	"../../builder"
	"encoding/json"
	"fmt"
	"github.com/gorilla/mux"
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"net/http"
)

var templ = template.Must(template.New("builder").Parse(templateStr))

const templateStr = `

<title>Builder</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">

  ID
  Title
  Descriptiton
  Port
  Created
  Status
  Diff

{{range .}}

   {{.Id}}
   {{.Title}}
   {{.Descr}}
   {{.Port}}
   {{.Created}}
   {{.Status}}
   diff
{{.Diffdata}}

{{end}}

`

func statusUpdate(res http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	job := vars["job"]
	status := vars["status"]

	db, err := builder.Connect()
	defer db.Close()
	if err != nil {
		log.Fatalf("Can't connect to DB: %v", err)
	}

	row, err := db.Query(`update jobs set status = $1 where id = $2`, status, job)
	if err != nil {
		log.Fatalf("Can't update status")
	}

	if err := json.NewEncoder(res).Encode(row); err != nil {
		panic(err)
	}
}

func showJobs(res http.ResponseWriter, req *http.Request) {
	db, err := builder.Connect()
	defer db.Close()
	builder.LogFail(err, "Can't connect to DB: %v")

	jobs, err := builder.GetJobs(db)
	builder.LogFail(err, "Can't get jobs: %v")

	templ.Execute(res, jobs)
}

func sendWork(res http.ResponseWriter, req *http.Request) {
	db, err := builder.Connect()
	defer db.Close()
	builder.LogFail(err, "Can't connect to DB: %v")

	jobs, err := builder.GetJobs(db)
	builder.LogFail(err, "Can't get jobs: %v")

	res.Header().Set("Content-Type", "application/json")

	if err := json.NewEncoder(res).Encode(jobs); err != nil {
		panic(err)
	}
}

func newJob(res http.ResponseWriter, req *http.Request) {
	var resp = builder.Resp{}
	body, err := ioutil.ReadAll(io.LimitReader(req.Body, 1048576))
	if err := req.Body.Close(); err != nil {
		resp.Error = err.Error()
	}

	var job = builder.Job{}
	if err := json.Unmarshal(body, &job); err != nil {
		panic(err)
	}

	db, err := builder.Connect()
	defer db.Close()
	if err != nil {
		panic(err)
	}

	//	var job = builder.Job{Title: title, Descr: desc, Port: port, Diffdata: diffdata}
	diffid, err := builder.CreateDiff(db, string(job.Diffdata))
	if err != nil {
		resp.Error = err.Error()
	}

	job.Diff = diffid
	jobid, err := builder.CreateJob(db, &job)
	if err != nil {
		resp.Error = err.Error()
	}

	resp.JobID = jobid

	if err := json.NewEncoder(res).Encode(resp); err != nil {
		panic(err)
	}
}

func main() {
	r := mux.NewRouter()

	r.HandleFunc("/status/{job}/{status}", statusUpdate)
	r.HandleFunc("/new", newJob).Methods("POST")
	r.HandleFunc("/jobs", sendWork)
	r.HandleFunc("/", showJobs)

	http.Handle("/", r)
	fmt.Println("Listening on :8001")
	http.ListenAndServe(":8001", nil)
}
<commit_msg>fix template, throw error when template sucks<commit_after>package main

import (
	"../../builder"
	"encoding/json"
	"fmt"
	"github.com/gorilla/mux"
	"html/template"
	"io"
	"io/ioutil"
	"log"
	"net/http"
)

var templ = template.Must(template.New("builder").Parse(templateStr))

const templateStr = `

<title>Builder</title>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap-theme.min.css">

  ID
  Title
  Descriptiton
  Port
  Created
  Status
  Diff

{{range .}}

   {{.ID}}
   {{.Title}}
   {{.Descr}}
   {{.Port}}
   {{.Created}}
   {{.Status}}
   diff
{{.Diffdata}}

{{end}}

`

func statusUpdate(res http.ResponseWriter, req *http.Request) {
	vars := mux.Vars(req)
	job := vars["job"]
	status := vars["status"]

	db, err := builder.Connect()
	defer db.Close()
	if err != nil {
		log.Fatalf("Can't connect to DB: %v", err)
	}

	row, err := db.Query(`update jobs set status = $1 where id = $2`, status, job)
	if err != nil {
		log.Fatalf("Can't update status")
	}

	if err := json.NewEncoder(res).Encode(row); err != nil {
		panic(err)
	}
}

func showJobs(w http.ResponseWriter, req *http.Request) {
	db, err := builder.Connect()
	defer db.Close()
	builder.LogFail(err, "Can't connect to DB: %v")

	jobs, err := builder.GetJobs(db)
	builder.LogFail(err, "Can't get jobs: %v")

	err = templ.Execute(w, jobs)
	if err != nil {
		panic(err)
	}
}

func sendWork(res http.ResponseWriter, req *http.Request) {
	db, err := builder.Connect()
	defer db.Close()
	builder.LogFail(err, "Can't connect to DB: %v")

	jobs, err := builder.GetJobs(db)
	builder.LogFail(err, "Can't get jobs: %v")

	res.Header().Set("Content-Type", "application/json")

	if err := json.NewEncoder(res).Encode(jobs); err != nil {
		panic(err)
	}
}

func newJob(w http.ResponseWriter, req *http.Request) {
	var resp = builder.Resp{}
	body, err := ioutil.ReadAll(io.LimitReader(req.Body, 1048576))
	if err := req.Body.Close(); err != nil {
		resp.Error = err.Error()
	}

	var job = builder.Job{}
	if err := json.Unmarshal(body, &job); err != nil {
		panic(err)
	}

	db, err := builder.Connect()
	defer db.Close()
	if err != nil {
		panic(err)
	}

	diffid, err := builder.CreateDiff(db, string(job.Diffdata))
	if err != nil {
		resp.Error = err.Error()
	}

	job.Diff = diffid
	jobid, err := builder.CreateJob(db, &job)
	if err != nil {
		resp.Error = err.Error()
	}

	resp.JobID = jobid

	if err := json.NewEncoder(w).Encode(resp); err != nil {
		http.Error(w, err.Error(), 501)
	}
}

func main() {
	r := mux.NewRouter()

	r.HandleFunc("/status/{job}/{status}", statusUpdate)
	r.HandleFunc("/new", newJob).Methods("POST")
	r.HandleFunc("/jobs", sendWork)
	r.HandleFunc("/", showJobs)

	http.Handle("/", r)
	fmt.Println("Listening on :8001")
	http.ListenAndServe(":8001", nil)
}
<|endoftext|>


<commit_before>// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package internal

import (
	"net/http"
	"os"
)

// These functions are implementations of the wrapper functions
// in ../appengine/identity.go. See that file for commentary.

const (
	hDefaultVersionHostname = "X-AppEngine-Default-Version-Hostname"
	hRequestLogId           = "X-AppEngine-Request-Log-Id"
	hDatacenter             = "X-AppEngine-Datacenter"
)

func DefaultVersionHostname(req interface{}) string {
	return req.(*http.Request).Header.Get(hDefaultVersionHostname)
}

func RequestID(req interface{}) string {
	return req.(*http.Request).Header.Get(hRequestLogId)
}

func Datacenter(req interface{}) string {
	return req.(*http.Request).Header.Get(hDatacenter)
}

func ServerSoftware() string {
	// TODO
	return "Google App Engine/1.x.x"
}

// TODO(dsymonds): Remove the metadata fetches.

func ModuleName() string {
	if s := os.Getenv("GAE_MODULE_NAME"); s != "" {
		return s
	}
	return string(mustGetMetadata("instance/attributes/gae_backend_name"))
}

func VersionID() string {
	if s := os.Getenv("GAE_MODULE_VERSION"); s != "" {
		return s
	}
	return string(mustGetMetadata("instance/attributes/gae_backend_version"))
}

func InstanceID() string {
	if s := os.Getenv("GAE_MODULE_INSTANCE"); s != "" {
		return s
	}
	return string(mustGetMetadata("instance/attributes/gae_backend_instance"))
}

func partitionlessAppID() string {
	// gae_project has everything except the partition prefix.
	appID := os.Getenv("GAE_LONG_APP_ID")
	if appID == "" {
		appID = string(mustGetMetadata("instance/attributes/gae_project"))
	}
	return appID
}

func fullyQualifiedAppID() string {
	appID := partitionlessAppID()

	part := os.Getenv("GAE_PARTITION")
	if part == "" {
		part = string(mustGetMetadata("instance/attributes/gae_partition"))
	}

	if part != "" {
		appID = part + "~" + appID
	}
	return appID
}
<commit_msg>Add correct implementation of ServerSoftware.<commit_after>// Copyright 2011 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package internal

import (
	"net/http"
	"os"
)

// These functions are implementations of the wrapper functions
// in ../appengine/identity.go. See that file for commentary.

const (
	hDefaultVersionHostname = "X-AppEngine-Default-Version-Hostname"
	hRequestLogId           = "X-AppEngine-Request-Log-Id"
	hDatacenter             = "X-AppEngine-Datacenter"
)

func DefaultVersionHostname(req interface{}) string {
	return req.(*http.Request).Header.Get(hDefaultVersionHostname)
}

func RequestID(req interface{}) string {
	return req.(*http.Request).Header.Get(hRequestLogId)
}

func Datacenter(req interface{}) string {
	return req.(*http.Request).Header.Get(hDatacenter)
}

func ServerSoftware() string {
	// TODO(dsymonds): Remove fallback when we've verified this.
	if s := os.Getenv("SERVER_SOFTWARE"); s != "" {
		return s
	}
	return "Google App Engine/1.x.x"
}

// TODO(dsymonds): Remove the metadata fetches.

func ModuleName() string {
	if s := os.Getenv("GAE_MODULE_NAME"); s != "" {
		return s
	}
	return string(mustGetMetadata("instance/attributes/gae_backend_name"))
}

func VersionID() string {
	if s := os.Getenv("GAE_MODULE_VERSION"); s != "" {
		return s
	}
	return string(mustGetMetadata("instance/attributes/gae_backend_version"))
}

func InstanceID() string {
	if s := os.Getenv("GAE_MODULE_INSTANCE"); s != "" {
		return s
	}
	return string(mustGetMetadata("instance/attributes/gae_backend_instance"))
}

func partitionlessAppID() string {
	// gae_project has everything except the partition prefix.
	appID := os.Getenv("GAE_LONG_APP_ID")
	if appID == "" {
		appID = string(mustGetMetadata("instance/attributes/gae_project"))
	}
	return appID
}

func fullyQualifiedAppID() string {
	appID := partitionlessAppID()

	part := os.Getenv("GAE_PARTITION")
	if part == "" {
		part = string(mustGetMetadata("instance/attributes/gae_partition"))
	}

	if part != "" {
		appID = part + "~" + appID
	}
	return appID
}
<|endoftext|>


<commit_before>package mdb

import (
	"github.com/mabetle/mcell/wxlsx"
	"io"
	"os"
)

// QueryToExcel
// NoLocal support
func (s Sql) QueryToExcel(out io.Writer,
	include string,
	exclude string,
	q string, args ...interface{}) error {
	table := ""
	locale := ""
	enableLocale := false
	return s.QueryToExcelWithLocale(out, table, include, exclude, locale, enableLocale, q, args...)
}

// QueryToExcelFile
func (s Sql) QueryToExcelFile(
	location string,
	include string,
	exclude string,
	q string, args ...interface{}) error {
	out, err := os.Create(location)
	if err != nil {
		return err
	}
	return s.QueryToExcel(out, include, exclude, q, args...)
}

// QueryToExcelFileWithLocale
func (s Sql) QueryToExcelFileWithLocale(
	location string,
	table string,
	include string,
	exclude string,
	locale string,
	enableLocale bool,
	q string, args ...interface{}) error {
	out, err := os.Create(location)
	if err != nil {
		return err
	}
	return s.QueryToExcelWithLocale(out, table, include, exclude, locale, enableLocale, q, args...)
}

// QueryToExcelWithLocale
// locale
// enableLocaleHeader
func (s Sql) QueryToExcelWithLocale(out io.Writer,
	table string,
	include string,
	exclude string,
	locale string,
	enableLocale bool,
	q string, args ...interface{}) error {
	rows, err := s.Query(q, args...)
	if err != nil {
		return err
	}
	// parse table name from sql
	if table == "" {
		table = ParseSqlTableName(q)
	}

	if table == "" {
		table = "common"
	}

	file, errFile := wxlsx.SqlRowsToExcelWithLocale("", table, rows, include, exclude, locale, enableLocale)
	if errFile != nil {
		return errFile
	}
	return file.Write(out)
}
<commit_msg>fix print<commit_after>package mdb

import (
	"github.com/mabetle/mcell/wxlsx"
	"io"
	"os"
)

// QueryToExcel
// NoLocal support
func (s Sql) QueryToExcel(out io.Writer,
	include string,
	exclude string,
	q string, args ...interface{}) error {
	table := ""
	locale := ""
	enableLocale := false
	return s.QueryToExcelWithLocale(out, table, include, exclude, locale, enableLocale, q, args...)
}

// QueryToExcelFile
func (s Sql) QueryToExcelFile(
	location string,
	include string,
	exclude string,
	q string, args ...interface{}) error {
	out, err := os.Create(location)
	if logger.CheckError(err) {
		return err
	}
	return s.QueryToExcel(out, include, exclude, q, args...)
}

// QueryToExcelFileWithLocale
func (s Sql) QueryToExcelFileWithLocale(
	location string,
	table string,
	include string,
	exclude string,
	locale string,
	enableLocale bool,
	q string, args ...interface{}) error {
	out, err := os.Create(location)
	if logger.CheckError(err) {
		return err
	}
	return s.QueryToExcelWithLocale(out, table, include, exclude, locale, enableLocale, q, args...)
}

// QueryToExcelWithLocale
// locale
// enableLocaleHeader
func (s Sql) QueryToExcelWithLocale(out io.Writer,
	table string,
	include string,
	exclude string,
	locale string,
	enableLocale bool,
	q string, args ...interface{}) error {
	rows, err := s.Query(q, args...)
	if logger.CheckError(err) {
		return err
	}
	// parse table name from sql
	if table == "" {
		table = ParseSqlTableName(q)
	}
	if table == "" {
		table = "common"
	}
	file, errFile := wxlsx.SqlRowsToExcelWithLocale("", table, rows, include, exclude, locale, enableLocale)
	if logger.CheckError(errFile) {
		return errFile
	}
	return file.Write(out)
}
<|endoftext|>


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

package drive

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

type desktopEntry struct {
	name string
	url  string
	icon string
}

func sepJoin(sep string, args ...string) string {
	return strings.Join(args, sep)
}

func (f *File) toDesktopEntry(urlMExt *urlMimeTypeExt) *desktopEntry {
	name := f.Name
	if urlMExt.ext != "" {
		name = sepJoin("-", f.Name, urlMExt.ext)
	}
	return &desktopEntry{
		name: name,
		url:  urlMExt.url,
		icon: urlMExt.mimeType,
	}
}

func (f *File) serializeAsDesktopEntry(destPath string, urlMExt *urlMimeTypeExt) (int, error) {
	deskEnt := f.toDesktopEntry(urlMExt)
	handle, err := os.Create(destPath)
	if err != nil {
		return 0, err
	}
	defer handle.Close()

	return fmt.Fprintf(handle, "[Desktop Entry]\nIcon=%s\nName=%s\nType=%s\nURL=%s\n",
		deskEnt.icon, deskEnt.name, LinkKey, deskEnt.url)
}

func remotePathSplit(p string) (dir, base string) {
	// Avoiding use of filepath.Split because of bug with trailing "/" not being stripped
	sp := strings.Split(p, "/")
	spl := len(sp)
	dirL, baseL := sp[:spl-1], sp[spl-1:]
	dir = strings.Join(dirL, "/")
	base = strings.Join(baseL, "/")
	return
}

func commonPrefix(values ...string) string {
	vLen := len(values)
	if vLen < 1 {
		return ""
	}
	minIndex := 0
	min := values[0]
	minLen := len(min)

	for i := 1; i < vLen; i += 1 {
		st := values[i]
		if st == "" {
			return ""
		}
		lst := len(st)
		if lst < minLen {
			min = st
			minLen = lst
			minIndex = i + 0
		}
	}

	prefix := make([]byte, minLen)
	matchOn := true
	for i := 0; i < minLen; i += 1 {
		for j, other := range values {
			if minIndex == j {
				continue
			}
			if other[i] != min[i] {
				matchOn = false
				break
			}
		}
		if !matchOn {
			break
		}
		prefix[i] = min[i]
	}
	return string(prefix)
}

func readCommentedFile(p, comment string) (clauses []string, err error) {
	f, fErr := os.Open(p)
	if fErr != nil || f == nil {
		err = fErr
		return
	}

	defer f.Close()
	scanner := bufio.NewScanner(f)

	for {
		if !scanner.Scan() {
			break
		}
		line := scanner.Text()
		line = strings.Trim(line, " ")
		line = strings.Trim(line, "\n")
		if strings.HasPrefix(line, comment) || len(line) < 1 {
			continue
		}
		clauses = append(clauses, line)
	}
	return
}
<commit_msg>iconPath: replace os.Sep with "-"<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package drive

import (
	"bufio"
	"fmt"
	"os"
	"strings"
)

const (
	MimeTypeJoiner = "-"
)

type desktopEntry struct {
	name string
	url  string
	icon string
}

func sepJoin(sep string, args ...string) string {
	return strings.Join(args, sep)
}

func (f *File) toDesktopEntry(urlMExt *urlMimeTypeExt) *desktopEntry {
	name := f.Name
	if urlMExt.ext != "" {
		name = sepJoin("-", f.Name, urlMExt.ext)
	}
	return &desktopEntry{
		name: name,
		url:  urlMExt.url,
		icon: urlMExt.mimeType,
	}
}

func (f *File) serializeAsDesktopEntry(destPath string, urlMExt *urlMimeTypeExt) (int, error) {
	deskEnt := f.toDesktopEntry(urlMExt)
	handle, err := os.Create(destPath)
	if err != nil {
		return 0, err
	}
	defer handle.Close()
	icon := strings.Replace(deskEnt.icon, UnescapedPathSep, MimeTypeJoiner, -1)

	return fmt.Fprintf(handle, "[Desktop Entry]\nIcon=%s\nName=%s\nType=%s\nURL=%s\n",
		icon, deskEnt.name, LinkKey, deskEnt.url)
}

func remotePathSplit(p string) (dir, base string) {
	// Avoiding use of filepath.Split because of bug with trailing "/" not being stripped
	sp := strings.Split(p, "/")
	spl := len(sp)
	dirL, baseL := sp[:spl-1], sp[spl-1:]
	dir = strings.Join(dirL, "/")
	base = strings.Join(baseL, "/")
	return
}

func commonPrefix(values ...string) string {
	vLen := len(values)
	if vLen < 1 {
		return ""
	}
	minIndex := 0
	min := values[0]
	minLen := len(min)

	for i := 1; i < vLen; i += 1 {
		st := values[i]
		if st == "" {
			return ""
		}
		lst := len(st)
		if lst < minLen {
			min = st
			minLen = lst
			minIndex = i + 0
		}
	}

	prefix := make([]byte, minLen)
	matchOn := true
	for i := 0; i < minLen; i += 1 {
		for j, other := range values {
			if minIndex == j {
				continue
			}
			if other[i] != min[i] {
				matchOn = false
				break
			}
		}
		if !matchOn {
			break
		}
		prefix[i] = min[i]
	}
	return string(prefix)
}

func readCommentedFile(p, comment string) (clauses []string, err error) {
	f, fErr := os.Open(p)
	if fErr != nil || f == nil {
		err = fErr
		return
	}

	defer f.Close()
	scanner := bufio.NewScanner(f)

	for {
		if !scanner.Scan() {
			break
		}
		line := scanner.Text()
		line = strings.Trim(line, " ")
		line = strings.Trim(line, "\n")
		if strings.HasPrefix(line, comment) || len(line) < 1 {
			continue
		}
		clauses = append(clauses, line)
	}
	return
}
<|endoftext|>


<commit_before>package claymore

import (
	"errors"
	"strings"
	"regexp"

	"encoding/json"
	"github.com/ghodss/yaml"
	"fmt"
	"net/url"
	"github.com/alexshemesh/claptrap/lib/http"
	"bytes"
	"path"
)

type MinerEntry struct {
	MinerName   string
	Currency    string
	RunningTime string
	Hashrate    []string
	MiningPool  []string
}

func ParseString(RawData string) (retVal []MinerEntry, err error) {

	return retVal, err
}

func (this *MinerEntry) SetFieldForIndex(data string, index int) {
	if index == 0 {
		this.MinerName = data
	} else if index == 2 {
		this.RunningTime = data
	} else if index == 3 {
		this.Hashrate[0] = data
	} else if index == 4 {
		this.Hashrate[1] = data
	} else if index == 6 {
		minerpools := strings.Split(data, ";")
		this.MiningPool[0] = minerpools[0]
		if len(minerpools) >1 {
			this.MiningPool[1] = minerpools[1]
		}
	}
}

func parseMinerInfoFromRawData(data string) (retVal *MinerEntry, err error) {
	ok := strings.Contains(data, "<td>")
	if ok {
		retVal = &MinerEntry{Hashrate: make([]string, 2), MiningPool: make([]string, 2)}
		rp, err := regexp.Compile("(COLOR=(.*)>(.*)<)")
		if err != nil {
			return retVal, err
		}
		fieldCounter := 0
		fontEntries := strings.Split(data, "<FONT")
		for _, newValue := range (fontEntries) {
			values := rp.FindAllString(newValue, -1)
			for _, newValue1 := range (values) {
				tagDataStart := strings.Index(newValue1, ">") + 1
				tagDataEnd := strings.Index(newValue1, "<")

				retVal.SetFieldForIndex(string(newValue1[tagDataStart:tagDataEnd]), fieldCounter)
				fieldCounter++

			}
		}
		return retVal, nil
	}
	return retVal, errors.New("No miner info found")
}

func ObjectAsYAMLToString(obj interface{}) (retVal string) {
	var objectContent []byte
	var err error
	objectContent, err = json.Marshal(obj)
	objectasYaml, err := yaml.JSONToYAML(objectContent)
	if err != nil {
		print(err)
	}
	return "\n" + string(objectasYaml)
}

func SplitTable(tableText string) (retVal []MinerEntry){
	lines := strings.Split(tableText, "<tr>")
	for _, val := range (lines) {
		miner, err := parseMinerInfoFromRawData(val)
		if err == nil {
			fmt.Printf("Miner: %s, RunningTime: %s, HashRate1: %s for pool1:%s, HashRate2: %s, for pool2: %s" , miner.MinerName, miner.RunningTime, miner.Hashrate[0], miner.MiningPool[0],miner.Hashrate[1], miner.MiningPool[1])
			println("========================================")
			retVal = append(retVal,*miner)
		}
	}
	return retVal
}

func GetMinersData()(retVal string,err error){
	httpClient := httpClient.NewHttpExecutor().WithBasicAuth("admin", "statuscheck")
	var u *url.URL
	u, err = url.Parse(path.Join(""))
	u.Scheme = "http"
	u.Host = "10.7.7.2:8193"

	q := u.Query()
	u.RawQuery = q.Encode()
	var response []byte
	body := `{"id":0,"jsonrpc":"2.0","method":"miner_getstat"}`
	response, err = httpClient.Post().Execute(u.String(), nil, []byte(body))
	retVal = string(response)
	if err == nil {
		err = json.Unmarshal(response, &retVal)
	}
	if err != nil {
		return retVal, err
	}

	miners := SplitTable(string(response))
	var buffer bytes.Buffer
	for i,miner :=range(miners){
		minerString := fmt.Sprintf("%d,%s,%s,%s,%s,%s,%s\r\n",i, miner.MinerName,miner.RunningTime,miner.Hashrate[0],miner.Hashrate[1],miner.MiningPool[0], miner.MiningPool[1])
		buffer.WriteString(minerString)
	}
	retVal = string(buffer.Bytes())
	return retVal,err
}
<commit_msg>get miners statistic<commit_after>package claymore

import (
	"errors"
	"strings"
	"regexp"

	"encoding/json"
	"github.com/ghodss/yaml"
	"fmt"
	"net/url"
	"github.com/alexshemesh/claptrap/lib/http"
	"bytes"
	"path"
)

type MinerEntry struct {
	MinerName   string
	Currency    string
	RunningTime string
	Hashrate    []string
	MiningPool  []string
}

func ParseString(RawData string) (retVal []MinerEntry, err error) {

	return retVal, err
}

func (this *MinerEntry) SetFieldForIndex(data string, index int) {
	if index == 0 {
		this.MinerName = data
	} else if index == 2 {
		this.RunningTime = data
	} else if index == 3 {
		this.Hashrate[0] = data
	} else if index == 4 {
		this.Hashrate[1] = data
	} else if index == 6 {
		minerpools := strings.Split(data, ";")
		this.MiningPool[0] = minerpools[0]
		if len(minerpools) >1 {
			this.MiningPool[1] = minerpools[1]
		}
	}
}

func parseMinerInfoFromRawData(data string) (retVal *MinerEntry, err error) {
	ok := strings.Contains(data, "<td>")
	if ok {
		retVal = &MinerEntry{Hashrate: make([]string, 2), MiningPool: make([]string, 2)}
		rp, err := regexp.Compile("(COLOR=(.*)>(.*)<)")
		if err != nil {
			return retVal, err
		}
		fieldCounter := 0
		fontEntries := strings.Split(data, "<FONT")
		for _, newValue := range (fontEntries) {
			values := rp.FindAllString(newValue, -1)
			for _, newValue1 := range (values) {
				tagDataStart := strings.Index(newValue1, ">") + 1
				tagDataEnd := strings.Index(newValue1, "<")

				retVal.SetFieldForIndex(string(newValue1[tagDataStart:tagDataEnd]), fieldCounter)
				fieldCounter++

			}
		}
		return retVal, nil
	}
	return retVal, errors.New("No miner info found")
}

func ObjectAsYAMLToString(obj interface{}) (retVal string) {
	var objectContent []byte
	var err error
	objectContent, err = json.Marshal(obj)
	objectasYaml, err := yaml.JSONToYAML(objectContent)
	if err != nil {
		print(err)
	}
	return "\n" + string(objectasYaml)
}

func SplitTable(tableText string) (retVal []MinerEntry){
	lines := strings.Split(tableText, "<tr>")
	for _, val := range (lines) {
		miner, err := parseMinerInfoFromRawData(val)
		if err == nil {
			fmt.Printf("Miner: %s, RunningTime: %s, HashRate1: %s for pool1:%s, HashRate2: %s, for pool2: %s" , miner.MinerName, miner.RunningTime, miner.Hashrate[0], miner.MiningPool[0],miner.Hashrate[1], miner.MiningPool[1])
			println("========================================")
			retVal = append(retVal,*miner)
		}
	}
	return retVal
}

func GetMinersData()(retVal string,err error){
	httpClient := httpClient.NewHttpExecutor().WithBasicAuth("admin", "statuscheck")
	var u *url.URL
	u, err = url.Parse(path.Join(""))
	u.Scheme = "http"
	u.Host = "10.7.7.2:8193"

	q := u.Query()
	u.RawQuery = q.Encode()
	var response []byte
	body := `{"id":0,"jsonrpc":"2.0","method":"miner_getstat"}`
	response, err = httpClient.Post().Execute(u.String(), nil, []byte(body))

	miners := SplitTable(string(response))
	var buffer bytes.Buffer
	for i,miner :=range(miners){
		minerString := fmt.Sprintf("%d,%s,%s,%s,%s,%s,%s\r\n",i, miner.MinerName,miner.RunningTime,miner.Hashrate[0],miner.Hashrate[1],miner.MiningPool[0], miner.MiningPool[1])
		buffer.WriteString(minerString)
	}
	retVal = string(buffer.Bytes())
	return retVal,err
}
<|endoftext|>


<commit_before>package main

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

  "errors"
  "testing"
)

func Test(t *testing.T) {
  RegisterFailHandler(Fail)
  RunSpecs(t, "Run")
}

var _ = Describe("Run", func() {
  extensionError := errors.New("run could not determine how to run this file because it does not have a known extension")

  Describe(".command_for_file", func() {
    Context("when a filename is given with a known extension", func() {
      It("should be a valid command", func() {
        command, err := commandForFile("hello.rb")
        Expect(command).To(Equal("ruby hello.rb"))
        Expect(err).To(BeNil())
      })
    })

    Context("when a filename is given without a known extension", func() {
      It("should return an error", func() {
        _, err := commandForFile("hello.unknown")
        Expect(err).To(Equal(extensionError))
      })
    })

    Context("when a filename is given without any extension", func() {
      It("should return an error", func() {
        _, err := commandForFile("hello")
        Expect(err).To(Equal(extensionError))
      })
    })
  })
})
<commit_msg>Use ginkgo's HaveOccurred() matcher<commit_after>package main

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

  "testing"
)

func Test(t *testing.T) {
  RegisterFailHandler(Fail)
  RunSpecs(t, "Run")
}

var _ = Describe("Run", func() {
  Describe(".command_for_file", func() {
    Context("when a filename is given with a known extension", func() {
      It("should be a valid command", func() {
        command, err := commandForFile("hello.rb")
        Expect(command).To(Equal("ruby hello.rb"))
        Expect(err).ToNot(HaveOccurred())
      })
    })

    Context("when a filename is given without a known extension", func() {
      It("should return an error", func() {
        _, err := commandForFile("hello.unknown")
        Expect(err).To(HaveOccurred())
      })
    })

    Context("when a filename is given without any extension", func() {
      It("should return an error", func() {
        _, err := commandForFile("hello")
        Expect(err).To(HaveOccurred())
      })
    })
  })
})
<|endoftext|>


<commit_before>package gangliamr

import (
	"fmt"
	"strings"
	"sync"
	"time"

	"github.com/daaku/go.ganglia/gmetric"
)

// Internally we verify the registered metrics match this interface.
type metric interface {
	writeMeta(c *gmetric.Client)
	writeValue(c *gmetric.Client)
	register(r *Registry)
}

// Registry provides the process to periodically report the in-memory metrics
// to Ganglia.
type Registry struct {
	Prefix        string
	NameSeparator string // Defaults to a dot "."
	Client        *gmetric.Client
	TickInterval  time.Duration
	startOnce     sync.Once
	metrics       []metric
	mutex         sync.Mutex
}

func (r *Registry) start() {
	go func() {
		for {
			metrics := r.registered()
			for _, m := range metrics {
				m.writeMeta(r.Client)
				m.writeValue(r.Client)
			}
			time.Sleep(r.TickInterval)
		}
	}()
}

// Register a metric. The only metrics acceptable for registration are the ones
// provided in this package itself. The registration function uses an untyped
// argument to make it easier for use with fields typed as one of the metrics
// in the go.metrics library. All the metrics provided by this library embed
// one of those metrics and augment them with Ganglia specific metadata.
func (r *Registry) Register(m interface{}) {
	r.startOnce.Do(r.start)
	r.mutex.Lock()
	defer r.mutex.Unlock()
	v, ok := m.(metric)
	if !ok {
		panic(fmt.Sprintf("unknown metric type: %T", m))
	}
	v.register(r)
	r.metrics = append(r.metrics, v)
}

func (r *Registry) registered() []metric {
	metrics := make([]metric, len(r.metrics))
	r.mutex.Lock()
	defer r.mutex.Unlock()
	copy(metrics, r.metrics)
	return metrics
}

func (r *Registry) makeName(parts ...string) string {
	var nonempty []string
	sep := r.NameSeparator
	if sep == "" {
		sep = "."
	}
	if r.Prefix != "" {
		nonempty = append(nonempty, r.Prefix)
	}
	for _, p := range parts {
		if p != "" {
			nonempty = append(nonempty, p)
		}
	}
	return strings.Join(nonempty, sep)
}
<commit_msg>fix data race<commit_after>package gangliamr

import (
	"fmt"
	"strings"
	"sync"
	"time"

	"github.com/daaku/go.ganglia/gmetric"
)

// Internally we verify the registered metrics match this interface.
type metric interface {
	writeMeta(c *gmetric.Client)
	writeValue(c *gmetric.Client)
	register(r *Registry)
}

// Registry provides the process to periodically report the in-memory metrics
// to Ganglia.
type Registry struct {
	Prefix        string
	NameSeparator string // Defaults to a dot "."
	Client        *gmetric.Client
	TickInterval  time.Duration
	startOnce     sync.Once
	metrics       []metric
	mutex         sync.Mutex
}

func (r *Registry) start() {
	go func() {
		for {
			metrics := r.registered()
			for _, m := range metrics {
				m.writeMeta(r.Client)
				m.writeValue(r.Client)
			}
			time.Sleep(r.TickInterval)
		}
	}()
}

// Register a metric. The only metrics acceptable for registration are the ones
// provided in this package itself. The registration function uses an untyped
// argument to make it easier for use with fields typed as one of the metrics
// in the go.metrics library. All the metrics provided by this library embed
// one of those metrics and augment them with Ganglia specific metadata.
func (r *Registry) Register(m interface{}) {
	r.startOnce.Do(r.start)
	r.mutex.Lock()
	defer r.mutex.Unlock()
	v, ok := m.(metric)
	if !ok {
		panic(fmt.Sprintf("unknown metric type: %T", m))
	}
	v.register(r)
	r.metrics = append(r.metrics, v)
}

func (r *Registry) registered() []metric {
	r.mutex.Lock()
	defer r.mutex.Unlock()
	metrics := make([]metric, len(r.metrics))
	copy(metrics, r.metrics)
	return metrics
}

func (r *Registry) makeName(parts ...string) string {
	var nonempty []string
	sep := r.NameSeparator
	if sep == "" {
		sep = "."
	}
	if r.Prefix != "" {
		nonempty = append(nonempty, r.Prefix)
	}
	for _, p := range parts {
		if p != "" {
			nonempty = append(nonempty, p)
		}
	}
	return strings.Join(nonempty, sep)
}
<|endoftext|>