<commit_before>package networking

import (
	"fmt"
	"os"
	"time"

	testexutil "github.com/openshift/origin/test/extended/util"
	testutil "github.com/openshift/origin/test/util"

	kapierrs "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	kapiv1 "k8s.io/kubernetes/pkg/api/v1"
	kapiv1pod "k8s.io/kubernetes/pkg/api/v1/pod"
	kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
	"k8s.io/kubernetes/pkg/client/retry"
	e2e "k8s.io/kubernetes/test/e2e/framework"

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

type NodeType int

const (
	// Initial pod start can be delayed O(minutes) by slow docker pulls
	// TODO: Make this 30 seconds once #4566 is resolved.
	podStartTimeout = 5 * time.Minute

	// How often to poll pods and nodes.
	poll = 5 * time.Second

	// How wide to print pod names, by default. Useful for aligning printing to
	// quickly scan through output.
	podPrintWidth = 55

	// Indicator for same or different node
	SAME_NODE      NodeType = iota
	DIFFERENT_NODE NodeType = iota
)

func expectNoError(err error, explain ...interface{}) {
	ExpectWithOffset(1, err).NotTo(HaveOccurred(), explain...)
}

// podReady returns whether pod has a condition of Ready with a status of true.
func podReady(pod *kapiv1.Pod) bool {
	for _, cond := range pod.Status.Conditions {
		if cond.Type == kapiv1.PodReady && cond.Status == kapiv1.ConditionTrue {
			return true
		}
	}
	return false
}

type podCondition func(pod *kapiv1.Pod) (bool, error)

func waitForPodCondition(c kclientset.Interface, ns, podName, desc string, timeout time.Duration, condition podCondition) error {
	e2e.Logf("Waiting up to %[1]v for pod %-[2]*[3]s status to be %[4]s", timeout, podPrintWidth, podName, desc)
	for start := time.Now(); time.Since(start) < timeout; time.Sleep(poll) {
		pod, err := c.CoreV1().Pods(ns).Get(podName, metav1.GetOptions{})
		if err != nil {
			// Aligning this text makes it much more readable
			e2e.Logf("Get pod %-[1]*[2]s in namespace '%[3]s' failed, ignoring for %[4]v. Error: %[5]v",
				podPrintWidth, podName, ns, poll, err)
			continue
		}
		done, err := condition(pod)
		if done {
			return err
		}
		e2e.Logf("Waiting for pod %-[1]*[2]s in namespace '%[3]s' status to be '%[4]s'"+
			"(found phase: %[5]q, readiness: %[6]t) (%[7]v elapsed)",
			podPrintWidth, podName, ns, desc, pod.Status.Phase, podReady(pod), time.Since(start))
	}
	return fmt.Errorf("gave up waiting for pod '%s' to be '%s' after %v", podName, desc, timeout)
}

// waitForPodSuccessInNamespace returns nil if the pod reached state success, or an error if it reached failure or ran too long.
func waitForPodSuccessInNamespace(c kclientset.Interface, podName string, contName string, namespace string) error {
	return waitForPodCondition(c, namespace, podName, "success or failure", podStartTimeout, func(pod *kapiv1.Pod) (bool, error) {
		// Cannot use pod.Status.Phase == api.PodSucceeded/api.PodFailed due to #2632
		ci, ok := kapiv1pod.GetContainerStatus(pod.Status.ContainerStatuses, contName)
		if !ok {
			e2e.Logf("No Status.Info for container '%s' in pod '%s' yet", contName, podName)
		} else {
			if ci.State.Terminated != nil {
				if ci.State.Terminated.ExitCode == 0 {
					By("Saw pod success")
					return true, nil
				}
				return true, fmt.Errorf("pod '%s' terminated with failure: %+v", podName, ci.State.Terminated)
			}
			e2e.Logf("Nil State.Terminated for container '%s' in pod '%s' in namespace '%s' so far", contName, podName, namespace)
		}
		return false, nil
	})
}

func waitForEndpoint(c kclientset.Interface, ns, name string) error {
	for t := time.Now(); time.Since(t) < 3*time.Minute; time.Sleep(poll) {
		endpoint, err := c.Core().Endpoints(ns).Get(name, metav1.GetOptions{})
		if kapierrs.IsNotFound(err) {
			e2e.Logf("Endpoint %s/%s is not ready yet", ns, name)
			continue
		}
		Expect(err).NotTo(HaveOccurred())
		if len(endpoint.Subsets) == 0 || len(endpoint.Subsets[0].Addresses) == 0 {
			e2e.Logf("Endpoint %s/%s is not ready yet", ns, name)
			continue
		} else {
			return nil
		}
	}
	return fmt.Errorf("Failed to get endpoints for %s/%s", ns, name)
}

func launchWebserverService(f *e2e.Framework, serviceName string, nodeName string) (serviceAddr string) {
	e2e.LaunchWebserverPod(f, serviceName, nodeName)

	// FIXME: make e2e.LaunchWebserverPod() set the label when creating the pod
	err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
		podClient := f.ClientSet.CoreV1().Pods(f.Namespace.Name)
		pod, err := podClient.Get(serviceName, metav1.GetOptions{})
		if err != nil {
			return err
		}
		if pod.ObjectMeta.Labels == nil {
			pod.ObjectMeta.Labels = make(map[string]string)
		}
		pod.ObjectMeta.Labels["name"] = "web"
		_, err = podClient.Update(pod)
		return err
	})
	expectNoError(err)

	servicePort := 8080
	service := &kapiv1.Service{
		ObjectMeta: metav1.ObjectMeta{
			Name: serviceName,
		},
		Spec: kapiv1.ServiceSpec{
			Type: kapiv1.ServiceTypeClusterIP,
			Ports: []kapiv1.ServicePort{
				{
					Protocol: kapiv1.ProtocolTCP,
					Port:     int32(servicePort),
				},
			},
			Selector: map[string]string{
				"name": "web",
			},
		},
	}
	serviceClient := f.ClientSet.CoreV1().Services(f.Namespace.Name)
	_, err = serviceClient.Create(service)
	expectNoError(err)
	expectNoError(waitForEndpoint(f.ClientSet, f.Namespace.Name, serviceName))
	createdService, err := serviceClient.Get(serviceName, metav1.GetOptions{})
	expectNoError(err)
	serviceAddr = fmt.Sprintf("%s:%d", createdService.Spec.ClusterIP, servicePort)
	e2e.Logf("Target service IP:port is %s", serviceAddr)
	return
}

func checkConnectivityToHost(f *e2e.Framework, nodeName string, podName string, host string, timeout int) error {
	contName := fmt.Sprintf("%s-container", podName)
	pod := &kapiv1.Pod{
		TypeMeta: metav1.TypeMeta{
			Kind: "Pod",
		},
		ObjectMeta: metav1.ObjectMeta{
			Name: podName,
		},
		Spec: kapiv1.PodSpec{
			Containers: []kapiv1.Container{
				{
					Name:    contName,
					Image:   "gcr.io/google_containers/busybox",
					Command: []string{"wget", fmt.Sprintf("--timeout=%d", timeout), "-s", host},
				},
			},
			NodeName:      nodeName,
			RestartPolicy: kapiv1.RestartPolicyNever,
		},
	}
	podClient := f.ClientSet.CoreV1().Pods(f.Namespace.Name)
	_, err := podClient.Create(pod)
	expectNoError(err)
	defer podClient.Delete(podName, nil)
	return waitForPodSuccessInNamespace(f.ClientSet, podName, contName, f.Namespace.Name)
}

func pluginIsolatesNamespaces() bool {
	return os.Getenv("NETWORKING_E2E_ISOLATION") == "true"
}

func pluginImplementsNetworkPolicy() bool {
	return os.Getenv("NETWORKING_E2E_NETWORKPOLICY") == "true"
}

func makeNamespaceGlobal(ns *kapiv1.Namespace) {
	client, err := testutil.GetClusterAdminClient(testexutil.KubeConfigPath())
	expectNoError(err)
	netns, err := client.NetNamespaces().Get(ns.Name, metav1.GetOptions{})
	expectNoError(err)
	netns.NetID = 0
	_, err = client.NetNamespaces().Update(netns)
	expectNoError(err)
}

func checkPodIsolation(f1, f2 *e2e.Framework, nodeType NodeType) error {
	nodes := e2e.GetReadySchedulableNodesOrDie(f1.ClientSet)
	var serverNode, clientNode *kapiv1.Node
	serverNode = &nodes.Items[0]
	if nodeType == DIFFERENT_NODE {
		if len(nodes.Items) == 1 {
			e2e.Skipf("Only one node is available in this environment")
		}
		clientNode = &nodes.Items[1]
	} else {
		clientNode = serverNode
	}

	podName := "isolation-webserver"
	defer f1.ClientSet.CoreV1().Pods(f1.Namespace.Name).Delete(podName, nil)
	ip := e2e.LaunchWebserverPod(f1, podName, serverNode.Name)

	return checkConnectivityToHost(f2, clientNode.Name, "isolation-wget", ip, 10)
}

func checkServiceConnectivity(serverFramework, clientFramework *e2e.Framework, nodeType NodeType) error {
	nodes := e2e.GetReadySchedulableNodesOrDie(serverFramework.ClientSet)
	var serverNode, clientNode *kapiv1.Node
	serverNode = &nodes.Items[0]
	if nodeType == DIFFERENT_NODE {
		if len(nodes.Items) == 1 {
			e2e.Skipf("Only one node is available in this environment")
		}
		clientNode = &nodes.Items[1]
	} else {
		clientNode = serverNode
	}

	podName := kapiv1.SimpleNameGenerator.GenerateName("service-")
	defer serverFramework.ClientSet.CoreV1().Pods(serverFramework.Namespace.Name).Delete(podName, nil)
	defer serverFramework.ClientSet.CoreV1().Services(serverFramework.Namespace.Name).Delete(podName, nil)
	ip := launchWebserverService(serverFramework, podName, serverNode.Name)

	return checkConnectivityToHost(clientFramework, clientNode.Name, "service-wget", ip, 10)
}

func InSingleTenantContext(body func()) {
	Context("when using a plugin that does not isolate namespaces by default", func() {
		BeforeEach(func() {
			if pluginIsolatesNamespaces() {
				e2e.Skipf("This plugin isolates namespaces by default.")
			}
		})

		body()
	})
}

func InMultiTenantContext(body func()) {
	Context("when using a plugin that isolates namespaces by default", func() {
		BeforeEach(func() {
			if !pluginIsolatesNamespaces() {
				e2e.Skipf("This plugin does not isolate namespaces by default.")
			}
		})

		body()
	})
}

func InNetworkPolicyContext(body func()) {
	Context("when using a plugin that implements NetworkPolicy", func() {
		BeforeEach(func() {
			if !pluginImplementsNetworkPolicy() {
				e2e.Skipf("This plugin does not implement NetworkPolicy.")
			}
		})

		body()
	})
}
<commit_msg>Make service e2e tests retry to avoid flakes<commit_after>package networking

import (
	"fmt"
	"os"
	"strings"
	"time"

	testexutil "github.com/openshift/origin/test/extended/util"
	testutil "github.com/openshift/origin/test/util"

	kapierrs "k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	kapiv1 "k8s.io/kubernetes/pkg/api/v1"
	kapiv1pod "k8s.io/kubernetes/pkg/api/v1/pod"
	kclientset "k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
	"k8s.io/kubernetes/pkg/client/retry"
	e2e "k8s.io/kubernetes/test/e2e/framework"

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

type NodeType int

const (
	// Initial pod start can be delayed O(minutes) by slow docker pulls
	// TODO: Make this 30 seconds once #4566 is resolved.
	podStartTimeout = 5 * time.Minute

	// How often to poll pods and nodes.
	poll = 5 * time.Second

	// How wide to print pod names, by default. Useful for aligning printing to
	// quickly scan through output.
	podPrintWidth = 55

	// Indicator for same or different node
	SAME_NODE      NodeType = iota
	DIFFERENT_NODE NodeType = iota
)

func expectNoError(err error, explain ...interface{}) {
	ExpectWithOffset(1, err).NotTo(HaveOccurred(), explain...)
}

// podReady returns whether pod has a condition of Ready with a status of true.
func podReady(pod *kapiv1.Pod) bool {
	for _, cond := range pod.Status.Conditions {
		if cond.Type == kapiv1.PodReady && cond.Status == kapiv1.ConditionTrue {
			return true
		}
	}
	return false
}

type podCondition func(pod *kapiv1.Pod) (bool, error)

func waitForPodCondition(c kclientset.Interface, ns, podName, desc string, timeout time.Duration, condition podCondition) error {
	e2e.Logf("Waiting up to %[1]v for pod %-[2]*[3]s status to be %[4]s", timeout, podPrintWidth, podName, desc)
	for start := time.Now(); time.Since(start) < timeout; time.Sleep(poll) {
		pod, err := c.CoreV1().Pods(ns).Get(podName, metav1.GetOptions{})
		if err != nil {
			// Aligning this text makes it much more readable
			e2e.Logf("Get pod %-[1]*[2]s in namespace '%[3]s' failed, ignoring for %[4]v. Error: %[5]v",
				podPrintWidth, podName, ns, poll, err)
			continue
		}
		done, err := condition(pod)
		if done {
			return err
		}
		e2e.Logf("Waiting for pod %-[1]*[2]s in namespace '%[3]s' status to be '%[4]s'"+
			"(found phase: %[5]q, readiness: %[6]t) (%[7]v elapsed)",
			podPrintWidth, podName, ns, desc, pod.Status.Phase, podReady(pod), time.Since(start))
	}
	return fmt.Errorf("gave up waiting for pod '%s' to be '%s' after %v", podName, desc, timeout)
}

// waitForPodSuccessInNamespace returns nil if the pod reached state success, or an error if it reached failure or ran too long.
func waitForPodSuccessInNamespace(c kclientset.Interface, podName string, contName string, namespace string) error {
	return waitForPodCondition(c, namespace, podName, "success or failure", podStartTimeout, func(pod *kapiv1.Pod) (bool, error) {
		// Cannot use pod.Status.Phase == api.PodSucceeded/api.PodFailed due to #2632
		ci, ok := kapiv1pod.GetContainerStatus(pod.Status.ContainerStatuses, contName)
		if !ok {
			e2e.Logf("No Status.Info for container '%s' in pod '%s' yet", contName, podName)
		} else {
			if ci.State.Terminated != nil {
				if ci.State.Terminated.ExitCode == 0 {
					By("Saw pod success")
					return true, nil
				}
				return true, fmt.Errorf("pod '%s' terminated with failure: %+v", podName, ci.State.Terminated)
			}
			e2e.Logf("Nil State.Terminated for container '%s' in pod '%s' in namespace '%s' so far", contName, podName, namespace)
		}
		return false, nil
	})
}

func waitForEndpoint(c kclientset.Interface, ns, name string) error {
	for t := time.Now(); time.Since(t) < 3*time.Minute; time.Sleep(poll) {
		endpoint, err := c.Core().Endpoints(ns).Get(name, metav1.GetOptions{})
		if kapierrs.IsNotFound(err) {
			e2e.Logf("Endpoint %s/%s is not ready yet", ns, name)
			continue
		}
		Expect(err).NotTo(HaveOccurred())
		if len(endpoint.Subsets) == 0 || len(endpoint.Subsets[0].Addresses) == 0 {
			e2e.Logf("Endpoint %s/%s is not ready yet", ns, name)
			continue
		} else {
			return nil
		}
	}
	return fmt.Errorf("Failed to get endpoints for %s/%s", ns, name)
}

func launchWebserverService(f *e2e.Framework, serviceName string, nodeName string) (serviceAddr string) {
	e2e.LaunchWebserverPod(f, serviceName, nodeName)

	// FIXME: make e2e.LaunchWebserverPod() set the label when creating the pod
	err := retry.RetryOnConflict(retry.DefaultRetry, func() error {
		podClient := f.ClientSet.CoreV1().Pods(f.Namespace.Name)
		pod, err := podClient.Get(serviceName, metav1.GetOptions{})
		if err != nil {
			return err
		}
		if pod.ObjectMeta.Labels == nil {
			pod.ObjectMeta.Labels = make(map[string]string)
		}
		pod.ObjectMeta.Labels["name"] = "web"
		_, err = podClient.Update(pod)
		return err
	})
	expectNoError(err)

	servicePort := 8080
	service := &kapiv1.Service{
		ObjectMeta: metav1.ObjectMeta{
			Name: serviceName,
		},
		Spec: kapiv1.ServiceSpec{
			Type: kapiv1.ServiceTypeClusterIP,
			Ports: []kapiv1.ServicePort{
				{
					Protocol: kapiv1.ProtocolTCP,
					Port:     int32(servicePort),
				},
			},
			Selector: map[string]string{
				"name": "web",
			},
		},
	}
	serviceClient := f.ClientSet.CoreV1().Services(f.Namespace.Name)
	_, err = serviceClient.Create(service)
	expectNoError(err)
	expectNoError(waitForEndpoint(f.ClientSet, f.Namespace.Name, serviceName))
	createdService, err := serviceClient.Get(serviceName, metav1.GetOptions{})
	expectNoError(err)
	serviceAddr = fmt.Sprintf("%s:%d", createdService.Spec.ClusterIP, servicePort)
	e2e.Logf("Target service IP:port is %s", serviceAddr)
	return
}

func checkConnectivityToHost(f *e2e.Framework, nodeName string, podName string, host string, timeout time.Duration) error {
	e2e.Logf("Creating an exec pod on node %v", nodeName)
	execPodName := e2e.CreateExecPodOrFail(f.ClientSet, f.Namespace.Name, fmt.Sprintf("execpod-sourceip-%s", nodeName), func(pod *kapiv1.Pod) {
		pod.Spec.NodeName = nodeName
	})
	defer func() {
		e2e.Logf("Cleaning up the exec pod")
		err := f.ClientSet.Core().Pods(f.Namespace.Name).Delete(execPodName, nil)
		Expect(err).NotTo(HaveOccurred())
	}()
	execPod, err := f.ClientSet.Core().Pods(f.Namespace.Name).Get(execPodName, metav1.GetOptions{})
	e2e.ExpectNoError(err)

	var stdout string
	e2e.Logf("Waiting up to %v to wget %s", timeout, host)
	cmd := fmt.Sprintf("wget -T 30 -qO- %s", host)
	for start := time.Now(); time.Since(start) < timeout; time.Sleep(2) {
		stdout, err = e2e.RunHostCmd(execPod.Namespace, execPod.Name, cmd)
		if err != nil {
			e2e.Logf("got err: %v, retry until timeout", err)
			continue
		}
		// Need to check output because wget -q might omit the error.
		if strings.TrimSpace(stdout) == "" {
			e2e.Logf("got empty stdout, retry until timeout")
			continue
		}
		break
	}
	return err
}

func pluginIsolatesNamespaces() bool {
	return os.Getenv("NETWORKING_E2E_ISOLATION") == "true"
}

func pluginImplementsNetworkPolicy() bool {
	return os.Getenv("NETWORKING_E2E_NETWORKPOLICY") == "true"
}

func makeNamespaceGlobal(ns *kapiv1.Namespace) {
	client, err := testutil.GetClusterAdminClient(testexutil.KubeConfigPath())
	expectNoError(err)
	netns, err := client.NetNamespaces().Get(ns.Name, metav1.GetOptions{})
	expectNoError(err)
	netns.NetID = 0
	_, err = client.NetNamespaces().Update(netns)
	expectNoError(err)
}

func checkPodIsolation(f1, f2 *e2e.Framework, nodeType NodeType) error {
	nodes := e2e.GetReadySchedulableNodesOrDie(f1.ClientSet)
	var serverNode, clientNode *kapiv1.Node
	serverNode = &nodes.Items[0]
	if nodeType == DIFFERENT_NODE {
		if len(nodes.Items) == 1 {
			e2e.Skipf("Only one node is available in this environment")
		}
		clientNode = &nodes.Items[1]
	} else {
		clientNode = serverNode
	}

	podName := "isolation-webserver"
	defer f1.ClientSet.CoreV1().Pods(f1.Namespace.Name).Delete(podName, nil)
	ip := e2e.LaunchWebserverPod(f1, podName, serverNode.Name)

	return checkConnectivityToHost(f2, clientNode.Name, "isolation-wget", ip, 10*time.Second)
}

func checkServiceConnectivity(serverFramework, clientFramework *e2e.Framework, nodeType NodeType) error {
	nodes := e2e.GetReadySchedulableNodesOrDie(serverFramework.ClientSet)
	var serverNode, clientNode *kapiv1.Node
	serverNode = &nodes.Items[0]
	if nodeType == DIFFERENT_NODE {
		if len(nodes.Items) == 1 {
			e2e.Skipf("Only one node is available in this environment")
		}
		clientNode = &nodes.Items[1]
	} else {
		clientNode = serverNode
	}

	podName := kapiv1.SimpleNameGenerator.GenerateName("service-")
	defer serverFramework.ClientSet.CoreV1().Pods(serverFramework.Namespace.Name).Delete(podName, nil)
	defer serverFramework.ClientSet.CoreV1().Services(serverFramework.Namespace.Name).Delete(podName, nil)
	ip := launchWebserverService(serverFramework, podName, serverNode.Name)

	return checkConnectivityToHost(clientFramework, clientNode.Name, "service-wget", ip, 10*time.Second)
}

func InSingleTenantContext(body func()) {
	Context("when using a plugin that does not isolate namespaces by default", func() {
		BeforeEach(func() {
			if pluginIsolatesNamespaces() {
				e2e.Skipf("This plugin isolates namespaces by default.")
			}
		})

		body()
	})
}

func InMultiTenantContext(body func()) {
	Context("when using a plugin that isolates namespaces by default", func() {
		BeforeEach(func() {
			if !pluginIsolatesNamespaces() {
				e2e.Skipf("This plugin does not isolate namespaces by default.")
			}
		})

		body()
	})
}

func InNetworkPolicyContext(body func()) {
	Context("when using a plugin that implements NetworkPolicy", func() {
		BeforeEach(func() {
			if !pluginImplementsNetworkPolicy() {
				e2e.Skipf("This plugin does not implement NetworkPolicy.")
			}
		})

		body()
	})
}
<|endoftext|>


<commit_before>package controllers

import (
	"context"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"strconv"

	"github.com/nicomo/abacaxi/logger"
	"github.com/nicomo/abacaxi/models"
	"github.com/nicomo/abacaxi/session"
	"github.com/nicomo/abacaxi/views"
)

// UploadGetHandler manages upload of a source file
func UploadGetHandler(w http.ResponseWriter, r *http.Request) {
	// our messages (errors, confirmation, etc) to the user & the template will be stored in this map
	d := make(map[string]interface{})

	// Get session
	sess := session.Instance(r)
	if sess.Values["id"] != nil {
		d["IsLoggedIn"] = true
	}

	// check if we have messages coming in the Request context
	if userM, ok := fromContextUserM(r.Context()); ok {
		for k, v := range userM {
			d[k] = v
		}
	}

	TSListing, _ := models.GetTargetServicesListing()
	d["TSListing"] = TSListing
	views.RenderTmpl(w, "upload", d)

}

// UploadPostHandler receives source file, checks extension
// then passes the file on to the appropriate controller
func UploadPostHandler(w http.ResponseWriter, r *http.Request) {

	// our messages (errors, confirmation, etc) to the user & the template will be store in this map
	//FIXME: either userMessages struct of d[string] interface{} as used in other funcs, but not both...
	userM := make(UserMessages)

	// parsing multipart file
	r.ParseMultipartForm(32 << 20)

	// get the Target Service name
	tsname := r.PostFormValue("pack")
	userM["myPackage"] = tsname
	file, handler, err := r.FormFile("uploadfile")
	if err != nil {
		logger.Error.Println(err)
		return
	}
	defer file.Close()

	// create dir if it doesn't exist
	path := "data"
	ErrPath := os.MkdirAll("data", os.ModePerm)
	if ErrPath != nil {
		logger.Error.Println(ErrPath)
	}

	fpath := path + "/" + handler.Filename
	f, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		logger.Error.Println(err)
		return
	}
	defer f.Close()

	// copy uploaded file into new file
	io.Copy(f, file)

	// if xml pass on to xmlio, if csv, pass on to csvio, if neither, abort
	ext := filepath.Ext(handler.Filename)
	var records []models.Record
	var myTS models.TargetService
	if ext == ".kbart" {

		records, myTS, userM, err = fileIO(fpath, tsname, userM, ext)
		if err != nil {
			logger.Error.Println(err)
		}

	} else if ext == ".csv" {

		// pass on the name of the package and the name of the file to csvio package
		records, myTS, userM, err = fileIO(fpath, tsname, userM, ext)
		if err != nil {
			logger.Error.Println(err)
		}

	} else if ext == ".xml" {

		records, myTS, userM, err = xmlIO(fpath, tsname, userM)
		if err != nil {
			logger.Error.Println(err)
		}

	} else {

		// manage case wrong file extension : message to the user
		logger.Error.Println("wrong file extension")
		userM["wrongExt"] = "wrong file extension"

		// insert the user messages in the http.Request Context before redirecting
		ctx, cancel = context.WithCancel(context.Background())
		defer cancel()
		ctx = newContextUserM(ctx, userM)

		// redirect to upload get page
		UploadGetHandler(w, r.WithContext(ctx))

	}

	recordsUpdated, recordsInserted := models.RecordsUpsert(records)
	logger.Info.Printf("TS: %s; recordsUpdated: %d; recordsInserted: %d", myTS.TSName, recordsUpdated, recordsInserted)
	userM["createdCounter"] = strconv.Itoa(recordsInserted)
	userM["updatedCounter"] = strconv.Itoa(recordsUpdated)

	// list of TS appearing in menu
	TSListing, _ := models.GetTargetServicesListing()
	userM["TSListing"] = TSListing

	views.RenderTmpl(w, "upload-report", userM)
}
<commit_msg>fixes #14<commit_after>package controllers

import (
	"context"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"strconv"

	"github.com/nicomo/abacaxi/logger"
	"github.com/nicomo/abacaxi/models"
	"github.com/nicomo/abacaxi/session"
	"github.com/nicomo/abacaxi/views"
)

// UploadGetHandler manages upload of a source file
func UploadGetHandler(w http.ResponseWriter, r *http.Request) {
	// our messages (errors, confirmation, etc) to the user & the template will be stored in this map
	d := make(map[string]interface{})

	// Get session
	sess := session.Instance(r)
	if sess.Values["id"] != nil {
		d["IsLoggedIn"] = true
	}

	// check if we have messages coming in the Request context
	if userM, ok := fromContextUserM(r.Context()); ok {
		for k, v := range userM {
			d[k] = v
		}
	}

	TSListing, _ := models.GetTargetServicesListing()
	d["TSListing"] = TSListing
	views.RenderTmpl(w, "upload", d)

}

// UploadPostHandler receives source file, checks extension
// then passes the file on to the appropriate controller
func UploadPostHandler(w http.ResponseWriter, r *http.Request) {

	// our messages (errors, confirmation, etc) to the user & the template will be store in this map
	//FIXME: either userMessages struct of d[string] interface{} as used in other funcs, but not both...
	userM := make(UserMessages)

	// parsing multipart file
	r.ParseMultipartForm(32 << 20)

	// get the Target Service name
	tsname := r.PostFormValue("pack")
	userM["myPackage"] = tsname
	file, handler, err := r.FormFile("uploadfile")
	if err != nil {
		logger.Error.Println(err)
		return
	}
	defer file.Close()

	// create dir if it doesn't exist
	path := "data"
	ErrPath := os.MkdirAll("data", os.ModePerm)
	if ErrPath != nil {
		logger.Error.Println(ErrPath)
	}

	fpath := path + "/" + handler.Filename
	f, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE, 0666)
	if err != nil {
		logger.Error.Println(err)
		return
	}
	defer f.Close()

	// copy uploaded file into new file
	io.Copy(f, file)

	// if xml pass on to xmlio, if csv, pass on to csvio, if neither, abort
	ext := filepath.Ext(handler.Filename)
	var records []models.Record
	var myTS models.TargetService
	if ext == ".kbart" {

		records, myTS, userM, err = fileIO(fpath, tsname, userM, ext)
		if err != nil {
			logger.Error.Println(err)
		}

	} else if ext == ".csv" {

		// pass on the name of the package and the name of the file to csvio package
		records, myTS, userM, err = fileIO(fpath, tsname, userM, ext)
		if err != nil {
			logger.Error.Println(err)
		}

	} else if ext == ".xml" {

		records, myTS, userM, err = xmlIO(fpath, tsname, userM)
		if err != nil {
			logger.Error.Println(err)
		}

	} else {

		// manage case wrong file extension : message to the user
		logger.Error.Println("wrong file extension")
		userM["wrongExt"] = "wrong file extension"

		// insert the user messages in the http.Request Context before redirecting
		ctx, cancel = context.WithCancel(context.Background())
		defer cancel()
		ctx = newContextUserM(ctx, userM)

		// redirect to upload get page
		UploadGetHandler(w, r.WithContext(ctx))
		return
	}

	recordsUpdated, recordsInserted := models.RecordsUpsert(records)
	logger.Info.Printf("TS: %s; recordsUpdated: %d; recordsInserted: %d", myTS.TSName, recordsUpdated, recordsInserted)
	userM["createdCounter"] = strconv.Itoa(recordsInserted)
	userM["updatedCounter"] = strconv.Itoa(recordsUpdated)

	// list of TS appearing in menu
	TSListing, _ := models.GetTargetServicesListing()
	userM["TSListing"] = TSListing

	views.RenderTmpl(w, "upload-report", userM)
}
<|endoftext|>


<commit_before>package terminal

import (
	"os"
	"regexp"

	"github.com/fatih/color"
	"golang.org/x/crypto/ssh/terminal"
)

const (
	red     color.Attribute = color.FgRed
	green                   = color.FgGreen
	yellow                  = color.FgYellow
	magenta                 = color.FgMagenta
	cyan                    = color.FgCyan
	grey                    = color.FgWhite
	white                   = color.FgHiWhite
)

var (
	colorize               func(message string, textColor color.Attribute, bold int) string
	TerminalSupportsColors = isTerminal()
	UserAskedForColors     = ""
)

func init() {
	InitColorSupport()
}

func InitColorSupport() {
	if colorsEnabled() {
		colorize = func(message string, textColor color.Attribute, bold int) string {
			colorPrinter := color.New(textColor)
			if bold == 1 {
				colorPrinter = colorPrinter.Add(color.Bold)
			}
			f := colorPrinter.SprintFunc()
			return f(message)
		}
	} else {
		colorize = func(message string, _ color.Attribute, _ int) string {
			return message
		}
	}
}

func colorsEnabled() bool {
	return userDidNotDisableColor() &&
		(userEnabledColors() || TerminalSupportsColors)
}

func userEnabledColors() bool {
	return UserAskedForColors == "true" || os.Getenv("CF_COLOR") == "true"
}

func userDidNotDisableColor() bool {
	return os.Getenv("CF_COLOR") != "false" && (UserAskedForColors != "false" || os.Getenv("CF_COLOR") == "true")
}

func Colorize(message string, textColor color.Attribute) string {
	return colorize(message, textColor, 0)
}

func ColorizeBold(message string, textColor color.Attribute) string {
	return colorize(message, textColor, 1)
}

var decolorizerRegex = regexp.MustCompile(`\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]`)

func Decolorize(message string) string {
	return string(decolorizerRegex.ReplaceAll([]byte(message), []byte("")))
}

func HeaderColor(message string) string {
	return ColorizeBold(message, white)
}

func CommandColor(message string) string {
	return ColorizeBold(message, yellow)
}

func StoppedColor(message string) string {
	return ColorizeBold(message, grey)
}

func AdvisoryColor(message string) string {
	return ColorizeBold(message, yellow)
}

func CrashedColor(message string) string {
	return ColorizeBold(message, red)
}

func FailureColor(message string) string {
	return ColorizeBold(message, red)
}

func SuccessColor(message string) string {
	return ColorizeBold(message, green)
}

func EntityNameColor(message string) string {
	return ColorizeBold(message, cyan)
}

func PromptColor(message string) string {
	return ColorizeBold(message, cyan)
}

func TableContentHeaderColor(message string) string {
	return ColorizeBold(message, cyan)
}

func WarningColor(message string) string {
	return ColorizeBold(message, magenta)
}

func LogStdoutColor(message string) string {
	return Colorize(message, white)
}

func LogStderrColor(message string) string {
	return Colorize(message, red)
}

func LogHealthHeaderColor(message string) string {
	return Colorize(message, grey)
}

func LogAppHeaderColor(message string) string {
	return ColorizeBold(message, yellow)
}

func LogSysHeaderColor(message string) string {
	return ColorizeBold(message, cyan)
}

func isTerminal() bool {
	return terminal.IsTerminal(1)
}
<commit_msg>Simplify color logic<commit_after>package terminal

import (
	"os"
	"regexp"

	"github.com/fatih/color"
	"golang.org/x/crypto/ssh/terminal"
)

const (
	red     color.Attribute = color.FgRed
	green                   = color.FgGreen
	yellow                  = color.FgYellow
	magenta                 = color.FgMagenta
	cyan                    = color.FgCyan
	grey                    = color.FgWhite
	white                   = color.FgHiWhite
)

var (
	colorize               func(message string, textColor color.Attribute, bold int) string
	TerminalSupportsColors = isTerminal()
	UserAskedForColors     = ""
)

func init() {
	InitColorSupport()
}

func InitColorSupport() {
	if colorsEnabled() {
		colorize = func(message string, textColor color.Attribute, bold int) string {
			colorPrinter := color.New(textColor)
			if bold == 1 {
				colorPrinter = colorPrinter.Add(color.Bold)
			}
			f := colorPrinter.SprintFunc()
			return f(message)
		}
	} else {
		colorize = func(message string, _ color.Attribute, _ int) string {
			return message
		}
	}
}

func colorsEnabled() bool {
	if os.Getenv("CF_COLOR") == "true" {
		return true
	}

	if os.Getenv("CF_COLOR") == "false" {
		return false
	}

	if UserAskedForColors == "true" {
		return true
	}

	return UserAskedForColors != "false" && TerminalSupportsColors
}

func Colorize(message string, textColor color.Attribute) string {
	return colorize(message, textColor, 0)
}

func ColorizeBold(message string, textColor color.Attribute) string {
	return colorize(message, textColor, 1)
}

var decolorizerRegex = regexp.MustCompile(`\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]`)

func Decolorize(message string) string {
	return string(decolorizerRegex.ReplaceAll([]byte(message), []byte("")))
}

func HeaderColor(message string) string {
	return ColorizeBold(message, white)
}

func CommandColor(message string) string {
	return ColorizeBold(message, yellow)
}

func StoppedColor(message string) string {
	return ColorizeBold(message, grey)
}

func AdvisoryColor(message string) string {
	return ColorizeBold(message, yellow)
}

func CrashedColor(message string) string {
	return ColorizeBold(message, red)
}

func FailureColor(message string) string {
	return ColorizeBold(message, red)
}

func SuccessColor(message string) string {
	return ColorizeBold(message, green)
}

func EntityNameColor(message string) string {
	return ColorizeBold(message, cyan)
}

func PromptColor(message string) string {
	return ColorizeBold(message, cyan)
}

func TableContentHeaderColor(message string) string {
	return ColorizeBold(message, cyan)
}

func WarningColor(message string) string {
	return ColorizeBold(message, magenta)
}

func LogStdoutColor(message string) string {
	return Colorize(message, white)
}

func LogStderrColor(message string) string {
	return Colorize(message, red)
}

func LogHealthHeaderColor(message string) string {
	return Colorize(message, grey)
}

func LogAppHeaderColor(message string) string {
	return ColorizeBold(message, yellow)
}

func LogSysHeaderColor(message string) string {
	return ColorizeBold(message, cyan)
}

func isTerminal() bool {
	return terminal.IsTerminal(1)
}
<|endoftext|>


<commit_before>package iptables

import (
	"testing"

	"github.com/luizbafilho/fusis/api/types"
	"github.com/luizbafilho/fusis/config"
	"github.com/luizbafilho/fusis/net"
	"github.com/luizbafilho/fusis/state"

	. "gopkg.in/check.v1"
)

func Test(t *testing.T) { TestingT(t) }

type IptablesSuite struct {
	iptablesMngr *IptablesMngr
}

var _ = Suite(&IptablesSuite{})

func (s *IptablesSuite) SetUpSuite(c *C) {
	var err error
	s.iptablesMngr, err = New(defaultConfig())
	c.Assert(err, IsNil)
}

func (s *IptablesSuite) SetUpTest(c *C) {
}

func (s *IptablesSuite) TearDownSuite(c *C) {
	rules, err := s.iptablesMngr.getSnatRules()
	c.Assert(err, IsNil)

	for _, r := range rules {
		err := s.iptablesMngr.removeRule(r)
		c.Assert(err, IsNil)
	}
}

func (s *IptablesSuite) TestSync(c *C) {
	state, err := state.New(defaultConfig())
	c.Assert(err, IsNil)

	s1 := &types.Service{
		Name:         "test",
		Host:         "10.0.1.1",
		Port:         80,
		Mode:         "nat",
		Protocol:     "tcp",
		Destinations: []types.Destination{},
	}
	state.AddService(s1)

	state.AddService(&types.Service{
		Name:         "test2",
		Host:         "10.0.1.2",
		Port:         80,
		Protocol:     "tcp",
		Mode:         "nat",
		Destinations: []types.Destination{},
	})

	toSource, err := net.GetIpByInterface("eth0")
	c.Assert(err, IsNil)
	rule2 := SnatRule{
		vaddr:    "10.0.1.2",
		vport:    "80",
		toSource: toSource,
	}
	rule3 := SnatRule{
		vaddr:    "10.0.1.3",
		vport:    "80",
		toSource: toSource,
	}

	err = s.iptablesMngr.addRule(rule2)
	c.Assert(err, IsNil)
	err = s.iptablesMngr.addRule(rule3)
	c.Assert(err, IsNil)

	err = s.iptablesMngr.Sync(*state)
	c.Assert(err, IsNil)

	rules, err := s.iptablesMngr.getKernelRulesSet()
	c.Assert(err, IsNil)

	rule1, err := s.iptablesMngr.serviceToSnatRule(*s1)
	c.Assert(err, IsNil)

	c.Assert(rules.Contains(rule2, *rule1), Equals, true)
}

func defaultConfig() *config.BalancerConfig {
	return &config.BalancerConfig{
		PublicInterface:  "eth0",
		PrivateInterface: "eth0",
		Name:             "Test",
		ConfigPath:       "/tmp/test",
		Bootstrap:        true,
		Provider: config.Provider{
			Type: "none",
			Params: map[string]string{
				"interface": "eth0",
				"vip-range": "192.168.0.0/28",
			},
		},
	}
}
<commit_msg>Fixing tests<commit_after>package iptables

import (
	"testing"

	"github.com/luizbafilho/fusis/api/types"
	"github.com/luizbafilho/fusis/config"
	"github.com/luizbafilho/fusis/net"
	"github.com/luizbafilho/fusis/state"

	. "gopkg.in/check.v1"
)

func Test(t *testing.T) { TestingT(t) }

type IptablesSuite struct {
	iptablesMngr *IptablesMngr
}

var _ = Suite(&IptablesSuite{})

func (s *IptablesSuite) SetUpSuite(c *C) {
	var err error
	s.iptablesMngr, err = New(defaultConfig())
	c.Assert(err, IsNil)
}

func (s *IptablesSuite) SetUpTest(c *C) {
}

func (s *IptablesSuite) TearDownSuite(c *C) {
	rules, err := s.iptablesMngr.getSnatRules()
	c.Assert(err, IsNil)

	for _, r := range rules {
		err := s.iptablesMngr.removeRule(r)
		c.Assert(err, IsNil)
	}
}

func (s *IptablesSuite) TestSync(c *C) {
	state, err := state.New(defaultConfig())
	c.Assert(err, IsNil)

	s1 := &types.Service{
		Name:         "test",
		Host:         "100.0.1.1",
		Port:         80,
		Mode:         "nat",
		Protocol:     "tcp",
		Destinations: []types.Destination{},
	}
	state.AddService(s1)

	state.AddService(&types.Service{
		Name:         "test2",
		Host:         "100.0.1.2",
		Port:         80,
		Protocol:     "tcp",
		Mode:         "nat",
		Destinations: []types.Destination{},
	})

	toSource, err := net.GetIpByInterface("eth0")
	c.Assert(err, IsNil)
	rule2 := SnatRule{
		vaddr:    "100.0.1.2",
		vport:    "80",
		toSource: toSource,
	}
	rule3 := SnatRule{
		vaddr:    "100.0.1.3",
		vport:    "80",
		toSource: toSource,
	}

	err = s.iptablesMngr.addRule(rule2)
	c.Assert(err, IsNil)
	err = s.iptablesMngr.addRule(rule3)
	c.Assert(err, IsNil)

	err = s.iptablesMngr.Sync(*state)
	c.Assert(err, IsNil)

	rules, err := s.iptablesMngr.getKernelRulesSet()
	c.Assert(err, IsNil)

	rule1, err := s.iptablesMngr.serviceToSnatRule(*s1)
	c.Assert(err, IsNil)

	c.Assert(rules.Contains(rule2, *rule1), Equals, true)
}

func defaultConfig() *config.BalancerConfig {
	return &config.BalancerConfig{
		PublicInterface:  "eth0",
		PrivateInterface: "eth0",
		Name:             "Test",
		ConfigPath:       "/tmp/test",
		Bootstrap:        true,
		Provider: config.Provider{
			Type: "none",
			Params: map[string]string{
				"interface": "eth0",
				"vip-range": "192.168.0.0/28",
			},
		},
	}
}
<|endoftext|>


<commit_before>package mstate_test

import (
	"labix.org/v2/mgo"
	. "launchpad.net/gocheck"
	"os/exec"
	"time"
)

type MgoSuite struct {
	session *mgo.Session
	server  *exec.Cmd
}

const (
	mgoport = "50017"
	mgoaddr = "localhost:" + mgoport
)

func (s *MgoSuite) SetUpSuite(c *C) {
	mgo.SetStats(true)
	dbdir := c.MkDir()
	args := []string{
		"--dbpath", dbdir,
		"--bind_ip", "127.0.0.1",
		"--port", mgoport,
		"--nssize", "1",
		"--noprealloc",
		"--smallfiles",
		"--nojournal",
	}
	s.server = exec.Command("mongod", args...)
	err := s.server.Start()
	if err != nil {
		panic(err)
	}
}

func (s *MgoSuite) TearDownSuite(c *C) {
	s.server.Process.Kill()
	s.server.Process.Wait()
}

func (s *MgoSuite) SetUpTest(c *C) {
	err := DropAll(mgoaddr)
	if err != nil {
		panic(err)
	}
	mgo.ResetStats()
	s.session, err = mgo.Dial(mgoaddr)
	if err != nil {
		panic(err)
	}
}

func (s *MgoSuite) TearDownTest(c *C) {
	s.session.Close()
	for i := 0; ; i++ {
		stats := mgo.GetStats()
		if stats.SocketsInUse == 0 && stats.SocketsAlive == 0 {
			break
		}
		if i == 20 {
			c.Fatal("Test left sockets in a dirty state")
		}
		c.Logf("Waiting for sockets to die: %d in use, %d alive", stats.SocketsInUse, stats.SocketsAlive)
		time.Sleep(500 * time.Millisecond)
	}
}

func DropAll(mongourl string) (err error) {
	session, err := mgo.Dial(mongourl)
	if err != nil {
		return err
	}
	defer session.Close()

	names, err := session.DatabaseNames()
	if err != nil {
		return err
	}
	for _, name := range names {
		switch name {
		case "admin", "local", "config":
		default:
			err = session.DB(name).DropDatabase()
			if err != nil {
				return err
			}
		}
	}
	return nil
}
<commit_msg>mstate: s/127.0.0.1/localhost/g, localhost is sometimes ::1, so make MongoDB use the same address the client is using to connect.<commit_after>package mstate_test

import (
	"labix.org/v2/mgo"
	. "launchpad.net/gocheck"
	"os/exec"
	"time"
)

type MgoSuite struct {
	session *mgo.Session
	server  *exec.Cmd
}

const (
	mgoport = "50017"
	mgoaddr = "localhost:" + mgoport
)

func (s *MgoSuite) SetUpSuite(c *C) {
	mgo.SetStats(true)
	dbdir := c.MkDir()
	args := []string{
		"--dbpath", dbdir,
		"--bind_ip", "localhost",
		"--port", mgoport,
		"--nssize", "1",
		"--noprealloc",
		"--smallfiles",
		"--nojournal",
	}
	s.server = exec.Command("mongod", args...)
	err := s.server.Start()
	if err != nil {
		panic(err)
	}
}

func (s *MgoSuite) TearDownSuite(c *C) {
	s.server.Process.Kill()
	s.server.Process.Wait()
}

func (s *MgoSuite) SetUpTest(c *C) {
	err := DropAll(mgoaddr)
	if err != nil {
		panic(err)
	}
	mgo.ResetStats()
	s.session, err = mgo.Dial(mgoaddr)
	if err != nil {
		panic(err)
	}
}

func (s *MgoSuite) TearDownTest(c *C) {
	s.session.Close()
	for i := 0; ; i++ {
		stats := mgo.GetStats()
		if stats.SocketsInUse == 0 && stats.SocketsAlive == 0 {
			break
		}
		if i == 20 {
			c.Fatal("Test left sockets in a dirty state")
		}
		c.Logf("Waiting for sockets to die: %d in use, %d alive", stats.SocketsInUse, stats.SocketsAlive)
		time.Sleep(500 * time.Millisecond)
	}
}

func DropAll(mongourl string) (err error) {
	session, err := mgo.Dial(mongourl)
	if err != nil {
		return err
	}
	defer session.Close()

	names, err := session.DatabaseNames()
	if err != nil {
		return err
	}
	for _, name := range names {
		switch name {
		case "admin", "local", "config":
		default:
			err = session.DB(name).DropDatabase()
			if err != nil {
				return err
			}
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package rui

import (
	"log"
	"testing"
	"time"

	"github.com/influx6/flux"
	"github.com/influx6/prox/reactive"
)

type sampleRob struct {
	// DataTrees
	Name reactive.Observers
	Age  reactive.Observers
	Date time.Time
}

func TestBasicRendable(t *testing.T) {
	name, _ := reactive.ObserveTransform("Alex", false)
	age, _ := reactive.ObserveTransform(1, false)

	bob := &sampleRob{
		Name: name,
		Age:  age,
		Date: time.Now(),
	}

	_, err := StructTree(bob)

	if err != nil {
		flux.FatalFailed(t, "Unable to create struct tree: %s", err.Error())
	}

	bob.Name.Set("Joe")
}

func TestTemplateRendering(t *testing.T) {

	tmpl, err := SourceTemplator("base.tml", `

{{.Name}}

{{.Age}}

  `)

	if err != nil {
		flux.FatalFailed(t, "Unable to create template gen tree: %s", err.Error())
	}

	name, _ := reactive.ObserveTransform("Alex", false)
	age, _ := reactive.ObserveTransform(1, false)

	tol, err := tmpl.Build(&sampleRob{
		Name: name,
		Age:  age,
		Date: time.Now(),
	})

	if err != nil {
		flux.FatalFailed(t, "Unable to create templateRenderer: %s", err.Error())
	}

	log.Printf("Render: %s", tol.Render())

	tol.React(func(r flux.Reactor, err error, d interface{}) {
		log.Printf("tol: %s", d)
	}, true)

	name.Set("ron!")
}
<commit_msg>first working reactive renderer<commit_after>package rui

import (
	"testing"
	"time"

	"github.com/influx6/flux"
	"github.com/influx6/prox/reactive"
)

type sampleRob struct {
	// DataTrees
	Name reactive.Observers
	Age  reactive.Observers
	Date time.Time
}

func TestBasicRendable(t *testing.T) {
	name, _ := reactive.ObserveTransform("Alex", false)
	age, _ := reactive.ObserveTransform(1, false)

	bob := &sampleRob{
		Name: name,
		Age:  age,
		Date: time.Now(),
	}

	_, err := StructTree(bob)

	if err != nil {
		flux.FatalFailed(t, "Unable to create struct tree: %s", err.Error())
	}

	bob.Name.Set("Joe")
}

func TestTemplateRendering(t *testing.T) {

	tmpl, err := SourceTemplator("base.tml", `

{{.Name}}

{{.Age}}

{{.Date}}

  `)

	if err != nil {
		flux.FatalFailed(t, "Unable to create template gen tree: %s", err.Error())
	}

	name, _ := reactive.ObserveTransform("Alex", false)
	age, _ := reactive.ObserveTransform(1, false)

	tol, err := tmpl.Build(&sampleRob{
		Name: name,
		Age:  age,
		Date: time.Now(),
	})

	if err != nil {
		flux.FatalFailed(t, "Unable to create templateRenderer: %s", err.Error())
	}

	cur := tol.Render()

	tol.React(func(r flux.Reactor, err error, d interface{}) {
		if cur == d {
			flux.FatalFailed(t, "both %s and %s should not be equal", cur, d)
		}

		flux.LogPassed(t, "both %s and %s are not be equal", cur, d)
	}, true)

	name.Set("Ron!")
}
<|endoftext|>


<commit_before>package runner

import (
	"reflect"
	"testing"

	"github.com/palats/glop/nodes"
)

func TestEval(t *testing.T) {
	r := ParseEval("(+ 1 2)")
	if r.(int64) != 3 {
		t.Errorf("Expected a result of 3, got: %v", r)
	}
}

func TestQuote(t *testing.T) {
	n := ParseEval("(quote (+ 1 2))").(nodes.Node)

	if len(n.Children()) != 3 {
		t.Errorf("Expected 3 children, got: %v", n.Children())
	}
}

func TestBegin(t *testing.T) {
	n := ParseEval("(begin 1 (+ 1 1))")
	if n.(int64) != 2 {
		t.Errorf("Expected '2', got: %v", n)
	}

	n = ParseEval("(begin)")
	if n != nil {
		t.Errorf("Expected nil, got: %v", n)
	}
}

func TestDefine(t *testing.T) {
	n := ParseEval("(begin (define a 5) a)")
	if n.(int64) != 5 {
		t.Errorf("Expected '5', got: %v", n)
	}
}

func TestSet(t *testing.T) {
	n := ParseEval("(begin (define a 5) (set! a 4) a)")
	if n.(int64) != 4 {
		t.Errorf("Expected '4', got: %v", n)
	}
}

func TestIf(t *testing.T) {
	valid := map[string]interface{}{
		"(if true 7)":    int64(7),
		"(if false 7)":   nil,
		"(if false 7 8)": int64(8),
	}

	for input, expected := range valid {
		r := ParseEval(input)
		if !reflect.DeepEqual(r, expected) {
			t.Errorf("Input %q -- expected <%T>%#+v, got: <%T>%#+v", input, expected, expected, r, r)
		}
	}
}
<commit_msg>Streamline tests<commit_after>package runner

import (
	"reflect"
	"testing"

	"github.com/palats/glop/nodes"
)

func TestQuote(t *testing.T) {
	n := ParseEval("(quote (+ 1 2))").(nodes.Node)

	if len(n.Children()) != 3 {
		t.Errorf("Expected 3 children, got: %v", n.Children())
	}
}

func TestValid(t *testing.T) {
	valid := map[string]interface{}{
		"(+ 1 2)":                           int64(3),
		"(begin 1 (+ 1 1))":                 int64(2),
		"(begin)":                           nil,
		"(begin (define a 5) a)":            int64(5),
		"(begin (define a 5) (set! a 4) a)": int64(4),
		"(if true 7)":                       int64(7),
		"(if false 7)":                      nil,
		"(if false 7 8)":                    int64(8),
	}

	for input, expected := range valid {
		r := ParseEval(input)
		if !reflect.DeepEqual(r, expected) {
			t.Errorf("Input %q -- expected <%T>%#+v, got: <%T>%#+v", input, expected, expected, r, r)
		}
	}
}
<|endoftext|>


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

package testblas

import (
	"math/cmplx"
	"testing"

	"gonum.org/v1/gonum/blas"
)

var zherTestCases = []struct {
	alpha float64
	x     []complex128
	a     []complex128

	want    []complex128
	wantRev []complex128 // Result when incX is negative.
}{
	{
		alpha: 1,
	},
	{
		alpha: 3,
		x: []complex128{
			0 - 3i,
			6 + 10i,
			-2 - 7i,
		},
		a: []complex128{
			-2 + 0i, -3 - 11i, 0 + 4i,
			-3 + 11i, -6 + 0i, 7 + 2i,
			0 - 4i, 7 - 2i, 18 + 0i,
		},
		want: []complex128{
			25 + 0i, -93 - 65i, 63 + 22i,
			-93 + 65i, 402 + 0i, -239 + 68i,
			63 - 22i, -239 - 68i, 177 + 0i},
		wantRev: []complex128{
			157 + 0i, -249 - 77i, 63 - 14i,
			-249 + 77i, 402 + 0i, -83 + 56i,
			63 + 14i, -83 - 56i, 45 + 0i,
		},
	},
	{
		alpha: 3,
		x: []complex128{
			-6 + 2i,
			-2 - 4i,
			0 + 0i,
			0 + 7i,
		},
		a: []complex128{
			2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i,
			-9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i,
			3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i,
			10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i,
		},
		want: []complex128{
			122 + 0i, 3 - 77i, 3 + 11i, 52 + 125i,
			3 + 77i, 76 + 0i, -5 + 2i, -91 + 37i,
			3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i,
			52 - 125i, -91 - 37i, 2 + 1i, 165 + 0i,
		},
		wantRev: []complex128{
			149 + 0i, -9 + 7i, -81 - 31i, 52 - 127i,
			-9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i,
			-81 + 31i, -5 - 2i, 74 + 0i, 14 + 83i,
			52 + 127i, -7 + 5i, 14 - 83i, 138 + 0i,
		},
	},
	{
		alpha: 0,
		x: []complex128{
			-6 + 2i,
			-2 - 4i,
			0 + 0i,
			0 + 7i,
		},
		a: []complex128{
			2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i,
			-9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i,
			3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i,
			10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i,
		},
		want: []complex128{
			2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i,
			-9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i,
			3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i,
			10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i,
		},
		wantRev: []complex128{
			2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i,
			-9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i,
			3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i,
			10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i,
		},
	},
}

type Zherer interface {
	Zher(uplo blas.Uplo, n int, alpha float64, x []complex128, incX int, a []complex128, lda int)
}

func ZherTest(t *testing.T, impl Zherer) {
	for tc, test := range zherTestCases {
		n := len(test.x)
		for _, uplo := range []blas.Uplo{blas.Lower, blas.Upper} {
			for _, incX := range []int{-11, -2, -1, 1, 2, 7} {
				for _, lda := range []int{max(1, n), n + 11} {
					x := makeZVector(test.x, incX)
					xCopy := make([]complex128, len(x))
					copy(xCopy, x)

					a := makeZGeneral(test.a, n, n, lda)

					var want []complex128
					if incX > 0 {
						want = makeZGeneral(test.want, n, n, lda)
					} else {
						want = makeZGeneral(test.wantRev, n, n, lda)
					}

					if uplo == blas.Upper {
						for i := 0; i < n; i++ {
							for j := 0; j < i; j++ {
								a[i*lda+j] = cmplx.NaN()
								want[i*lda+j] = cmplx.NaN()
							}
						}
					} else {
						for i := 0; i < n; i++ {
							for j := i + 1; j < n; j++ {
								a[i*lda+j] = cmplx.NaN()
								want[i*lda+j] = cmplx.NaN()
							}
						}
					}

					impl.Zher(uplo, n, test.alpha, x, incX, a, lda)

					if !zsame(x, xCopy) {
						t.Errorf("Case %v (uplo=%v,incX=%v,lda=%v,alpha=%v): unexpected modification of x", tc, uplo, incX, test.alpha, lda)
					}
					if !zsame(want, a) {
						t.Errorf("Case %v (uplo=%v,incX=%v,lda=%v,alpha=%v): unexpected result\nwant: %v\ngot:  %v", tc, uplo, incX, lda, test.alpha, want, a)
					}
				}
			}
		}
	}
}
<commit_msg>blas/testblas: use complex diagonals in test matrices for Zher, Zher2, Zhpr<commit_after>// Copyright ©2017 The Gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package testblas

import (
	"math/cmplx"
	"testing"

	"gonum.org/v1/gonum/blas"
)

var zherTestCases = []struct {
	alpha float64
	x     []complex128
	a     []complex128

	want    []complex128
	wantRev []complex128 // Result when incX is negative.
}{
	{
		alpha: 1,
	},
	{
		alpha: 3,
		x: []complex128{
			0 - 3i,
			6 + 10i,
			-2 - 7i,
		},
		a: []complex128{
			-2 + 3i, -3 - 11i, 0 + 4i,
			-3 + 11i, -6 + 3i, 7 + 2i,
			0 - 4i, 7 - 2i, 18 + 3i,
		},
		want: []complex128{
			25 + 0i, -93 - 65i, 63 + 22i,
			-93 + 65i, 402 + 0i, -239 + 68i,
			63 - 22i, -239 - 68i, 177 + 0i},
		wantRev: []complex128{
			157 + 0i, -249 - 77i, 63 - 14i,
			-249 + 77i, 402 + 0i, -83 + 56i,
			63 + 14i, -83 - 56i, 45 + 0i,
		},
	},
	{
		alpha: 3,
		x: []complex128{
			-6 + 2i,
			-2 - 4i,
			0 + 0i,
			0 + 7i,
		},
		a: []complex128{
			2 + 3i, -9 + 7i, 3 + 11i, 10 - 1i,
			-9 - 7i, 16 + 3i, -5 + 2i, -7 - 5i,
			3 - 11i, -5 - 2i, 14 + 3i, 2 - 1i,
			10 + 1i, -7 + 5i, 2 + 1i, 18 + 3i,
		},
		want: []complex128{
			122 + 0i, 3 - 77i, 3 + 11i, 52 + 125i,
			3 + 77i, 76 + 0i, -5 + 2i, -91 + 37i,
			3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i,
			52 - 125i, -91 - 37i, 2 + 1i, 165 + 0i,
		},
		wantRev: []complex128{
			149 + 0i, -9 + 7i, -81 - 31i, 52 - 127i,
			-9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i,
			-81 + 31i, -5 - 2i, 74 + 0i, 14 + 83i,
			52 + 127i, -7 + 5i, 14 - 83i, 138 + 0i,
		},
	},
	{
		alpha: 0,
		x: []complex128{
			-6 + 2i,
			-2 - 4i,
			0 + 0i,
			0 + 7i,
		},
		a: []complex128{
			2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i,
			-9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i,
			3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i,
			10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i,
		},
		want: []complex128{
			2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i,
			-9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i,
			3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i,
			10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i,
		},
		wantRev: []complex128{
			2 + 0i, -9 + 7i, 3 + 11i, 10 - 1i,
			-9 - 7i, 16 + 0i, -5 + 2i, -7 - 5i,
			3 - 11i, -5 - 2i, 14 + 0i, 2 - 1i,
			10 + 1i, -7 + 5i, 2 + 1i, 18 + 0i,
		},
	},
}

type Zherer interface {
	Zher(uplo blas.Uplo, n int, alpha float64, x []complex128, incX int, a []complex128, lda int)
}

func ZherTest(t *testing.T, impl Zherer) {
	for tc, test := range zherTestCases {
		n := len(test.x)
		for _, uplo := range []blas.Uplo{blas.Lower, blas.Upper} {
			for _, incX := range []int{-11, -2, -1, 1, 2, 7} {
				for _, lda := range []int{max(1, n), n + 11} {
					x := makeZVector(test.x, incX)
					xCopy := make([]complex128, len(x))
					copy(xCopy, x)

					a := makeZGeneral(test.a, n, n, lda)

					var want []complex128
					if incX > 0 {
						want = makeZGeneral(test.want, n, n, lda)
					} else {
						want = makeZGeneral(test.wantRev, n, n, lda)
					}

					if uplo == blas.Upper {
						for i := 0; i < n; i++ {
							for j := 0; j < i; j++ {
								a[i*lda+j] = cmplx.NaN()
								want[i*lda+j] = cmplx.NaN()
							}
						}
					} else {
						for i := 0; i < n; i++ {
							for j := i + 1; j < n; j++ {
								a[i*lda+j] = cmplx.NaN()
								want[i*lda+j] = cmplx.NaN()
							}
						}
					}

					impl.Zher(uplo, n, test.alpha, x, incX, a, lda)

					if !zsame(x, xCopy) {
						t.Errorf("Case %v (uplo=%v,incX=%v,lda=%v,alpha=%v): unexpected modification of x", tc, uplo, incX, test.alpha, lda)
					}
					if !zsame(want, a) {
						t.Errorf("Case %v (uplo=%v,incX=%v,lda=%v,alpha=%v): unexpected result\nwant: %v\ngot:  %v", tc, uplo, incX, lda, test.alpha, want, a)
					}
				}
			}
		}
	}
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors 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 mungers

import (
	"fmt"
	"regexp"

	"k8s.io/contrib/mungegithub/github"

	"github.com/golang/glog"
	githubapi "github.com/google/go-github/github"
	"github.com/spf13/cobra"
	"k8s.io/kubernetes/pkg/util/sets"
)

// RebuildMunger looks for situations where a someone has asked for an e2e rebuild, but hasn't provided
// an issue
type RebuildMunger struct {
	robots sets.String
}

var (
	buildMatcher = regexp.MustCompile("@k8s-bot\\s+(?:e2e\\s+)?(?:unit\\s+)?test\\s+this.*")
	issueMatcher = regexp.MustCompile("\\s+(?:github\\s+)?(issue|flake)\\:?\\s+#(?:IGNORE|[0-9]+)")
)

func init() {
	RegisterMungerOrDie(&RebuildMunger{})
}

// Name is the name usable in --pr-mungers
func (r *RebuildMunger) Name() string { return "rebuild-request" }

// Initialize will initialize the munger
func (r *RebuildMunger) Initialize(config *github.Config) error {
	r.robots = sets.NewString("googlebot", "k8s-bot", "k8s-merge-robot")
	return nil
}

// EachLoop is called at the start of every munge loop
func (r *RebuildMunger) EachLoop() error { return nil }

// AddFlags will add any request flags to the cobra `cmd`
func (r *RebuildMunger) AddFlags(cmd *cobra.Command, config *github.Config) {}

// Munge is the workhorse the will actually make updates to the PR
func (r *RebuildMunger) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	comments, err := obj.ListComments(*obj.Issue.Number)
	if err != nil {
		glog.Errorf("unexpected error getting comments: %v", err)
	}

	for ix := range comments {
		comment := &comments[ix]
		// Skip all robot comments
		if r.robots.Has(*comment.User.Login) {
			glog.V(4).Infof("Skipping comment by robot %s: %s", *comment.User.Login, *comment.Body)
			continue
		}
		if isRebuildComment(comment) && rebuildCommentMissingIssueNumber(comment) {
			if err := obj.DeleteComment(comment); err != nil {
				glog.Errorf("Error deleting comment: %v", err)
				continue
			}
			body := fmt.Sprintf(`@%s you must link to the test flake issue when requesting a manual test.
Expecting comment of the form '@k8s-bot test this github issue: #\<number\>'
[Open test flakes](https://github.com/kubernetes/kubernetes/issues?q=is:issue+label:kind/flake+is:open)`, *comment.User.Login)
			err := obj.WriteComment(body)
			if err != nil {
				glog.Errorf("unexpected error adding comment: %v", err)
				continue
			}
			if obj.HasLabel("lgtm") {
				if err := obj.RemoveLabel("lgtm"); err != nil {
					glog.Errorf("unexpected error removing lgtm label: %v", err)
				}
			}
		}
	}
}

func isRebuildComment(comment *githubapi.IssueComment) bool {
	return buildMatcher.MatchString(*comment.Body)
}

func rebuildCommentMissingIssueNumber(comment *githubapi.IssueComment) bool {
	return !issueMatcher.MatchString(*comment.Body)
}
<commit_msg>Another test flake munger message tweak<commit_after>/*
Copyright 2016 The Kubernetes Authors 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 mungers

import (
	"fmt"
	"regexp"

	"k8s.io/contrib/mungegithub/github"

	"github.com/golang/glog"
	githubapi "github.com/google/go-github/github"
	"github.com/spf13/cobra"
	"k8s.io/kubernetes/pkg/util/sets"
)

// RebuildMunger looks for situations where a someone has asked for an e2e rebuild, but hasn't provided
// an issue
type RebuildMunger struct {
	robots sets.String
}

var (
	buildMatcher = regexp.MustCompile("@k8s-bot\\s+(?:e2e\\s+)?(?:unit\\s+)?test\\s+this.*")
	issueMatcher = regexp.MustCompile("\\s+(?:github\\s+)?(issue|flake)\\:?\\s+#(?:IGNORE|[0-9]+)")
)

func init() {
	RegisterMungerOrDie(&RebuildMunger{})
}

// Name is the name usable in --pr-mungers
func (r *RebuildMunger) Name() string { return "rebuild-request" }

// Initialize will initialize the munger
func (r *RebuildMunger) Initialize(config *github.Config) error {
	r.robots = sets.NewString("googlebot", "k8s-bot", "k8s-merge-robot")
	return nil
}

// EachLoop is called at the start of every munge loop
func (r *RebuildMunger) EachLoop() error { return nil }

// AddFlags will add any request flags to the cobra `cmd`
func (r *RebuildMunger) AddFlags(cmd *cobra.Command, config *github.Config) {}

// Munge is the workhorse the will actually make updates to the PR
func (r *RebuildMunger) Munge(obj *github.MungeObject) {
	if !obj.IsPR() {
		return
	}

	comments, err := obj.ListComments(*obj.Issue.Number)
	if err != nil {
		glog.Errorf("unexpected error getting comments: %v", err)
	}

	for ix := range comments {
		comment := &comments[ix]
		// Skip all robot comments
		if r.robots.Has(*comment.User.Login) {
			glog.V(4).Infof("Skipping comment by robot %s: %s", *comment.User.Login, *comment.Body)
			continue
		}
		if isRebuildComment(comment) && rebuildCommentMissingIssueNumber(comment) {
			if err := obj.DeleteComment(comment); err != nil {
				glog.Errorf("Error deleting comment: %v", err)
				continue
			}
			body := fmt.Sprintf(`@%s
You must link to the test flake issue which caused you to request this manual re-test.
Re-test requests should be in the form of: `+"`"+`k8s-bot test this issue: #<number>`+"`"+`
Here is the [list of open test flakes](https://github.com/kubernetes/kubernetes/issues?q=is:issue+label:kind/flake+is:open).`, *comment.User.Login)
			err := obj.WriteComment(body)
			if err != nil {
				glog.Errorf("unexpected error adding comment: %v", err)
				continue
			}
			if obj.HasLabel("lgtm") {
				if err := obj.RemoveLabel("lgtm"); err != nil {
					glog.Errorf("unexpected error removing lgtm label: %v", err)
				}
			}
		}
	}
}

func isRebuildComment(comment *githubapi.IssueComment) bool {
	return buildMatcher.MatchString(*comment.Body)
}

func rebuildCommentMissingIssueNumber(comment *githubapi.IssueComment) bool {
	return !issueMatcher.MatchString(*comment.Body)
}
<|endoftext|>


<commit_before>// Copyright 2016 Google LLC
//
// 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 iterator_test

import (
	"bytes"
	"context"
	"fmt"
	"html/template"
	"log"
	"math"
	"net/http"
	"sort"
	"strconv"

	"google.golang.org/api/iterator"
)

var (
	client *Client
	ctx    = context.Background()
)

var pageTemplate = template.Must(template.New("").Parse(`

  {{range .Entries}}

{{.}}

  {{end}}

{{with .Next}}
  Next Page
{{end}}
`))

// This example demonstrates how to use Pager to support
// pagination on a web site.
func Example_webHandler(w http.ResponseWriter, r *http.Request) {
	const pageSize = 25
	it := client.Items(ctx)
	var items []int
	pageToken, err := iterator.NewPager(it, pageSize, r.URL.Query().Get("pageToken")).NextPage(&items)
	if err != nil {
		http.Error(w, fmt.Sprintf("getting next page: %v", err), http.StatusInternalServerError)
	}
	data := struct {
		Items []int
		Next  string
	}{
		items,
		pageToken,
	}
	var buf bytes.Buffer
	if err := pageTemplate.Execute(&buf, data); err != nil {
		http.Error(w, fmt.Sprintf("executing page template: %v", err), http.StatusInternalServerError)
	}
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	if _, err := buf.WriteTo(w); err != nil {
		log.Printf("writing response: %v", err)
	}
}

// This example demonstrates how to use a Pager to page through an iterator in a loop.
func Example_pageLoop() {
	// Find all primes up to 42, in pages of size 5.
	const max = 42
	const pageSize = 5
	p := iterator.NewPager(Primes(max), pageSize, "" /* start from the beginning */)
	for page := 0; ; page++ {
		var items []int
		pageToken, err := p.NextPage(&items)
		if err != nil {
			log.Fatalf("Iterator paging failed: %v", err)
		}
		fmt.Printf("Page %d: %v\n", page, items)
		if pageToken == "" {
			break
		}
	}
	// Output:
	// Page 0: [2 3 5 7 11]
	// Page 1: [13 17 19 23 29]
	// Page 2: [31 37 41]
}

// The example demonstrates how to use a Pager to request a page from a given token.
func Example_pageToken() {
	const pageSize = 5
	const pageToken = "1337"
	p := iterator.NewPager(Primes(0), pageSize, pageToken)

	var items []int
	nextPage, err := p.NextPage(&items)
	if err != nil {
		log.Fatalf("Iterator paging failed: %v", err)
	}
	fmt.Printf("Primes: %v\nToken:  %q\n", items, nextPage)
	// Output:
	// Primes: [1361 1367 1373 1381 1399]
	// Token:  "1400"
}

// This example demonstrates how to get exactly the items in the buffer, without
// triggering an extra RPC.
func Example_serverPages() {
	// The iterator returned by Primes has a default page size of 20, which means
	// it will return all the primes in the range [2, 21).
	it := Primes(0)
	var items []int
	for {
		item, err := it.Next()
		if err != nil && err != iterator.Done {
			log.Fatal(err)
		}
		if err == iterator.Done {
			break
		}
		items = append(items, item)
		if it.PageInfo().Remaining() == 0 {
			break
		}
	}
	fmt.Println(items)
	// Output:
	// [2 3 5 7 11 13 17 19]
}

// Primes returns a iterator which returns a sequence of prime numbers.
// If non-zero, max specifies the maximum number which could possibly be
// returned.
func Primes(max int) *SieveIterator {
	it := &SieveIterator{pos: 2, max: max}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(
		it.fetch,
		func() int { return len(it.items) },
		func() interface{} { b := it.items; it.items = nil; return b })
	return it
}

// SieveIterator is an iterator that returns primes using the sieve of
// Eratosthenes. It is a demonstration of how an iterator might work.
// Internally, it uses "page size" as the number of ints to consider,
// and "page token" as the first number to consider (defaults to 2).
type SieveIterator struct {
	pageInfo *iterator.PageInfo
	nextFunc func() error
	max      int   // The largest number to consider.
	p        []int // Primes in the range [2, pos).
	pos      int   // Next number to consider when generating p.
	items    []int
}

// PageInfo returns a PageInfo, which supports pagination.
func (it *SieveIterator) PageInfo() *iterator.PageInfo { return it.pageInfo }

func (it *SieveIterator) fetch(pageSize int, pageToken string) (string, error) {
	start := 2
	if pageToken != "" {
		s, err := strconv.Atoi(pageToken)
		if err != nil || s < 2 {
			return "", fmt.Errorf("invalid token %q", pageToken)
		}
		start = s
	}
	if pageSize == 0 {
		pageSize = 20 // Default page size.
	}

	// Make sure sufficient primes have been calculated.
	it.calc(start + pageSize)

	// Find the subslice of primes which match this page.
	// Note that PageInfo requires that fetch does not remove any existing items,
	// so we cannot assume that items is empty at this call.
	items := it.p[sort.SearchInts(it.p, start):]
	items = items[:sort.SearchInts(items, start+pageSize)]
	it.items = append(it.items, items...)

	if it.max > 0 && start+pageSize > it.max {
		return "", nil // No more possible numbers to return.
	}

	return strconv.Itoa(start + pageSize), nil
}

// calc populates p with all primes up to, but not including, max.
func (it *SieveIterator) calc(max int) {
	if it.max > 0 && max > it.max+1 { // it.max is an inclusive bounds, max is exclusive.
		max = it.max + 1
	}
outer:
	for x := it.pos; x < max; x++ {
		sqrt := int(math.Sqrt(float64(x)))
	inner:
		for _, p := range it.p {
			switch {
			case x%p == 0:
				// Not a prime.
				continue outer
			case p > sqrt:
				// Only need to check up to sqrt.
				break inner
			}
		}
		it.p = append(it.p, x)
	}
	it.pos = max
}

func (it *SieveIterator) Next() (int, error) {
	if err := it.nextFunc(); err != nil {
		return 0, err
	}
	item := it.items[0]
	it.items = it.items[1:]
	return item, nil
}
<commit_msg>docs: add basic iterator example<commit_after>// Copyright 2016 Google LLC
//
// 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 iterator_test

import (
	"bytes"
	"context"
	"fmt"
	"html/template"
	"log"
	"math"
	"net/http"
	"sort"
	"strconv"

	"google.golang.org/api/iterator"
)

var (
	client *Client
	ctx    = context.Background()
)

var pageTemplate = template.Must(template.New("").Parse(`

  {{range .Entries}}

{{.}}

  {{end}}

{{with .Next}}
  Next Page
{{end}}
`))

func Example() {
	it := Primes(19)

	for {
		item, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("%d ", item)
	}
	// Output:
	// 2 3 5 7 11 13 17 19
}

// This example demonstrates how to use Pager to support
// pagination on a web site.
func Example_webHandler(w http.ResponseWriter, r *http.Request) {
	const pageSize = 25
	it := client.Items(ctx)
	var items []int
	pageToken, err := iterator.NewPager(it, pageSize, r.URL.Query().Get("pageToken")).NextPage(&items)
	if err != nil {
		http.Error(w, fmt.Sprintf("getting next page: %v", err), http.StatusInternalServerError)
	}
	data := struct {
		Items []int
		Next  string
	}{
		items,
		pageToken,
	}
	var buf bytes.Buffer
	if err := pageTemplate.Execute(&buf, data); err != nil {
		http.Error(w, fmt.Sprintf("executing page template: %v", err), http.StatusInternalServerError)
	}
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	if _, err := buf.WriteTo(w); err != nil {
		log.Printf("writing response: %v", err)
	}
}

// This example demonstrates how to use a Pager to page through an iterator in a loop.
func Example_pageLoop() {
	// Find all primes up to 42, in pages of size 5.
	const max = 42
	const pageSize = 5
	p := iterator.NewPager(Primes(max), pageSize, "" /* start from the beginning */)
	for page := 0; ; page++ {
		var items []int
		pageToken, err := p.NextPage(&items)
		if err != nil {
			log.Fatalf("Iterator paging failed: %v", err)
		}
		fmt.Printf("Page %d: %v\n", page, items)
		if pageToken == "" {
			break
		}
	}
	// Output:
	// Page 0: [2 3 5 7 11]
	// Page 1: [13 17 19 23 29]
	// Page 2: [31 37 41]
}

// The example demonstrates how to use a Pager to request a page from a given token.
func Example_pageToken() {
	const pageSize = 5
	const pageToken = "1337"
	p := iterator.NewPager(Primes(0), pageSize, pageToken)

	var items []int
	nextPage, err := p.NextPage(&items)
	if err != nil {
		log.Fatalf("Iterator paging failed: %v", err)
	}
	fmt.Printf("Primes: %v\nToken:  %q\n", items, nextPage)
	// Output:
	// Primes: [1361 1367 1373 1381 1399]
	// Token:  "1400"
}

// This example demonstrates how to get exactly the items in the buffer, without
// triggering an extra RPC.
func Example_serverPages() {
	// The iterator returned by Primes has a default page size of 20, which means
	// it will return all the primes in the range [2, 21).
	it := Primes(0)
	var items []int
	for {
		item, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
		items = append(items, item)
		if it.PageInfo().Remaining() == 0 {
			break
		}
	}
	fmt.Println(items)
	// Output:
	// [2 3 5 7 11 13 17 19]
}

// Primes returns a iterator which returns a sequence of prime numbers.
// If non-zero, max specifies the maximum number which could possibly be
// returned.
func Primes(max int) *SieveIterator {
	it := &SieveIterator{pos: 2, max: max}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(
		it.fetch,
		func() int { return len(it.items) },
		func() interface{} { b := it.items; it.items = nil; return b })
	return it
}

// SieveIterator is an iterator that returns primes using the sieve of
// Eratosthenes. It is a demonstration of how an iterator might work.
// Internally, it uses "page size" as the number of ints to consider,
// and "page token" as the first number to consider (defaults to 2).
type SieveIterator struct {
	pageInfo *iterator.PageInfo
	nextFunc func() error
	max      int   // The largest number to consider.
	p        []int // Primes in the range [2, pos).
	pos      int   // Next number to consider when generating p.
	items    []int
}

// PageInfo returns a PageInfo, which supports pagination.
func (it *SieveIterator) PageInfo() *iterator.PageInfo { return it.pageInfo }

func (it *SieveIterator) fetch(pageSize int, pageToken string) (string, error) {
	start := 2
	if pageToken != "" {
		s, err := strconv.Atoi(pageToken)
		if err != nil || s < 2 {
			return "", fmt.Errorf("invalid token %q", pageToken)
		}
		start = s
	}
	if pageSize == 0 {
		pageSize = 20 // Default page size.
	}

	// Make sure sufficient primes have been calculated.
	it.calc(start + pageSize)

	// Find the subslice of primes which match this page.
	// Note that PageInfo requires that fetch does not remove any existing items,
	// so we cannot assume that items is empty at this call.
	items := it.p[sort.SearchInts(it.p, start):]
	items = items[:sort.SearchInts(items, start+pageSize)]
	it.items = append(it.items, items...)

	if it.max > 0 && start+pageSize > it.max {
		return "", nil // No more possible numbers to return.
	}

	return strconv.Itoa(start + pageSize), nil
}

// calc populates p with all primes up to, but not including, max.
func (it *SieveIterator) calc(max int) {
	if it.max > 0 && max > it.max+1 { // it.max is an inclusive bounds, max is exclusive.
		max = it.max + 1
	}
outer:
	for x := it.pos; x < max; x++ {
		sqrt := int(math.Sqrt(float64(x)))
	inner:
		for _, p := range it.p {
			switch {
			case x%p == 0:
				// Not a prime.
				continue outer
			case p > sqrt:
				// Only need to check up to sqrt.
				break inner
			}
		}
		it.p = append(it.p, x)
	}
	it.pos = max
}

func (it *SieveIterator) Next() (int, error) {
	if err := it.nextFunc(); err != nil {
		return 0, err
	}
	item := it.items[0]
	it.items = it.items[1:]
	return item, nil
}
<|endoftext|>


<commit_before>// Copyright 2016 go-mxnet-predictor Authors. 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 mxnet

/*
// go preamble
#cgo pkg-config: mxnet
#include <mxnet/c_predict_api.h>
#include <stdlib.h>
*/
import "C"
import (
	"fmt"
	"unsafe"
)

const (
	CPU_DEVICE = iota + 1 // cpu device type
	GPU_DEVICE            // gpu device type
)

//TODO higher level api like context
type Device struct {
	Type int // device type
	Id   int // device id
}

type InputNode struct {
	Key   string   // name
	Shape []uint32 // shape of ndarray
}

// predictor for inference
type Predictor struct {
	handle C.PredictorHandle // C handle of predictor
}

// Create a Predictor
// go binding for MXPredCreate
// param symbol The JSON string of the symbol
// param params In-memory raw bytes of parameter ndarray file
// param device Device to run predictor
// param nodes An array of InputNode which stored the name and shape data of ndarray item
func CreatePredictor(symbol []byte,
	params []byte,
	device Device,
	nodes []InputNode,
) (*Predictor, error) {

	var (
		pc        *C.char
		shapeIdx  = []uint32{}
		shapeData = []uint32{}
	)

	// malloc a **char which like []string to store node keys
	keys := C.malloc(C.size_t(len(nodes)) * C.size_t(unsafe.Sizeof(pc))) // c gc
	j := 0
	for i := 0; i < len(nodes); i++ {
		// get memory address
		p := (**C.char)(unsafe.Pointer(uintptr(keys) + uintptr(i)*unsafe.Sizeof(pc)))
		// c gc
		*p = C.CString(nodes[i].Key)

		// shapeIdx for next node
		shapeIdx = append(shapeIdx, uint32(j+len(nodes[i].Shape)))
		j += len(nodes[i].Shape)
		// shape data for current node
		shapeData = append(shapeData, nodes[i].Shape...)
	}

	var handle C.PredictorHandle

	success := C.MXPredCreate((*C.char)(unsafe.Pointer(&symbol[0])),
		unsafe.Pointer(&params[0]),
		C.int(len(params)),
		C.int(device.Type),
		C.int(device.Id),
		C.mx_uint(len(nodes)),
		(**C.char)(keys),
		(*C.mx_uint)(unsafe.Pointer(&shapeIdx[0])),
		(*C.mx_uint)(unsafe.Pointer(&shapeData[0])),
		&handle,
	)

	// free mem we created before return, go gc won't do that for us
	for i := 0; i < len(nodes); i++ {
		p := (**C.char)(unsafe.Pointer(uintptr(keys) + uintptr(i)*unsafe.Sizeof(pc)))
		C.free(unsafe.Pointer(*p))
	}
	C.free(unsafe.Pointer(keys))

	if success < 0 {
		return nil, GetLastError()
	}
	return &Predictor{handle: handle}, nil
}

// CreatePredictorPartial Creates a Predictor wich customized outputs [layer]
// go binding for MXPredCreate
// param symbol The JSON string of the symbol
// param params In-memory raw bytes of parameter ndarray file
// param device Device to run predictor
// param nodes An array of InputNode which stored the name and shape data of ndarray item
// param outputKey the name of the output layer/key
func CreatePredictorPartial(symbol []byte,
	params []byte,
	device Device,
	nodes []InputNode,
	outputKey string,
) (*Predictor, error) {

	var (
		pc        *C.char
		shapeIdx  = []uint32{0}
		shapeData = []uint32{}
	)

	// malloc a **char which like []string to store node keys
	keys := C.malloc(C.size_t(len(nodes)) * C.size_t(unsafe.Sizeof(pc))) // c gc
	for i := 0; i < len(nodes); i++ {
		// get memory address
		p := (**C.char)(unsafe.Pointer(uintptr(keys) + uintptr(i)*unsafe.Sizeof(pc)))
		// c gc
		*p = C.CString(nodes[i].Key)

		// shapeIdx for next node
		shapeIdx = append(shapeIdx, uint32(len(nodes[i].Shape)))
		// shape data for current node
		shapeData = append(shapeData, nodes[i].Shape...)
	}

	oKeys := C.malloc(C.size_t(len(nodes)) * C.size_t(unsafe.Sizeof(pc)))
	p := (**C.char)(unsafe.Pointer(uintptr(oKeys)))
	*p = C.CString(outputKey)

	var handle C.PredictorHandle

	success := C.MXPredCreatePartialOut((*C.char)(unsafe.Pointer(&symbol[0])),
		unsafe.Pointer(&params[0]),
		C.int(len(params)),
		C.int(device.Type),
		C.int(device.Id),
		C.mx_uint(len(nodes)),
		(**C.char)(keys),
		(*C.mx_uint)(unsafe.Pointer(&shapeIdx[0])),
		(*C.mx_uint)(unsafe.Pointer(&shapeData[0])),
		C.mx_uint(1),
		(**C.char)(oKeys),
		&handle,
	)

	// free mem we created before return, go gc won't do that for us
	for i := 0; i < len(nodes); i++ {
		p := (**C.char)(unsafe.Pointer(uintptr(keys) + uintptr(i)*unsafe.Sizeof(pc)))
		C.free(unsafe.Pointer(*p))
	}
	C.free(unsafe.Pointer(keys))

	if success < 0 {
		return nil, GetLastError()
	}
	return &Predictor{handle: handle}, nil
}

// set the input data of predictor
// go binding for MXPredSetInput
// param key The name of input node to set
// param data The float data to be set
func (s *Predictor) SetInput(key string, data []float32) error {
	// check input
	if data == nil || len(data) < 1 {
		return fmt.Errorf("intput data nil or empty")
	}

	// c gc
	k := C.CString(key)
	// free mem before return
	defer C.free(unsafe.Pointer(k))

	success, err := C.MXPredSetInput(s.handle,
		k,
		(*C.mx_float)(unsafe.Pointer(&data[0])),
		C.mx_uint(len(data)),
	)

	if err != nil {
		return err
	} else if success < 0 {
		return GetLastError()
	}
	return nil
}

// run a forward pass after SetInput
// go binding for MXPredForward
func (s *Predictor) Forward() error {
	success, err := C.MXPredForward(s.handle)
	if err != nil {
		return err
	} else if success < 0 {
		return GetLastError()
	}
	return nil
}

// get the shape of output node
// go binding for MXPredGetOutputShape
// param index The index of output node, set to 0 if there is only one output
func (s *Predictor) GetOutputShape(index uint32) ([]uint32, error) {
	var (
		shapeData *C.mx_uint
		shapeDim  C.mx_uint
	)
	success, err := C.MXPredGetOutputShape(s.handle,
		C.mx_uint(index),
		&shapeData,
		&shapeDim,
	)
	if err != nil {
		return nil, err
	} else if success < 0 {
		return nil, GetLastError()
	}
	// c array to go
	shape := (*[1 << 32]uint32)(unsafe.Pointer(shapeData))[:shapeDim:shapeDim]
	return shape, nil
}

// get the output value of prediction
// go binding for MXPredGetOutput
// param index The index of output node, set to 0 if there is only one output
func (s *Predictor) GetOutput(index uint32) ([]float32, error) {
	shape, err := s.GetOutputShape(index)
	if err != nil {
		return nil, err
	}
	size := uint32(1)
	for _, v := range shape {
		size *= v
	}
	data := make([]float32, size)
	success, err := C.MXPredGetOutput(s.handle,
		C.mx_uint(index),
		(*C.mx_float)(unsafe.Pointer(&data[0])),
		C.mx_uint(size),
	)
	if err != nil {
		return nil, err
	} else if success < 0 {
		return nil, GetLastError()
	}
	return data, nil
}

// free this predictor's C handle
// go binding for MXPredFree
func (s *Predictor) Free() error {
	success, err := C.MXPredFree(s.handle)
	if err != nil {
		return err
	} else if success < 0 {
		return GetLastError()
	}
	return nil
}
<commit_msg>actually correct fix.<commit_after>// Copyright 2016 go-mxnet-predictor Authors. 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 mxnet

/*
// go preamble
#cgo pkg-config: mxnet
#include <mxnet/c_predict_api.h>
#include <stdlib.h>
*/
import "C"
import (
	"fmt"
	"unsafe"
)

const (
	CPU_DEVICE = iota + 1 // cpu device type
	GPU_DEVICE            // gpu device type
)

//TODO higher level api like context
type Device struct {
	Type int // device type
	Id   int // device id
}

type InputNode struct {
	Key   string   // name
	Shape []uint32 // shape of ndarray
}

// predictor for inference
type Predictor struct {
	handle C.PredictorHandle // C handle of predictor
}

// Create a Predictor
// go binding for MXPredCreate
// param symbol The JSON string of the symbol
// param params In-memory raw bytes of parameter ndarray file
// param device Device to run predictor
// param nodes An array of InputNode which stored the name and shape data of ndarray item
func CreatePredictor(symbol []byte,
	params []byte,
	device Device,
	nodes []InputNode,
) (*Predictor, error) {

	var (
		pc        *C.char
		shapeIdx  = []uint32{0}
		shapeData = []uint32{}
	)

	// malloc a **char which like []string to store node keys
	keys := C.malloc(C.size_t(len(nodes)) * C.size_t(unsafe.Sizeof(pc))) // c gc
	j := 0
	for i := 0; i < len(nodes); i++ {
		// get memory address
		p := (**C.char)(unsafe.Pointer(uintptr(keys) + uintptr(i)*unsafe.Sizeof(pc)))
		// c gc
		*p = C.CString(nodes[i].Key)

		// shapeIdx for next node
		shapeIdx = append(shapeIdx, uint32(j+len(nodes[i].Shape)))
		j += len(nodes[i].Shape)
		// shape data for current node
		shapeData = append(shapeData, nodes[i].Shape...)
	}

	var handle C.PredictorHandle

	success := C.MXPredCreate((*C.char)(unsafe.Pointer(&symbol[0])),
		unsafe.Pointer(&params[0]),
		C.int(len(params)),
		C.int(device.Type),
		C.int(device.Id),
		C.mx_uint(len(nodes)),
		(**C.char)(keys),
		(*C.mx_uint)(unsafe.Pointer(&shapeIdx[0])),
		(*C.mx_uint)(unsafe.Pointer(&shapeData[0])),
		&handle,
	)

	// free mem we created before return, go gc won't do that for us
	for i := 0; i < len(nodes); i++ {
		p := (**C.char)(unsafe.Pointer(uintptr(keys) + uintptr(i)*unsafe.Sizeof(pc)))
		C.free(unsafe.Pointer(*p))
	}
	C.free(unsafe.Pointer(keys))

	if success < 0 {
		return nil, GetLastError()
	}
	return &Predictor{handle: handle}, nil
}

// CreatePredictorPartial Creates a Predictor wich customized outputs [layer]
// go binding for MXPredCreate
// param symbol The JSON string of the symbol
// param params In-memory raw bytes of parameter ndarray file
// param device Device to run predictor
// param nodes An array of InputNode which stored the name and shape data of ndarray item
// param outputKey the name of the output layer/key
func CreatePredictorPartial(symbol []byte,
	params []byte,
	device Device,
	nodes []InputNode,
	outputKey string,
) (*Predictor, error) {

	var (
		pc        *C.char
		shapeIdx  = []uint32{0}
		shapeData = []uint32{}
	)

	// malloc a **char which like []string to store node keys
	keys := C.malloc(C.size_t(len(nodes)) * C.size_t(unsafe.Sizeof(pc))) // c gc
	j := 0
	for i := 0; i < len(nodes); i++ {
		// get memory address
		p := (**C.char)(unsafe.Pointer(uintptr(keys) + uintptr(i)*unsafe.Sizeof(pc)))
		// c gc
		*p = C.CString(nodes[i].Key)

		// shapeIdx for next node
		shapeIdx = append(shapeIdx, uint32(j+len(nodes[i].Shape)))
		j += len(nodes[i].Shape)
		// shape data for current node
		shapeData = append(shapeData, nodes[i].Shape...)
	}

	oKeys := C.malloc(C.size_t(len(nodes)) * C.size_t(unsafe.Sizeof(pc)))
	p := (**C.char)(unsafe.Pointer(uintptr(oKeys)))
	*p = C.CString(outputKey)

	var handle C.PredictorHandle

	success := C.MXPredCreatePartialOut((*C.char)(unsafe.Pointer(&symbol[0])),
		unsafe.Pointer(&params[0]),
		C.int(len(params)),
		C.int(device.Type),
		C.int(device.Id),
		C.mx_uint(len(nodes)),
		(**C.char)(keys),
		(*C.mx_uint)(unsafe.Pointer(&shapeIdx[0])),
		(*C.mx_uint)(unsafe.Pointer(&shapeData[0])),
		C.mx_uint(1),
		(**C.char)(oKeys),
		&handle,
	)

	// free mem we created before return, go gc won't do that for us
	for i := 0; i < len(nodes); i++ {
		p := (**C.char)(unsafe.Pointer(uintptr(keys) + uintptr(i)*unsafe.Sizeof(pc)))
		C.free(unsafe.Pointer(*p))
	}
	C.free(unsafe.Pointer(keys))

	if success < 0 {
		return nil, GetLastError()
	}
	return &Predictor{handle: handle}, nil
}

// set the input data of predictor
// go binding for MXPredSetInput
// param key The name of input node to set
// param data The float data to be set
func (s *Predictor) SetInput(key string, data []float32) error {
	// check input
	if data == nil || len(data) < 1 {
		return fmt.Errorf("intput data nil or empty")
	}

	// c gc
	k := C.CString(key)
	// free mem before return
	defer C.free(unsafe.Pointer(k))

	success, err := C.MXPredSetInput(s.handle,
		k,
		(*C.mx_float)(unsafe.Pointer(&data[0])),
		C.mx_uint(len(data)),
	)

	if err != nil {
		return err
	} else if success < 0 {
		return GetLastError()
	}
	return nil
}

// run a forward pass after SetInput
// go binding for MXPredForward
func (s *Predictor) Forward() error {
	success, err := C.MXPredForward(s.handle)
	if err != nil {
		return err
	} else if success < 0 {
		return GetLastError()
	}
	return nil
}

// get the shape of output node
// go binding for MXPredGetOutputShape
// param index The index of output node, set to 0 if there is only one output
func (s *Predictor) GetOutputShape(index uint32) ([]uint32, error) {
	var (
		shapeData *C.mx_uint
		shapeDim  C.mx_uint
	)
	success, err := C.MXPredGetOutputShape(s.handle,
		C.mx_uint(index),
		&shapeData,
		&shapeDim,
	)
	if err != nil {
		return nil, err
	} else if success < 0 {
		return nil, GetLastError()
	}
	// c array to go
	shape := (*[1 << 32]uint32)(unsafe.Pointer(shapeData))[:shapeDim:shapeDim]
	return shape, nil
}

// get the output value of prediction
// go binding for MXPredGetOutput
// param index The index of output node, set to 0 if there is only one output
func (s *Predictor) GetOutput(index uint32) ([]float32, error) {
	shape, err := s.GetOutputShape(index)
	if err != nil {
		return nil, err
	}
	size := uint32(1)
	for _, v := range shape {
		size *= v
	}
	data := make([]float32, size)
	success, err := C.MXPredGetOutput(s.handle,
		C.mx_uint(index),
		(*C.mx_float)(unsafe.Pointer(&data[0])),
		C.mx_uint(size),
	)
	if err != nil {
		return nil, err
	} else if success < 0 {
		return nil, GetLastError()
	}
	return data, nil
}

// free this predictor's C handle
// go binding for MXPredFree
func (s *Predictor) Free() error {
	success, err := C.MXPredFree(s.handle)
	if err != nil {
		return err
	} else if success < 0 {
		return GetLastError()
	}
	return nil
}
<|endoftext|>


<commit_before>package user_test

import (
	f "github.com/lastbackend/lastbackend/utils"
	"io/ioutil"
	"testing"
	"github.com/stretchr/testify/assert"
	"github.com/lastbackend/lastbackend/pkg/client/cmd/user"
)

func TestLogout(t *testing.T) {
	err := f.MkDir(f.GetHomeDir() + "/.lb", 0777)
	if err != nil {
		t.Error(err)
	}

	files, err := ioutil.ReadDir(f.GetHomeDir() + "/.lb")
	if err != nil {
		t.Error(err)
	}

	assert.NotNil(t, files)

	err = user.Logout()
	if err != nil {
		t.Error(err)
	}

	files, err = ioutil.ReadDir(f.GetHomeDir() + "/.lb")
	if err != nil {
		t.Error(err)
	}

	assert.Nil(t, files)
}
<commit_msg>Fix logout test<commit_after>package user_test

import (
	f "github.com/lastbackend/lastbackend/utils"
	"io/ioutil"
	"testing"
	"github.com/stretchr/testify/assert"
	"github.com/lastbackend/lastbackend/pkg/client/cmd/user"
)

func TestLogout(t *testing.T) {
	err := f.MkDir(f.GetHomeDir() + "/.lb", 0777)
	if err != nil {
		t.Error(err)
	}

	files, err := ioutil.ReadDir(f.GetHomeDir() + "/.lb")
	if err != nil {
		t.Error(err)
	}

	assert.NotNil(t, files)

	err = user.Logout()
	if err != nil {
		t.Error(err)
	}

	files, err = ioutil.ReadDir(f.GetHomeDir() + "/.lb")
	if err != nil {
		assert.Nil(t, files)
	}
}
<|endoftext|>