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

import (
	"fmt"

	"k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/uuid"
	utilversion "k8s.io/kubernetes/pkg/util/version"
	"k8s.io/kubernetes/test/e2e/framework"

	. "github.com/onsi/ginkgo"
)

var hostIPVersion = utilversion.MustParseSemantic("v1.8.0")

var _ = framework.KubeDescribe("Downward API", func() {
	f := framework.NewDefaultFramework("downward-api")

	It("should provide pod name and namespace as env vars [Conformance]", func() {
		podName := "downward-api-" + string(uuid.NewUUID())
		env := []v1.EnvVar{
			{
				Name: "POD_NAME",
				ValueFrom: &v1.EnvVarSource{
					FieldRef: &v1.ObjectFieldSelector{
						APIVersion: "v1",
						FieldPath:  "metadata.name",
					},
				},
			},
			{
				Name: "POD_NAMESPACE",
				ValueFrom: &v1.EnvVarSource{
					FieldRef: &v1.ObjectFieldSelector{
						APIVersion: "v1",
						FieldPath:  "metadata.namespace",
					},
				},
			},
		}

		expectations := []string{
			fmt.Sprintf("POD_NAME=%v", podName),
			fmt.Sprintf("POD_NAMESPACE=%v", f.Namespace.Name),
		}

		testDownwardAPI(f, podName, env, expectations)
	})

	It("should provide pod and host IP as an env var [Conformance]", func() {
		framework.SkipUnlessServerVersionGTE(hostIPVersion, f.ClientSet.Discovery())
		podName := "downward-api-" + string(uuid.NewUUID())
		env := []v1.EnvVar{
			{
				Name: "POD_IP",
				ValueFrom: &v1.EnvVarSource{
					FieldRef: &v1.ObjectFieldSelector{
						APIVersion: "v1",
						FieldPath:  "status.podIP",
					},
				},
			},
			{
				Name: "HOST_IP",
				ValueFrom: &v1.EnvVarSource{
					FieldRef: &v1.ObjectFieldSelector{
						APIVersion: "v1",
						FieldPath:  "status.hostIP",
					},
				},
			},
		}

		expectations := []string{
			"POD_IP=(?:\\d+)\\.(?:\\d+)\\.(?:\\d+)\\.(?:\\d+)",
			"HOST_IP=(?:\\d+)\\.(?:\\d+)\\.(?:\\d+)\\.(?:\\d+)",
		}

		testDownwardAPI(f, podName, env, expectations)
	})

	It("should provide container's limits.cpu/memory and requests.cpu/memory as env vars [Conformance]", func() {
		podName := "downward-api-" + string(uuid.NewUUID())
		env := []v1.EnvVar{
			{
				Name: "CPU_LIMIT",
				ValueFrom: &v1.EnvVarSource{
					ResourceFieldRef: &v1.ResourceFieldSelector{
						Resource: "limits.cpu",
					},
				},
			},
			{
				Name: "MEMORY_LIMIT",
				ValueFrom: &v1.EnvVarSource{
					ResourceFieldRef: &v1.ResourceFieldSelector{
						Resource: "limits.memory",
					},
				},
			},
			{
				Name: "CPU_REQUEST",
				ValueFrom: &v1.EnvVarSource{
					ResourceFieldRef: &v1.ResourceFieldSelector{
						Resource: "requests.cpu",
					},
				},
			},
			{
				Name: "MEMORY_REQUEST",
				ValueFrom: &v1.EnvVarSource{
					ResourceFieldRef: &v1.ResourceFieldSelector{
						Resource: "requests.memory",
					},
				},
			},
		}
		expectations := []string{
			fmt.Sprintf("CPU_LIMIT=2"),
			fmt.Sprintf("MEMORY_LIMIT=67108864"),
			fmt.Sprintf("CPU_REQUEST=1"),
			fmt.Sprintf("MEMORY_REQUEST=33554432"),
		}

		testDownwardAPI(f, podName, env, expectations)
	})

	It("should provide default limits.cpu/memory from node allocatable [Conformance]", func() {
		podName := "downward-api-" + string(uuid.NewUUID())
		env := []v1.EnvVar{
			{
				Name: "CPU_LIMIT",
				ValueFrom: &v1.EnvVarSource{
					ResourceFieldRef: &v1.ResourceFieldSelector{
						Resource: "limits.cpu",
					},
				},
			},
			{
				Name: "MEMORY_LIMIT",
				ValueFrom: &v1.EnvVarSource{
					ResourceFieldRef: &v1.ResourceFieldSelector{
						Resource: "limits.memory",
					},
				},
			},
		}
		expectations := []string{
			fmt.Sprintf("CPU_LIMIT=[1-9]"),
			fmt.Sprintf("MEMORY_LIMIT=[1-9]"),
		}
		pod := &v1.Pod{
			ObjectMeta: metav1.ObjectMeta{
				Name:   podName,
				Labels: map[string]string{"name": podName},
			},
			Spec: v1.PodSpec{
				Containers: []v1.Container{
					{
						Name:    "dapi-container",
						Image:   busyboxImage,
						Command: []string{"sh", "-c", "env"},
						Env:     env,
					},
				},
				RestartPolicy: v1.RestartPolicyNever,
			},
		}

		testDownwardAPIUsingPod(f, pod, env, expectations)
	})
})

func testDownwardAPI(f *framework.Framework, podName string, env []v1.EnvVar, expectations []string) {
	pod := &v1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:   podName,
			Labels: map[string]string{"name": podName},
		},
		Spec: v1.PodSpec{
			Containers: []v1.Container{
				{
					Name:    "dapi-container",
					Image:   busyboxImage,
					Command: []string{"sh", "-c", "env"},
					Resources: v1.ResourceRequirements{
						Requests: v1.ResourceList{
							v1.ResourceCPU:    resource.MustParse("250m"),
							v1.ResourceMemory: resource.MustParse("32Mi"),
						},
						Limits: v1.ResourceList{
							v1.ResourceCPU:    resource.MustParse("1250m"),
							v1.ResourceMemory: resource.MustParse("64Mi"),
						},
					},
					Env: env,
				},
			},
			RestartPolicy: v1.RestartPolicyNever,
		},
	}

	testDownwardAPIUsingPod(f, pod, env, expectations)
}

func testDownwardAPIUsingPod(f *framework.Framework, pod *v1.Pod, env []v1.EnvVar, expectations []string) {
	f.TestContainerOutputRegexp("downward api env vars", pod, 0, expectations)
}
<commit_msg>Add e2e test case for downward API exposing pod UID<commit_after>/*
Copyright 2016 The Kubernetes 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 common

import (
	"fmt"

	"k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/util/uuid"
	utilversion "k8s.io/kubernetes/pkg/util/version"
	"k8s.io/kubernetes/test/e2e/framework"

	. "github.com/onsi/ginkgo"
)

var hostIPVersion = utilversion.MustParseSemantic("v1.8.0")

var _ = framework.KubeDescribe("Downward API", func() {
	f := framework.NewDefaultFramework("downward-api")

	It("should provide pod name and namespace as env vars [Conformance]", func() {
		podName := "downward-api-" + string(uuid.NewUUID())
		env := []v1.EnvVar{
			{
				Name: "POD_NAME",
				ValueFrom: &v1.EnvVarSource{
					FieldRef: &v1.ObjectFieldSelector{
						APIVersion: "v1",
						FieldPath:  "metadata.name",
					},
				},
			},
			{
				Name: "POD_NAMESPACE",
				ValueFrom: &v1.EnvVarSource{
					FieldRef: &v1.ObjectFieldSelector{
						APIVersion: "v1",
						FieldPath:  "metadata.namespace",
					},
				},
			},
		}

		expectations := []string{
			fmt.Sprintf("POD_NAME=%v", podName),
			fmt.Sprintf("POD_NAMESPACE=%v", f.Namespace.Name),
		}

		testDownwardAPI(f, podName, env, expectations)
	})

	It("should provide pod and host IP as an env var [Conformance]", func() {
		framework.SkipUnlessServerVersionGTE(hostIPVersion, f.ClientSet.Discovery())
		podName := "downward-api-" + string(uuid.NewUUID())
		env := []v1.EnvVar{
			{
				Name: "POD_IP",
				ValueFrom: &v1.EnvVarSource{
					FieldRef: &v1.ObjectFieldSelector{
						APIVersion: "v1",
						FieldPath:  "status.podIP",
					},
				},
			},
			{
				Name: "HOST_IP",
				ValueFrom: &v1.EnvVarSource{
					FieldRef: &v1.ObjectFieldSelector{
						APIVersion: "v1",
						FieldPath:  "status.hostIP",
					},
				},
			},
		}

		expectations := []string{
			"POD_IP=(?:\\d+)\\.(?:\\d+)\\.(?:\\d+)\\.(?:\\d+)",
			"HOST_IP=(?:\\d+)\\.(?:\\d+)\\.(?:\\d+)\\.(?:\\d+)",
		}

		testDownwardAPI(f, podName, env, expectations)
	})

	It("should provide container's limits.cpu/memory and requests.cpu/memory as env vars [Conformance]", func() {
		podName := "downward-api-" + string(uuid.NewUUID())
		env := []v1.EnvVar{
			{
				Name: "CPU_LIMIT",
				ValueFrom: &v1.EnvVarSource{
					ResourceFieldRef: &v1.ResourceFieldSelector{
						Resource: "limits.cpu",
					},
				},
			},
			{
				Name: "MEMORY_LIMIT",
				ValueFrom: &v1.EnvVarSource{
					ResourceFieldRef: &v1.ResourceFieldSelector{
						Resource: "limits.memory",
					},
				},
			},
			{
				Name: "CPU_REQUEST",
				ValueFrom: &v1.EnvVarSource{
					ResourceFieldRef: &v1.ResourceFieldSelector{
						Resource: "requests.cpu",
					},
				},
			},
			{
				Name: "MEMORY_REQUEST",
				ValueFrom: &v1.EnvVarSource{
					ResourceFieldRef: &v1.ResourceFieldSelector{
						Resource: "requests.memory",
					},
				},
			},
		}
		expectations := []string{
			fmt.Sprintf("CPU_LIMIT=2"),
			fmt.Sprintf("MEMORY_LIMIT=67108864"),
			fmt.Sprintf("CPU_REQUEST=1"),
			fmt.Sprintf("MEMORY_REQUEST=33554432"),
		}

		testDownwardAPI(f, podName, env, expectations)
	})

	It("should provide default limits.cpu/memory from node allocatable [Conformance]", func() {
		podName := "downward-api-" + string(uuid.NewUUID())
		env := []v1.EnvVar{
			{
				Name: "CPU_LIMIT",
				ValueFrom: &v1.EnvVarSource{
					ResourceFieldRef: &v1.ResourceFieldSelector{
						Resource: "limits.cpu",
					},
				},
			},
			{
				Name: "MEMORY_LIMIT",
				ValueFrom: &v1.EnvVarSource{
					ResourceFieldRef: &v1.ResourceFieldSelector{
						Resource: "limits.memory",
					},
				},
			},
		}
		expectations := []string{
			fmt.Sprintf("CPU_LIMIT=[1-9]"),
			fmt.Sprintf("MEMORY_LIMIT=[1-9]"),
		}
		pod := &v1.Pod{
			ObjectMeta: metav1.ObjectMeta{
				Name:   podName,
				Labels: map[string]string{"name": podName},
			},
			Spec: v1.PodSpec{
				Containers: []v1.Container{
					{
						Name:    "dapi-container",
						Image:   busyboxImage,
						Command: []string{"sh", "-c", "env"},
						Env:     env,
					},
				},
				RestartPolicy: v1.RestartPolicyNever,
			},
		}

		testDownwardAPIUsingPod(f, pod, env, expectations)
	})

	It("should provide pod UID as env vars [Conformance]", func() {
		framework.SkipUnlessServerVersionGTE(hostIPVersion, f.ClientSet.Discovery())
		podUID := uuid.NewUUID()
		podName := "downward-api-" + string(podUID)
		env := []v1.EnvVar{
			{
				Name: "POD_UID",
				ValueFrom: &v1.EnvVarSource{
					FieldRef: &v1.ObjectFieldSelector{
						APIVersion: "v1",
						FieldPath:  "metadata.uid",
					},
				},
			},
		}

		expectations := []string{
			fmt.Sprintf("POD_UID=%v", podUID),
		}

		testDownwardAPI(f, podName, env, expectations)
	})
})

func testDownwardAPI(f *framework.Framework, podName string, env []v1.EnvVar, expectations []string) {
	pod := &v1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Name:   podName,
			Labels: map[string]string{"name": podName},
		},
		Spec: v1.PodSpec{
			Containers: []v1.Container{
				{
					Name:    "dapi-container",
					Image:   busyboxImage,
					Command: []string{"sh", "-c", "env"},
					Resources: v1.ResourceRequirements{
						Requests: v1.ResourceList{
							v1.ResourceCPU:    resource.MustParse("250m"),
							v1.ResourceMemory: resource.MustParse("32Mi"),
						},
						Limits: v1.ResourceList{
							v1.ResourceCPU:    resource.MustParse("1250m"),
							v1.ResourceMemory: resource.MustParse("64Mi"),
						},
					},
					Env: env,
				},
			},
			RestartPolicy: v1.RestartPolicyNever,
		},
	}

	testDownwardAPIUsingPod(f, pod, env, expectations)
}

func testDownwardAPIUsingPod(f *framework.Framework, pod *v1.Pod, env []v1.EnvVar, expectations []string) {
	f.TestContainerOutputRegexp("downward api env vars", pod, 0, expectations)
}
<|endoftext|>


<commit_before>/*
Copyright 2015 The Kubernetes 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 e2e

import (
	"fmt"
	"path/filepath"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/v1"
	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
	"k8s.io/kubernetes/test/e2e/framework"

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

const (
	dnsReadyTimeout = time.Minute
)

const queryDnsPythonTemplate string = `
import socket
try:
	socket.gethostbyname('%s')
	print 'ok'
except:
	print 'err'`

var _ = framework.KubeDescribe("ClusterDns [Feature:Example]", func() {
	f := framework.NewDefaultFramework("cluster-dns")

	var c clientset.Interface
	BeforeEach(func() {
		c = f.ClientSet
	})

	It("should create pod that uses dns", func() {
		mkpath := func(file string) string {
			return filepath.Join(framework.TestContext.RepoRoot, "examples/cluster-dns", file)
		}

		// contrary to the example, this test does not use contexts, for simplicity
		// namespaces are passed directly.
		// Also, for simplicity, we don't use yamls with namespaces, but we
		// create testing namespaces instead.

		backendRcYaml := mkpath("dns-backend-rc.yaml")
		backendRcName := "dns-backend"
		backendSvcYaml := mkpath("dns-backend-service.yaml")
		backendSvcName := "dns-backend"
		backendPodName := "dns-backend"
		frontendPodYaml := mkpath("dns-frontend-pod.yaml")
		frontendPodName := "dns-frontend"
		frontendPodContainerName := "dns-frontend"

		podOutput := "Hello World!"

		// we need two namespaces anyway, so let's forget about
		// the one created in BeforeEach and create two new ones.
		namespaces := []*v1.Namespace{nil, nil}
		for i := range namespaces {
			var err error
			namespaces[i], err = f.CreateNamespace(fmt.Sprintf("dnsexample%d", i), nil)
			Expect(err).NotTo(HaveOccurred())
		}

		for _, ns := range namespaces {
			framework.RunKubectlOrDie("create", "-f", backendRcYaml, getNsCmdFlag(ns))
		}

		for _, ns := range namespaces {
			framework.RunKubectlOrDie("create", "-f", backendSvcYaml, getNsCmdFlag(ns))
		}

		// wait for objects
		for _, ns := range namespaces {
			framework.WaitForControlledPodsRunning(c, ns.Name, backendRcName, api.Kind("ReplicationController"))
			framework.WaitForService(c, ns.Name, backendSvcName, true, framework.Poll, framework.ServiceStartTimeout)
		}
		// it is not enough that pods are running because they may be set to running, but
		// the application itself may have not been initialized. Just query the application.
		for _, ns := range namespaces {
			label := labels.SelectorFromSet(labels.Set(map[string]string{"name": backendRcName}))
			options := metav1.ListOptions{LabelSelector: label.String()}
			pods, err := c.Core().Pods(ns.Name).List(options)
			Expect(err).NotTo(HaveOccurred())
			err = framework.PodsResponding(c, ns.Name, backendPodName, false, pods)
			Expect(err).NotTo(HaveOccurred(), "waiting for all pods to respond")
			framework.Logf("found %d backend pods responding in namespace %s", len(pods.Items), ns.Name)

			err = framework.ServiceResponding(c, ns.Name, backendSvcName)
			Expect(err).NotTo(HaveOccurred(), "waiting for the service to respond")
		}

		// Now another tricky part:
		// It may happen that the service name is not yet in DNS.
		// So if we start our pod, it will fail. We must make sure
		// the name is already resolvable. So let's try to query DNS from
		// the pod we have, until we find our service name.
		// This complicated code may be removed if the pod itself retried after
		// dns error or timeout.
		// This code is probably unnecessary, but let's stay on the safe side.
		label := labels.SelectorFromSet(labels.Set(map[string]string{"name": backendPodName}))
		options := metav1.ListOptions{LabelSelector: label.String()}
		pods, err := c.Core().Pods(namespaces[0].Name).List(options)

		if err != nil || pods == nil || len(pods.Items) == 0 {
			framework.Failf("no running pods found")
		}
		podName := pods.Items[0].Name

		queryDns := fmt.Sprintf(queryDnsPythonTemplate, backendSvcName+"."+namespaces[0].Name)
		_, err = framework.LookForStringInPodExec(namespaces[0].Name, podName, []string{"python", "-c", queryDns}, "ok", dnsReadyTimeout)
		Expect(err).NotTo(HaveOccurred(), "waiting for output from pod exec")

		updatedPodYaml := prepareResourceWithReplacedString(frontendPodYaml, "dns-backend.development.cluster.local", fmt.Sprintf("dns-backend.%s.svc.cluster.local", namespaces[0].Name))

		// create a pod in each namespace
		for _, ns := range namespaces {
			framework.NewKubectlCommand("create", "-f", "-", getNsCmdFlag(ns)).WithStdinData(updatedPodYaml).ExecOrDie()
		}

		// wait until the pods have been scheduler, i.e. are not Pending anymore. Remember
		// that we cannot wait for the pods to be running because our pods terminate by themselves.
		for _, ns := range namespaces {
			err := framework.WaitForPodNotPending(c, ns.Name, frontendPodName)
			framework.ExpectNoError(err)
		}

		// wait for pods to print their result
		for _, ns := range namespaces {
			_, err := framework.LookForStringInLog(ns.Name, frontendPodName, frontendPodContainerName, podOutput, framework.PodStartTimeout)
			Expect(err).NotTo(HaveOccurred())
		}
	})
})

func getNsCmdFlag(ns *v1.Namespace) string {
	return fmt.Sprintf("--namespace=%v", ns.Name)
}
<commit_msg>Fixed e2e test flake - ClusterDns [Feature:Example] should create pod that uses dns<commit_after>/*
Copyright 2015 The Kubernetes 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 e2e

import (
	"fmt"
	"path/filepath"
	"time"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/v1"
	"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
	"k8s.io/kubernetes/test/e2e/framework"

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

const (
	dnsReadyTimeout = time.Minute
)

const queryDnsPythonTemplate string = `
import socket
try:
	socket.gethostbyname('%s')
	print 'ok'
except:
	print 'err'`

var _ = framework.KubeDescribe("ClusterDns [Feature:Example]", func() {
	f := framework.NewDefaultFramework("cluster-dns")

	var c clientset.Interface
	BeforeEach(func() {
		c = f.ClientSet
	})

	It("should create pod that uses dns", func() {
		mkpath := func(file string) string {
			return filepath.Join(framework.TestContext.RepoRoot, "examples/cluster-dns", file)
		}

		// contrary to the example, this test does not use contexts, for simplicity
		// namespaces are passed directly.
		// Also, for simplicity, we don't use yamls with namespaces, but we
		// create testing namespaces instead.

		backendRcYaml := mkpath("dns-backend-rc.yaml")
		backendRcName := "dns-backend"
		backendSvcYaml := mkpath("dns-backend-service.yaml")
		backendSvcName := "dns-backend"
		backendPodName := "dns-backend"
		frontendPodYaml := mkpath("dns-frontend-pod.yaml")
		frontendPodName := "dns-frontend"
		frontendPodContainerName := "dns-frontend"

		podOutput := "Hello World!"

		// we need two namespaces anyway, so let's forget about
		// the one created in BeforeEach and create two new ones.
		namespaces := []*v1.Namespace{nil, nil}
		for i := range namespaces {
			var err error
			namespaces[i], err = f.CreateNamespace(fmt.Sprintf("dnsexample%d", i), nil)
			Expect(err).NotTo(HaveOccurred())
		}

		for _, ns := range namespaces {
			framework.RunKubectlOrDie("create", "-f", backendRcYaml, getNsCmdFlag(ns))
		}

		for _, ns := range namespaces {
			framework.RunKubectlOrDie("create", "-f", backendSvcYaml, getNsCmdFlag(ns))
		}

		// wait for objects
		for _, ns := range namespaces {
			framework.WaitForControlledPodsRunning(c, ns.Name, backendRcName, api.Kind("ReplicationController"))
			framework.WaitForService(c, ns.Name, backendSvcName, true, framework.Poll, framework.ServiceStartTimeout)
		}
		// it is not enough that pods are running because they may be set to running, but
		// the application itself may have not been initialized. Just query the application.
		for _, ns := range namespaces {
			label := labels.SelectorFromSet(labels.Set(map[string]string{"name": backendRcName}))
			options := metav1.ListOptions{LabelSelector: label.String()}
			pods, err := c.Core().Pods(ns.Name).List(options)
			Expect(err).NotTo(HaveOccurred())
			err = framework.PodsResponding(c, ns.Name, backendPodName, false, pods)
			Expect(err).NotTo(HaveOccurred(), "waiting for all pods to respond")
			framework.Logf("found %d backend pods responding in namespace %s", len(pods.Items), ns.Name)

			err = framework.ServiceResponding(c, ns.Name, backendSvcName)
			Expect(err).NotTo(HaveOccurred(), "waiting for the service to respond")
		}

		// Now another tricky part:
		// It may happen that the service name is not yet in DNS.
		// So if we start our pod, it will fail. We must make sure
		// the name is already resolvable. So let's try to query DNS from
		// the pod we have, until we find our service name.
		// This complicated code may be removed if the pod itself retried after
		// dns error or timeout.
		// This code is probably unnecessary, but let's stay on the safe side.
		label := labels.SelectorFromSet(labels.Set(map[string]string{"name": backendPodName}))
		options := metav1.ListOptions{LabelSelector: label.String()}
		pods, err := c.Core().Pods(namespaces[0].Name).List(options)

		if err != nil || pods == nil || len(pods.Items) == 0 {
			framework.Failf("no running pods found")
		}
		podName := pods.Items[0].Name

		queryDns := fmt.Sprintf(queryDnsPythonTemplate, backendSvcName+"."+namespaces[0].Name)
		_, err = framework.LookForStringInPodExec(namespaces[0].Name, podName, []string{"python", "-c", queryDns}, "ok", dnsReadyTimeout)
		Expect(err).NotTo(HaveOccurred(), "waiting for output from pod exec")

		updatedPodYaml := prepareResourceWithReplacedString(frontendPodYaml, "dns-backend.development.svc.cluster.local", fmt.Sprintf("dns-backend.%s.svc.cluster.local", namespaces[0].Name))

		// create a pod in each namespace
		for _, ns := range namespaces {
			framework.NewKubectlCommand("create", "-f", "-", getNsCmdFlag(ns)).WithStdinData(updatedPodYaml).ExecOrDie()
		}

		// wait until the pods have been scheduler, i.e. are not Pending anymore. Remember
		// that we cannot wait for the pods to be running because our pods terminate by themselves.
		for _, ns := range namespaces {
			err := framework.WaitForPodNotPending(c, ns.Name, frontendPodName)
			framework.ExpectNoError(err)
		}

		// wait for pods to print their result
		for _, ns := range namespaces {
			_, err := framework.LookForStringInLog(ns.Name, frontendPodName, frontendPodContainerName, podOutput, framework.PodStartTimeout)
			Expect(err).NotTo(HaveOccurred())
		}
	})
})

func getNsCmdFlag(ns *v1.Namespace) string {
	return fmt.Sprintf("--namespace=%v", ns.Name)
}
<|endoftext|>


<commit_before>// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see <http://www.gnu.org/licenses/>.

package twitter

import (
	"github.com/ChimeraCoder/anaconda"
	"github.com/nmeum/marvin/irc"
	"github.com/nmeum/marvin/modules"
	"html"
	"net/url"
	"strconv"
	"strings"
)

type Module struct {
	api               *anaconda.TwitterApi
	ReadOnly          bool   `json:"read_only"`
	ConsumerKey       string `json:"consumer_key"`
	ConsumerSecret    string `json:"consumer_secret"`
	AccessToken       string `json:"access_token"`
	AccessTokenSecret string `json:"access_token_secret"`
}

func Init(moduleSet *modules.ModuleSet) {
	moduleSet.Register(new(Module))
}

func (m *Module) Name() string {
	return "twitter"
}

func (m *Module) Help() string {
	return "USAGE: !tweet TEXT || !reply ID TEXT || !retweet ID || !favorite ID"
}

func (m *Module) Defaults() {
	m.ReadOnly = false
}

func (m *Module) Load(client *irc.Client) error {
	anaconda.SetConsumerKey(m.ConsumerKey)
	anaconda.SetConsumerSecret(m.ConsumerSecret)
	m.api = anaconda.NewTwitterApi(m.AccessToken, m.AccessTokenSecret)

	if !m.ReadOnly {
		client.CmdHook("privmsg", m.tweetCmd)
		client.CmdHook("privmsg", m.replyCmd)
		client.CmdHook("privmsg", m.retweetCmd)
		client.CmdHook("privmsg", m.favoriteCmd)
	}

	values := url.Values{}
	values.Add("replies", "all")
	values.Add("with", "user")

	stream := m.api.UserStream(values)
	go func(c *irc.Client, s anaconda.Stream) {
		for i := range s.C {
			t, ok := i.(anaconda.Tweet)
			if ok {
				m.notify(c, t)
			}
		}
	}(client, stream)

	return nil
}

func (m *Module) tweetCmd(client *irc.Client, msg irc.Message) error {
	splited := strings.Fields(msg.Data)
	if len(splited) < 2 || splited[0] != "!tweet" || !client.Connected(msg.Receiver) {
		return nil
	}

	status := strings.Join(splited[1:], " ")
	if _, err := m.api.PostTweet(status, url.Values{}); err != nil {
		return client.Write("NOTICE %s :ERROR: %s",
			msg.Receiver, err.Error())
	}

	return nil
}

func (m *Module) replyCmd(client *irc.Client, msg irc.Message) error {
	splited := strings.Fields(msg.Data)
	if len(splited) < 3 || splited[0] != "!reply" || !client.Connected(msg.Receiver) {
		return nil
	}

	values := url.Values{}
	values.Add("in_reply_to_status_id", splited[1])

	status := strings.Join(splited[2:], " ")
	if !strings.Contains(status, "@") {
		return client.Write("NOTICE %s :ERROR: %s",
			msg.Receiver, "A reply must contain a @mention")
	}

	if _, err := m.api.PostTweet(status, values); err != nil {
		return client.Write("NOTICE %s :ERROR: %s",
			msg.Receiver, err.Error())
	}

	return nil
}

func (m *Module) retweetCmd(client *irc.Client, msg irc.Message) error {
	splited := strings.Fields(msg.Data)
	if len(splited) < 2 || splited[0] != "!retweet" || !client.Connected(msg.Receiver) {
		return nil
	}

	id, err := strconv.Atoi(splited[1])
	if err != nil {
		return err
	}

	if _, err := m.api.Retweet(int64(id), false); err != nil {
		return client.Write("NOTICE %s :ERROR: %s",
			msg.Receiver, err.Error())
	}

	return nil
}

func (m *Module) favoriteCmd(client *irc.Client, msg irc.Message) error {
	splited := strings.Fields(msg.Data)
	if len(splited) < 2 || splited[0] != "!favorite" || !client.Connected(msg.Receiver) {
		return nil
	}

	id, err := strconv.Atoi(splited[1])
	if err != nil {
		return err
	}

	tweet, err := m.api.Favorite(int64(id))
	if err != nil {
		return client.Write("NOTICE %s :ERROR: %s",
			msg.Receiver, err.Error())
	}

	return client.Write("NOTICE %s :Favorited tweet %d by %s: %s",
		msg.Receiver, tweet.Id, tweet.User.ScreenName, m.sanitize(tweet.Text))
}

func (m *Module) notify(client *irc.Client, tweet anaconda.Tweet) {
	for _, ch := range client.Channels {
		client.Write("NOTICE %s :Tweet %d by %s: %s",
			ch, tweet.Id, tweet.User.ScreenName, m.sanitize(tweet.Text))
	}
}

func (m *Module) sanitize(text string) string {
	sanitized := html.UnescapeString(text)
	sanitized = strings.Replace(sanitized, "\n", " ", -1)
	return strings.TrimSpace(sanitized)
}
<commit_msg>twitter: rework stream handler<commit_after>// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public
// License along with this program. If not, see <http://www.gnu.org/licenses/>.

package twitter

import (
	"fmt"
	"github.com/ChimeraCoder/anaconda"
	"github.com/nmeum/marvin/irc"
	"github.com/nmeum/marvin/modules"
	"html"
	"net/url"
	"strconv"
	"strings"
)

type Module struct {
	api               *anaconda.TwitterApi
	ReadOnly          bool   `json:"read_only"`
	ConsumerKey       string `json:"consumer_key"`
	ConsumerSecret    string `json:"consumer_secret"`
	AccessToken       string `json:"access_token"`
	AccessTokenSecret string `json:"access_token_secret"`
}

func Init(moduleSet *modules.ModuleSet) {
	moduleSet.Register(new(Module))
}

func (m *Module) Name() string {
	return "twitter"
}

func (m *Module) Help() string {
	return "USAGE: !tweet TEXT || !reply ID TEXT || !retweet ID || !favorite ID"
}

func (m *Module) Defaults() {
	m.ReadOnly = false
}

func (m *Module) Load(client *irc.Client) error {
	anaconda.SetConsumerKey(m.ConsumerKey)
	anaconda.SetConsumerSecret(m.ConsumerSecret)
	m.api = anaconda.NewTwitterApi(m.AccessToken, m.AccessTokenSecret)

	if !m.ReadOnly {
		client.CmdHook("privmsg", m.tweetCmd)
		client.CmdHook("privmsg", m.replyCmd)
		client.CmdHook("privmsg", m.retweetCmd)
		client.CmdHook("privmsg", m.favoriteCmd)
	}

	values := url.Values{}
	values.Add("replies", "all")
	values.Add("with", "user")

	go func(client *irc.Client, values url.Values) {
		for {
			m.streamHandler(client, values)
		}
	}(client, values)

	return nil
}

func (m *Module) tweetCmd(client *irc.Client, msg irc.Message) error {
	splited := strings.Fields(msg.Data)
	if len(splited) < 2 || splited[0] != "!tweet" || !client.Connected(msg.Receiver) {
		return nil
	}

	status := strings.Join(splited[1:], " ")
	if _, err := m.api.PostTweet(status, url.Values{}); err != nil {
		return client.Write("NOTICE %s :ERROR: %s",
			msg.Receiver, err.Error())
	}

	return nil
}

func (m *Module) replyCmd(client *irc.Client, msg irc.Message) error {
	splited := strings.Fields(msg.Data)
	if len(splited) < 3 || splited[0] != "!reply" || !client.Connected(msg.Receiver) {
		return nil
	}

	values := url.Values{}
	values.Add("in_reply_to_status_id", splited[1])

	status := strings.Join(splited[2:], " ")
	if !strings.Contains(status, "@") {
		return client.Write("NOTICE %s :ERROR: %s",
			msg.Receiver, "A reply must contain a @mention")
	}

	if _, err := m.api.PostTweet(status, values); err != nil {
		return client.Write("NOTICE %s :ERROR: %s",
			msg.Receiver, err.Error())
	}

	return nil
}

func (m *Module) retweetCmd(client *irc.Client, msg irc.Message) error {
	splited := strings.Fields(msg.Data)
	if len(splited) < 2 || splited[0] != "!retweet" || !client.Connected(msg.Receiver) {
		return nil
	}

	id, err := strconv.Atoi(splited[1])
	if err != nil {
		return err
	}

	if _, err := m.api.Retweet(int64(id), false); err != nil {
		return client.Write("NOTICE %s :ERROR: %s",
			msg.Receiver, err.Error())
	}

	return nil
}

func (m *Module) favoriteCmd(client *irc.Client, msg irc.Message) error {
	splited := strings.Fields(msg.Data)
	if len(splited) < 2 || splited[0] != "!favorite" || !client.Connected(msg.Receiver) {
		return nil
	}

	id, err := strconv.Atoi(splited[1])
	if err != nil {
		return err
	}

	if _, err := m.api.Favorite(int64(id)); err != nil {
		return client.Write("NOTICE %s :ERROR: %s",
			msg.Receiver, err.Error())
	}

	return nil
}

func (m *Module) streamHandler(client *irc.Client, values url.Values) {
	stream := m.api.UserStream(values)
	for {
		var msg string
		select {
		case event := <-stream.C:
			msg = m.formatEvent(event)
		case <-stream.Quit:
			break
		}

		if len(msg) > 0 {
			m.notify(client, msg)
		}
	}
}

func (m *Module) formatEvent(event interface{}) string {
	var msg string
	switch t := event.(type) {
	case anaconda.ApiError:
		msg = fmt.Sprintf("API error %d: %s",
			t.StatusCode, t.Decoded.Error())
	case anaconda.Tweet:
		msg = fmt.Sprintf("Tweet %d by @%s: %s",
			t.Id, t.User.ScreenName, m.sanitize(t.Text))
	case anaconda.EventTweet:
		if t.Event.Event != "favorite" {
			break
		}

		msg = fmt.Sprintf("@%s favorited tweet %d: %s",
			t.Source.ScreenName, t.TargetObject.Id, m.sanitize(t.TargetObject.Text))
	case anaconda.StatusDeletionNotice:
		msg = fmt.Sprintf("Tweet %d has been deleted", t.Id)
	}

	return msg
}

func (m *Module) notify(client *irc.Client, text string) {
	for _, ch := range client.Channels {
		client.Write("NOTICE %s :%s -- %s",
			ch, strings.ToUpper(m.Name()), text)
	}
}

func (m *Module) sanitize(text string) string {
	sanitized := html.UnescapeString(text)
	sanitized = strings.Replace(sanitized, "\n", " ", -1)
	return strings.TrimSpace(sanitized)
}
<|endoftext|>


<commit_before>package assets

type Assets struct {
	AsyncServiceBroker       string
	Dora                     string
	DoraZip                  string
	Fuse                     string
	Golang                   string
	HelloWorld               string
	HelloRouting             string
	Java                     string
	JavaSpringZip            string
	JavaUnwriteableZip       string
	LoggregatorLoadGenerator string
	Python                   string
	Node                     string
	NodeWithProcfile         string
	Php                      string
	RubySimple               string
	SecurityGroupBuildpack   string
	ServiceBroker            string
	Staticfile               string
	SyslogDrainListener      string
	Binary                   string
	LoggingRouteService      string
	WorkerApp                string
	LatticeApp               string
}

func NewAssets() Assets {
	return Assets{
		AsyncServiceBroker:       "../assets/service_broker",
		Dora:                     "../assets/dora",
		DoraZip:                  "../assets/dora.zip",
		Fuse:                     "../assets/fuse-mount",
		Golang:                   "../assets/golang",
		HelloRouting:             "../assets/hello-routing",
		HelloWorld:               "../assets/hello-world",
		Java:                     "../assets/java",
		JavaSpringZip:            "../assets/java-spring/java-spring.jar",
		JavaUnwriteableZip:       "../assets/java-unwriteable-dir/java-unwriteable-dir.jar",
		LoggregatorLoadGenerator: "../assets/loggregator-load-generator",
		Node:                   "../assets/node",
		NodeWithProcfile:       "../assets/node-with-procfile",
		Php:                    "../assets/php",
		Python:                 "../assets/python",
		RubySimple:             "../assets/ruby_simple",
		SecurityGroupBuildpack: "../assets/security_group_buildpack.zip",
		ServiceBroker:          "../assets/service_broker",
		Staticfile:             "../assets/staticfile",
		SyslogDrainListener:    "../assets/syslog-drain-listener",
		Binary:                 "../assets/binary",
		LoggingRouteService:    "../assets/logging-route-service",
		WorkerApp:              "../assets/worker-app",
		LatticeApp:             "../assets/lattice-app",
	}
}
<commit_msg>Fix dir for assets<commit_after>package assets

type Assets struct {
	AsyncServiceBroker       string
	Dora                     string
	DoraZip                  string
	Fuse                     string
	Golang                   string
	HelloWorld               string
	HelloRouting             string
	Java                     string
	JavaSpringZip            string
	JavaUnwriteableZip       string
	LoggregatorLoadGenerator string
	Python                   string
	Node                     string
	NodeWithProcfile         string
	Php                      string
	RubySimple               string
	SecurityGroupBuildpack   string
	ServiceBroker            string
	Staticfile               string
	SyslogDrainListener      string
	Binary                   string
	LoggingRouteService      string
	WorkerApp                string
	LatticeApp               string
}

func NewAssets() Assets {
	return Assets{
		AsyncServiceBroker:       "assets/service_broker",
		Dora:                     "assets/dora",
		DoraZip:                  "assets/dora.zip",
		Fuse:                     "assets/fuse-mount",
		Golang:                   "assets/golang",
		HelloRouting:             "assets/hello-routing",
		HelloWorld:               "assets/hello-world",
		Java:                     "assets/java",
		JavaSpringZip:            "assets/java-spring/java-spring.jar",
		JavaUnwriteableZip:       "assets/java-unwriteable-dir/java-unwriteable-dir.jar",
		LoggregatorLoadGenerator: "assets/loggregator-load-generator",
		Node:                   "assets/node",
		NodeWithProcfile:       "assets/node-with-procfile",
		Php:                    "assets/php",
		Python:                 "assets/python",
		RubySimple:             "assets/ruby_simple",
		SecurityGroupBuildpack: "assets/security_group_buildpack.zip",
		ServiceBroker:          "assets/service_broker",
		Staticfile:             "assets/staticfile",
		SyslogDrainListener:    "assets/syslog-drain-listener",
		Binary:                 "assets/binary",
		LoggingRouteService:    "assets/logging-route-service",
		WorkerApp:              "assets/worker-app",
		LatticeApp:             "assets/lattice-app",
	}
}
<|endoftext|>


<commit_before>package main

import (
    "os"
    "bufio"
    "fmt"
    "io"
    "math"
    "regexp"
    "sort"
    "strconv"
    "strings"
)

const (
   // for Nginx($request_time)
   SCALE = 0
   EFFECTIVE_DIGIT = 3
   // for Apache(%D)
   // SCALE = -6
   // EFFECTIVE_DIGIT = 6
)

type Measure struct {
  Url string
  Count int
  Total float64
  Min float64
  Mean float64
  Median float64
  P90 float64
  Max float64
}

type By func(a, b *Measure) bool

func (by By) Sort(measures []*Measure) {
  ms := &measureSorter{
    measures: measures,
    by: by,
  }
  sort.Sort(ms)
}

type measureSorter struct {
  measures []*Measure
  by func(a, b *Measure) bool
}

func (s *measureSorter) Len() int {
  return len(s.measures)
}

func (s *measureSorter) Swap(i, j int) {
  s.measures[i], s.measures[j] = s.measures[j], s.measures[i]
}

func (s *measureSorter) Less(i, j int) bool {
  return s.by(s.measures[i], s.measures[j])
}

type Column struct {
  Name string
  Summary string
  Sort By
}

var (
    totals = make(map[string]float64)
    times = make(map[string][]float64)
    measures []*Measure
    topCount = 10
    columns = []*Column{
      &Column{ Name: "Count", Summary: "Count", Sort: func(a, b *Measure) bool { return a.Count > b.Count } },
      &Column{ Name: "Total", Summary: "Total", Sort: func(a, b *Measure) bool { return a.Total > b.Total } },
      &Column{ Name: "Mean", Summary: "Mean", Sort: func(a, b *Measure) bool { return a.Mean > b.Mean } },
      &Column{ Name: "Min", Summary: "Minimum(0 Percentile)", Sort: func(a, b *Measure) bool { return a.Min > b.Min } },
      &Column{ Name: "Median", Summary: "Median(50 Percentile)", Sort: func(a, b *Measure) bool { return a.Median > b.Median } },
      &Column{ Name: "P90", Summary: "90 Percentile", Sort: func(a, b *Measure) bool { return a.P90 > b.P90 } },
      &Column{ Name: "Max", Summary: "Maximum(100 Percentile)", Sort: func(a, b *Measure) bool { return a.Max > b.Max } },
    }
)

func showMeasures(measures []*Measure) {
  countWidth := 5 // for title
  totalWidth := 2 + EFFECTIVE_DIGIT
  meanWidth := 2 + EFFECTIVE_DIGIT * 2
  maxWidth := 2 + EFFECTIVE_DIGIT

  for i := 0; i < topCount; i++ {
    if countWidth < int(math.Log10(float64(measures[i].Count)) + 1) {
      countWidth = int(math.Log10(float64(measures[i].Count)) + 1)
    }
    if totalWidth < int(math.Log10(measures[i].Total) + 1 + EFFECTIVE_DIGIT + 1) {
      totalWidth = int(math.Log10(measures[i].Total) + 1 + EFFECTIVE_DIGIT + 1)
    }
    if meanWidth < int(math.Log10(measures[i].Max) + 1 + EFFECTIVE_DIGIT * 2 + 1) {
      meanWidth = int(math.Log10(measures[i].Max) + 1 + EFFECTIVE_DIGIT * 2 + 1)
    }
    if maxWidth < int(math.Log10(measures[i].Max) + 1 + EFFECTIVE_DIGIT + 1) {
      maxWidth = int(math.Log10(measures[i].Max) + 1 + EFFECTIVE_DIGIT + 1)
    }
  }

  var format string
  for _, column := range columns {
    switch column.Name {
    case "Count":
      fmt.Printf(fmt.Sprintf("%%%ds  ", countWidth), column.Name)
      format += fmt.Sprintf("%%%dd  ", countWidth)
    case "Total":
      fmt.Printf(fmt.Sprintf("%%%ds  ", totalWidth), column.Name)
      format += fmt.Sprintf("%%%d.%df  ", totalWidth, EFFECTIVE_DIGIT)
    case "Mean":
      fmt.Printf(fmt.Sprintf("%%%ds  ", meanWidth), column.Name)
      format += fmt.Sprintf("%%%d.%df  ", meanWidth, EFFECTIVE_DIGIT * 2)
    default:
      fmt.Printf(fmt.Sprintf("%%%ds  ", maxWidth), column.Name)
      format += fmt.Sprintf("%%%d.%df  ", maxWidth, EFFECTIVE_DIGIT)
    }
  }
  fmt.Printf("url\n")
  format += "%s\n"

  for i := 0; i < topCount; i++ {
    m := measures[i]
    fmt.Printf(format, m.Count, m.Total, m.Mean, m.Min, m.Median, m.P90, m.Max, m.Url)
  }
}

func main() {
    reader := bufio.NewReaderSize(os.Stdin, 4096)
    delimiter := regexp.MustCompile(" +")
    scale := math.Pow10(SCALE)
    for {
        line, err := reader.ReadString('\n')
        if err == io.EOF {
          break
        } else if err != nil {
          panic(err)
        }
        s := delimiter.Split(line, -1)
        if len(s) > 0 {
          var url string
          if len(s) >= 7 {
            url = strings.TrimLeft(strings.Join(s[5:7], " "), "\"")
          }
          time, err := strconv.ParseFloat(strings.Trim(s[len(s)-1], "\r\n"), 10)
          if err == nil {
            time = time * scale
          } else {
            time = 0.000
          }
          totals[url] += time
          times[url] = append(times[url], time)
        }
    }

    for url, total := range totals {
      sorted := times[url]
      sort.Float64s(sorted)
      count := len(sorted)
      measure := &Measure{
        Url: url,
        Count: count,
        Total: total,
        Min: sorted[0],
        Mean: totals[url]/float64(count),
        Median: sorted[int(count*50/100)],
        P90: sorted[int(count*90/100)],
        Max: sorted[count-1],
      }
      measures = append(measures, measure)
    }
    if len(measures) < topCount {
      topCount = len(measures)
    }

    for _, column := range columns {
      fmt.Printf("Sort By %s\n", column.Summary)
      By(column.Sort).Sort(measures)
      showMeasures(measures)
      fmt.Println()
    }
}
<commit_msg>正規表現でURLをまとめられるように<commit_after>package main

import (
    "os"
    "bufio"
    "fmt"
    "io"
    "math"
    "regexp"
    "sort"
    "strconv"
    "strings"
)

const (
   // for Nginx($request_time)
   SCALE = 0
   EFFECTIVE_DIGIT = 3
   // for Apache(%D)
   // SCALE = -6
   // EFFECTIVE_DIGIT = 6
)

var (
    topCount = 10
    urlNormalizes = []string{
      "^GET /memo/[0-9]+$",
      "^GET /stylesheets/",
      "^GET /images/",
    }
)

type Measure struct {
  Url string
  Count int
  Total float64
  Min float64
  Mean float64
  Median float64
  P90 float64
  Max float64
}

type By func(a, b *Measure) bool

func (by By) Sort(measures []*Measure) {
  ms := &measureSorter{
    measures: measures,
    by: by,
  }
  sort.Sort(ms)
}

type measureSorter struct {
  measures []*Measure
  by func(a, b *Measure) bool
}

func (s *measureSorter) Len() int {
  return len(s.measures)
}

func (s *measureSorter) Swap(i, j int) {
  s.measures[i], s.measures[j] = s.measures[j], s.measures[i]
}

func (s *measureSorter) Less(i, j int) bool {
  return s.by(s.measures[i], s.measures[j])
}

type Column struct {
  Name string
  Summary string
  Sort By
}

var (
    totals = make(map[string]float64)
    times = make(map[string][]float64)
    measures []*Measure
    columns = []*Column{
      &Column{ Name: "Count", Summary: "Count", Sort: func(a, b *Measure) bool { return a.Count > b.Count } },
      &Column{ Name: "Total", Summary: "Total", Sort: func(a, b *Measure) bool { return a.Total > b.Total } },
      &Column{ Name: "Mean", Summary: "Mean", Sort: func(a, b *Measure) bool { return a.Mean > b.Mean } },
      &Column{ Name: "Min", Summary: "Minimum(0 Percentile)", Sort: func(a, b *Measure) bool { return a.Min > b.Min } },
      &Column{ Name: "Median", Summary: "Median(50 Percentile)", Sort: func(a, b *Measure) bool { return a.Median > b.Median } },
      &Column{ Name: "P90", Summary: "90 Percentile", Sort: func(a, b *Measure) bool { return a.P90 > b.P90 } },
      &Column{ Name: "Max", Summary: "Maximum(100 Percentile)", Sort: func(a, b *Measure) bool { return a.Max > b.Max } },
    }
)

func showMeasures(measures []*Measure) {
  countWidth := 5 // for title
  totalWidth := 2 + EFFECTIVE_DIGIT
  meanWidth := 2 + EFFECTIVE_DIGIT * 2
  maxWidth := 2 + EFFECTIVE_DIGIT

  for i := 0; i < topCount; i++ {
    if countWidth < int(math.Log10(float64(measures[i].Count)) + 1) {
      countWidth = int(math.Log10(float64(measures[i].Count)) + 1)
    }
    if totalWidth < int(math.Log10(measures[i].Total) + 1 + EFFECTIVE_DIGIT + 1) {
      totalWidth = int(math.Log10(measures[i].Total) + 1 + EFFECTIVE_DIGIT + 1)
    }
    if meanWidth < int(math.Log10(measures[i].Max) + 1 + EFFECTIVE_DIGIT * 2 + 1) {
      meanWidth = int(math.Log10(measures[i].Max) + 1 + EFFECTIVE_DIGIT * 2 + 1)
    }
    if maxWidth < int(math.Log10(measures[i].Max) + 1 + EFFECTIVE_DIGIT + 1) {
      maxWidth = int(math.Log10(measures[i].Max) + 1 + EFFECTIVE_DIGIT + 1)
    }
  }

  var format string
  for _, column := range columns {
    switch column.Name {
    case "Count":
      fmt.Printf(fmt.Sprintf("%%%ds  ", countWidth), column.Name)
      format += fmt.Sprintf("%%%dd  ", countWidth)
    case "Total":
      fmt.Printf(fmt.Sprintf("%%%ds  ", totalWidth), column.Name)
      format += fmt.Sprintf("%%%d.%df  ", totalWidth, EFFECTIVE_DIGIT)
    case "Mean":
      fmt.Printf(fmt.Sprintf("%%%ds  ", meanWidth), column.Name)
      format += fmt.Sprintf("%%%d.%df  ", meanWidth, EFFECTIVE_DIGIT * 2)
    default:
      fmt.Printf(fmt.Sprintf("%%%ds  ", maxWidth), column.Name)
      format += fmt.Sprintf("%%%d.%df  ", maxWidth, EFFECTIVE_DIGIT)
    }
  }
  fmt.Printf("url\n")
  format += "%s\n"

  for i := 0; i < topCount; i++ {
    m := measures[i]
    fmt.Printf(format, m.Count, m.Total, m.Mean, m.Min, m.Median, m.P90, m.Max, m.Url)
  }
}

func main() {
    reader := bufio.NewReaderSize(os.Stdin, 4096)
    delimiter := regexp.MustCompile(" +")
    scale := math.Pow10(SCALE)

    var urlNormalizeRegexps []*regexp.Regexp
    for _, str := range urlNormalizes {
	re := regexp.MustCompile(str)
        urlNormalizeRegexps = append(urlNormalizeRegexps, re)
    }

    for {
        line, err := reader.ReadString('\n')
        if err == io.EOF {
          break
        } else if err != nil {
          panic(err)
        }
        s := delimiter.Split(line, -1)
        if len(s) >= 7 {
          url := strings.TrimLeft(strings.Join(s[5:7], " "), "\"")
          for _, re := range urlNormalizeRegexps {
            if re.MatchString(url) {
              url = re.String()
            }
          }
          time, err := strconv.ParseFloat(strings.Trim(s[len(s)-1], "\r\n"), 10)
          if err == nil {
            time = time * scale
          } else {
            time = 0.000
          }
          totals[url] += time
          times[url] = append(times[url], time)
        }
    }

    for url, total := range totals {
      sorted := times[url]
      sort.Float64s(sorted)
      count := len(sorted)
      measure := &Measure{
        Url: url,
        Count: count,
        Total: total,
        Min: sorted[0],
        Mean: totals[url]/float64(count),
        Median: sorted[int(count*50/100)],
        P90: sorted[int(count*90/100)],
        Max: sorted[count-1],
      }
      measures = append(measures, measure)
    }
    if len(measures) < topCount {
      topCount = len(measures)
    }

    for _, column := range columns {
      fmt.Printf("Sort By %s\n", column.Summary)
      By(column.Sort).Sort(measures)
      showMeasures(measures)
      fmt.Println()
    }
}
<|endoftext|>


<commit_before>package goinwx

import (
	"errors"

	"time"

	"github.com/fatih/structs"
	"github.com/mitchellh/mapstructure"
	"fmt"
)

const (
	methodNameserverCheck        = "nameserver.check"
	methodNameserverCreate       = "nameserver.create"
	methodNameserverCreateRecord = "nameserver.createRecord"
	methodNameserverDelete       = "nameserver.delete"
	methodNameserverDeleteRecord = "nameserver.deleteRecord"
	methodNameserverInfo         = "nameserver.info"
	methodNameserverList         = "nameserver.list"
	methodNameserverUpdate       = "nameserver.update"
	methodNameserverUpdateRecord = "nameserver.updateRecord"
)

type NameserverService interface {
	Check(domain string, nameservers []string) (*NameserverCheckResponse, error)
	Info(domain string, domainId int) (*NamserverInfoResponse, error)
	List(domain string) (*NamserverListResponse, error)
	CreateRecord(*NameserverRecordRequest) (int, error)
	UpdateRecord(recId int, request *NameserverRecordRequest) error
	DeleteRecord(recId int) error
	FindRecordById(recId int) (*NameserverRecord, *NameserverDomain, error)
}

type NameserverServiceOp struct {
	client *Client
}

var _ NameserverService = &NameserverServiceOp{}

type NameserverCheckResponse struct {
	Details []string
	Status  string
}

type NameserverRecordRequest struct {
	RoId                   int    `structs:"roId,omitempty"`
	Domain                 string `structs:"domain,omitempty"`
	Type                   string `structs:"type"`
	Content                string `structs:"content"`
	Name                   string `structs:"name,omitempty"`
	Ttl                    int    `structs:"ttl,omitempty"`
	Priority               int    `structs:"prio,omitempty"`
	UrlRedirectType        string `structs:"urlRedirectType,omitempty"`
	UrlRedirectTitle       string `structs:"urlRedirectTitle,omitempty"`
	UrlRedirectDescription string `structs:"urlRedirectDescription,omitempty"`
	UrlRedirectFavIcon     string `structs:"urlRedirectFavIcon,omitempty"`
	UrlRedirectKeywords    string `structs:"urlRedirectKeywords,omitempty"`
}

type NamserverInfoResponse struct {
	RoId          int
	Domain        string
	Type          string
	MasterIp      string
	LastZoneCheck time.Time
	SlaveDns      interface{}
	SOAserial     string
	Count         int
	Records       []NameserverRecord `mapstructure:"record"`
}

type NameserverRecord struct {
	Id                     int
	Name                   string
	Type                   string
	Content                string
	Ttl                    int
	Prio                   int
	UrlRedirectType        string
	UrlRedirectTitle       string
	UrlRedirectDescription string
	UrlRedirectKeywords    string
	UrlRedirectFavIcon     string
}

type NamserverListResponse struct {
	Count   int
	Domains []NameserverDomain `mapstructure:"domains"`
}

type NameserverDomain struct {
	RoId     int    `mapstructure:"roId"`
	Domain   string `mapstructure:"domain"`
	Type     string `mapstructure:"type"`
	MasterIp string `mapstructure:"masterIp"`
	Mail     string `mapstructure:"mail"`
	Web      string `mapstructure:"web"`
	Url      string `mapstructure:"url"`
	Ipv4     string `mapstructure:"ipv4"`
	Ipv6     string `mapstructure:"ipv6"`
}

func (s *NameserverServiceOp) Check(domain string, nameservers []string) (*NameserverCheckResponse, error) {
	req := s.client.NewRequest(methodNameserverCheck, map[string]interface{}{
		"domain": domain,
		"ns":     nameservers,
	})

	resp, err := s.client.Do(*req)
	if err != nil {
		return nil, err
	}

	var result NameserverCheckResponse
	err = mapstructure.Decode(*resp, &result)
	if err != nil {
		return nil, err
	}

	return &result, nil
}

func (s *NameserverServiceOp) Info(domain string, domainId int) (*NamserverInfoResponse, error) {
	var requestMap = make(map[string]interface{})

	if domain != "" {
		requestMap["domain"] = domain
	}
	if domainId != 0 {
		requestMap["roId"] = domainId
	}
	req := s.client.NewRequest(methodNameserverInfo, requestMap)

	resp, err := s.client.Do(*req)
	if err != nil {
		return nil, err
	}
	var result NamserverInfoResponse
	err = mapstructure.Decode(*resp, &result)
	if err != nil {
		return nil, err
	}

	return &result, nil
}

func (s *NameserverServiceOp) List(domain string) (*NamserverListResponse, error) {
	requestMap := map[string]interface{}{
		"domain": "*",
		"wide": 2,
	}
	if domain != "" {
		requestMap["domain"] = domain
	}
	req := s.client.NewRequest(methodNameserverList, requestMap)

	resp, err := s.client.Do(*req)
	if err != nil {
		return nil, err
	}
	var result NamserverListResponse
	err = mapstructure.Decode(*resp, &result)
	if err != nil {
		return nil, err
	}

	return &result, nil
}

func (s *NameserverServiceOp) CreateRecord(request *NameserverRecordRequest) (int, error) {
	req := s.client.NewRequest(methodNameserverCreateRecord, structs.Map(request))

	//fmt.Println("Args", req.Args)
	resp, err := s.client.Do(*req)
	if err != nil {
		return 0, err
	}

	var result map[string]int
	err = mapstructure.Decode(*resp, &result)
	if err != nil {
		return 0, err
	}

	return result["id"], nil
}

func (s *NameserverServiceOp) UpdateRecord(recId int, request *NameserverRecordRequest) error {
	if request == nil {
		return errors.New("Request can't be nil")
	}
	requestMap := structs.Map(request)
	requestMap["id"] = recId

	req := s.client.NewRequest(methodNameserverUpdateRecord, requestMap)

	_, err := s.client.Do(*req)
	if err != nil {
		return err
	}

	return nil
}

func (s *NameserverServiceOp) DeleteRecord(recId int) error {
	req := s.client.NewRequest(methodNameserverDeleteRecord, map[string]interface{}{
		"id": recId,
	})

	_, err := s.client.Do(*req)
	if err != nil {
		return err
	}

	return nil
}

func (s *NameserverServiceOp) FindRecordById(recId int) (*NameserverRecord, *NameserverDomain, error) {
	var domain *NameserverDomain
	var rec *NameserverRecord

	listResp, err := s.client.Nameservers.List("")
	if err != nil {
		return nil, nil, err
	}

	for _, domainItem := range listResp.Domains {
		resp, err := s.client.Nameservers.Info("", domainItem.RoId)
		if err != nil {
			return nil, nil, err
		}

		for _, record := range resp.Records {
			if record.Id == recId {
				rec = &record
				domain = &domainItem
				return rec, domain, nil
			}
		}
	}
	return nil, nil, errors.New(fmt.Sprintf("Couldn't find INWX Record for id %d", recId))

}
<commit_msg>added NameserverCreate Request in nameserver<commit_after>package goinwx

import (
	"errors"

	"time"

	"fmt"

	"github.com/fatih/structs"
	"github.com/mitchellh/mapstructure"
)

const (
	methodNameserverCheck        = "nameserver.check"
	methodNameserverCreate       = "nameserver.create"
	methodNameserverCreateRecord = "nameserver.createRecord"
	methodNameserverDelete       = "nameserver.delete"
	methodNameserverDeleteRecord = "nameserver.deleteRecord"
	methodNameserverInfo         = "nameserver.info"
	methodNameserverList         = "nameserver.list"
	methodNameserverUpdate       = "nameserver.update"
	methodNameserverUpdateRecord = "nameserver.updateRecord"
)

type NameserverService interface {
	Check(domain string, nameservers []string) (*NameserverCheckResponse, error)
	Create(*NameserverCreateRequest) (int, error)
	Info(domain string, domainId int) (*NamserverInfoResponse, error)
	List(domain string) (*NamserverListResponse, error)
	CreateRecord(*NameserverRecordRequest) (int, error)
	UpdateRecord(recId int, request *NameserverRecordRequest) error
	DeleteRecord(recId int) error
	FindRecordById(recId int) (*NameserverRecord, *NameserverDomain, error)
}

type NameserverServiceOp struct {
	client *Client
}

var _ NameserverService = &NameserverServiceOp{}

type NameserverCheckResponse struct {
	Details []string
	Status  string
}

type NameserverRecordRequest struct {
	RoId                   int    `structs:"roId,omitempty"`
	Domain                 string `structs:"domain,omitempty"`
	Type                   string `structs:"type"`
	Content                string `structs:"content"`
	Name                   string `structs:"name,omitempty"`
	Ttl                    int    `structs:"ttl,omitempty"`
	Priority               int    `structs:"prio,omitempty"`
	UrlRedirectType        string `structs:"urlRedirectType,omitempty"`
	UrlRedirectTitle       string `structs:"urlRedirectTitle,omitempty"`
	UrlRedirectDescription string `structs:"urlRedirectDescription,omitempty"`
	UrlRedirectFavIcon     string `structs:"urlRedirectFavIcon,omitempty"`
	UrlRedirectKeywords    string `structs:"urlRedirectKeywords,omitempty"`
}

type NameserverCreateRequest struct {
	Domain                 string   `structs:"domain"`
	Type                   string   `structs:"type"`
	Nameservers            []string `structs:"ns,omitempty"`
	MasterIp               string   `structs:"masterIp,omitempty"`
	Web                    string   `structs:"web,omitempty"`
	Mail                   string   `structs:"mail,omitempty"`
	SoaEmail               string   `structs:"soaEmail,omitempty"`
	UrlRedirectType        string   `structs:"urlRedirectType,omitempty"`
	UrlRedirectTitle       string   `structs:"urlRedirectTitle,omitempty"`
	UrlRedirectDescription string   `structs:"urlRedirectDescription,omitempty"`
	UrlRedirectFavIcon     string   `structs:"urlRedirectFavIcon,omitempty"`
	UrlRedirectKeywords    string   `structs:"urlRedirectKeywords,omitempty"`
	Testing                bool     `structs:"testing,omitempty"`
}

type NamserverInfoResponse struct {
	RoId          int
	Domain        string
	Type          string
	MasterIp      string
	LastZoneCheck time.Time
	SlaveDns      interface{}
	SOAserial     string
	Count         int
	Records       []NameserverRecord `mapstructure:"record"`
}

type NameserverRecord struct {
	Id                     int
	Name                   string
	Type                   string
	Content                string
	Ttl                    int
	Prio                   int
	UrlRedirectType        string
	UrlRedirectTitle       string
	UrlRedirectDescription string
	UrlRedirectKeywords    string
	UrlRedirectFavIcon     string
}

type NamserverListResponse struct {
	Count   int
	Domains []NameserverDomain `mapstructure:"domains"`
}

type NameserverDomain struct {
	RoId     int    `mapstructure:"roId"`
	Domain   string `mapstructure:"domain"`
	Type     string `mapstructure:"type"`
	MasterIp string `mapstructure:"masterIp"`
	Mail     string `mapstructure:"mail"`
	Web      string `mapstructure:"web"`
	Url      string `mapstructure:"url"`
	Ipv4     string `mapstructure:"ipv4"`
	Ipv6     string `mapstructure:"ipv6"`
}

func (s *NameserverServiceOp) Check(domain string, nameservers []string) (*NameserverCheckResponse, error) {
	req := s.client.NewRequest(methodNameserverCheck, map[string]interface{}{
		"domain": domain,
		"ns":     nameservers,
	})

	resp, err := s.client.Do(*req)
	if err != nil {
		return nil, err
	}

	var result NameserverCheckResponse
	err = mapstructure.Decode(*resp, &result)
	if err != nil {
		return nil, err
	}

	return &result, nil
}

func (s *NameserverServiceOp) Info(domain string, domainId int) (*NamserverInfoResponse, error) {
	var requestMap = make(map[string]interface{})

	if domain != "" {
		requestMap["domain"] = domain
	}
	if domainId != 0 {
		requestMap["roId"] = domainId
	}
	req := s.client.NewRequest(methodNameserverInfo, requestMap)

	resp, err := s.client.Do(*req)
	if err != nil {
		return nil, err
	}
	var result NamserverInfoResponse
	err = mapstructure.Decode(*resp, &result)
	if err != nil {
		return nil, err
	}

	return &result, nil
}

func (s *NameserverServiceOp) List(domain string) (*NamserverListResponse, error) {
	requestMap := map[string]interface{}{
		"domain": "*",
		"wide":   2,
	}
	if domain != "" {
		requestMap["domain"] = domain
	}
	req := s.client.NewRequest(methodNameserverList, requestMap)

	resp, err := s.client.Do(*req)
	if err != nil {
		return nil, err
	}
	var result NamserverListResponse
	err = mapstructure.Decode(*resp, &result)
	if err != nil {
		return nil, err
	}

	return &result, nil
}

func (s *NameserverServiceOp) Create(request *NameserverCreateRequest) (int, error) {
	req := s.client.NewRequest(methodNameserverCreate, structs.Map(request))

	resp, err := s.client.Do(*req)
	if err != nil {
		return 0, err
	}

	var result map[string]int
	err = mapstructure.Decode(*resp, &result)
	if err != nil {
		return 0, err
	}

	return result["roId"], nil
}

func (s *NameserverServiceOp) CreateRecord(request *NameserverRecordRequest) (int, error) {
	req := s.client.NewRequest(methodNameserverCreateRecord, structs.Map(request))

	//fmt.Println("Args", req.Args)
	resp, err := s.client.Do(*req)
	if err != nil {
		return 0, err
	}

	var result map[string]int
	err = mapstructure.Decode(*resp, &result)
	if err != nil {
		return 0, err
	}

	return result["id"], nil
}

func (s *NameserverServiceOp) UpdateRecord(recId int, request *NameserverRecordRequest) error {
	if request == nil {
		return errors.New("Request can't be nil")
	}
	requestMap := structs.Map(request)
	requestMap["id"] = recId

	req := s.client.NewRequest(methodNameserverUpdateRecord, requestMap)

	_, err := s.client.Do(*req)
	if err != nil {
		return err
	}

	return nil
}

func (s *NameserverServiceOp) DeleteRecord(recId int) error {
	req := s.client.NewRequest(methodNameserverDeleteRecord, map[string]interface{}{
		"id": recId,
	})

	_, err := s.client.Do(*req)
	if err != nil {
		return err
	}

	return nil
}

func (s *NameserverServiceOp) FindRecordById(recId int) (*NameserverRecord, *NameserverDomain, error) {
	var domain *NameserverDomain
	var rec *NameserverRecord

	listResp, err := s.client.Nameservers.List("")
	if err != nil {
		return nil, nil, err
	}

	for _, domainItem := range listResp.Domains {
		resp, err := s.client.Nameservers.Info("", domainItem.RoId)
		if err != nil {
			return nil, nil, err
		}

		for _, record := range resp.Records {
			if record.Id == recId {
				rec = &record
				domain = &domainItem
				return rec, domain, nil
			}
		}
	}
	return nil, nil, errors.New(fmt.Sprintf("Couldn't find INWX Record for id %d", recId))

}
<|endoftext|>


<commit_before>package grayt

import (
	"image"
	"math/rand"
	"sync/atomic"
	"time"
)

type strategy struct {
}

func (s *strategy) traceImage(pxHigh, pxWide int, scene Scene, quality int) image.Image {

	acc := newAccumulator(pxHigh, pxWide)

	var completed uint64 // MUST only be used atomically.

	cli := newCLI()
	done := make(chan struct{})
	go func() {
		total := uint64(pxWide * pxHigh * quality)
		for {
			select {
			case <-done:
				cli.update(atomic.LoadUint64(&completed), total)
				cli.done()
				done <- struct{}{}
				return
			case <-time.After(100 * time.Millisecond):
				cli.update(atomic.LoadUint64(&completed), total)
			}
		}
	}()

	w := newWorld(scene.Entities)
	pxPitch := 2.0 / float64(pxWide)
	for i := 0; i < quality; i++ {
		for pxX := 0; pxX < pxWide; pxX++ {
			for pxY := 0; pxY < pxHigh; pxY++ {
				x := (float64(pxX-pxWide/2) + rand.Float64()) * pxPitch
				y := (float64(pxY-pxHigh/2) + rand.Float64()) * pxPitch * -1.0
				r := scene.Camera.MakeRay(x, y)
				r.Dir = r.Dir.Unit()
				acc.add(pxX, pxY, tracePath(w, r))
				atomic.AddUint64(&completed, 1)
			}
		}
	}
	done <- struct{}{}
	<-done

	return acc.toImage(1.0)
}

// TODO: Also output some kind of meta file about the image that was generated?
<commit_msg>Refactor UI update loop<commit_after>package grayt

import (
	"image"
	"math/rand"
	"sync/atomic"
	"time"
)

type strategy struct {
}

func (s *strategy) traceImage(pxHigh, pxWide int, scene Scene, quality int) image.Image {

	acc := newAccumulator(pxHigh, pxWide)

	var completed uint64 // MUST only be used atomically.

	cli := newCLI()
	done := make(chan struct{})
	go func() {
		total := uint64(pxWide * pxHigh * quality)
		for {
			var exit bool
			select {
			case <-done:
				exit = true
			case <-time.After(100 * time.Millisecond):
			}
			cli.update(atomic.LoadUint64(&completed), total)
			if exit {
				cli.done()
				done <- struct{}{}
				return
			}
		}
	}()

	w := newWorld(scene.Entities)
	pxPitch := 2.0 / float64(pxWide)
	for i := 0; i < quality; i++ {
		for pxX := 0; pxX < pxWide; pxX++ {
			for pxY := 0; pxY < pxHigh; pxY++ {
				x := (float64(pxX-pxWide/2) + rand.Float64()) * pxPitch
				y := (float64(pxY-pxHigh/2) + rand.Float64()) * pxPitch * -1.0
				r := scene.Camera.MakeRay(x, y)
				r.Dir = r.Dir.Unit()
				acc.add(pxX, pxY, tracePath(w, r))
				atomic.AddUint64(&completed, 1)
			}
		}
	}
	done <- struct{}{}
	<-done

	return acc.toImage(1.0)
}

// TODO: Also output some kind of meta file about the image that was generated?
<|endoftext|>


<commit_before>// +build gen

//go:generate glow generate -out=./v2.1/gl/ -api=gl -version=2.1 -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./all-core/gl/ -api=gl -version=all -profile=core -lenientInit -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v3.2-core/gl/ -api=gl -version=3.2 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v3.3-core/gl/ -api=gl -version=3.3 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.1-core/gl/ -api=gl -version=4.1 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.2-core/gl/ -api=gl -version=4.2 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.3-core/gl/ -api=gl -version=4.3 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.4-core/gl/ -api=gl -version=4.4 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.5-core/gl/ -api=gl -version=4.5 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.6-core/gl/ -api=gl -version=4.6 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v3.2-compatibility/gl/ -api=gl -version=3.2 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v3.3-compatibility/gl/ -api=gl -version=3.3 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.1-compatibility/gl/ -api=gl -version=4.1 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.2-compatibility/gl/ -api=gl -version=4.2 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.3-compatibility/gl/ -api=gl -version=4.3 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.4-compatibility/gl/ -api=gl -version=4.4 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.5-compatibility/gl/ -api=gl -version=4.5 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.6-compatibility/gl/ -api=gl -version=4.6 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v3.1/gles2/ -api=gles2 -version=3.1 -xml=../glow/xml/ -tmpl=../glow/tmpl/

// This is an empty pseudo-package with the sole purpose of containing go generate directives
// that generate all gl binding packages inside this repository.
package gl
<commit_msg>generate gles 3.0 (#143)<commit_after>// +build gen

//go:generate glow generate -out=./v2.1/gl/ -api=gl -version=2.1 -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./all-core/gl/ -api=gl -version=all -profile=core -lenientInit -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v3.2-core/gl/ -api=gl -version=3.2 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v3.3-core/gl/ -api=gl -version=3.3 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.1-core/gl/ -api=gl -version=4.1 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.2-core/gl/ -api=gl -version=4.2 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.3-core/gl/ -api=gl -version=4.3 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.4-core/gl/ -api=gl -version=4.4 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.5-core/gl/ -api=gl -version=4.5 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.6-core/gl/ -api=gl -version=4.6 -profile=core -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v3.2-compatibility/gl/ -api=gl -version=3.2 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v3.3-compatibility/gl/ -api=gl -version=3.3 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.1-compatibility/gl/ -api=gl -version=4.1 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.2-compatibility/gl/ -api=gl -version=4.2 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.3-compatibility/gl/ -api=gl -version=4.3 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.4-compatibility/gl/ -api=gl -version=4.4 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.5-compatibility/gl/ -api=gl -version=4.5 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v4.6-compatibility/gl/ -api=gl -version=4.6 -profile=compatibility -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v3.1/gles2/ -api=gles2 -version=3.1 -xml=../glow/xml/ -tmpl=../glow/tmpl/
//go:generate glow generate -out=./v3.0/gles2/ -api=gles2 -version=3.0 -xml=../glow/xml/ -tmpl=../glow/tmpl/

// This is an empty pseudo-package with the sole purpose of containing go generate directives
// that generate all gl binding packages inside this repository.
package gl
<|endoftext|>


<commit_before>package controller

import (
	. "eaciit/wfdemo-git/library/models"
	"eaciit/wfdemo-git/web/helper"
	"errors"
	"reflect"
	"strings"
	"time"

	"github.com/eaciit/acl/v1.0"
	// "github.com/eaciit/dbox"
	"github.com/eaciit/knot/knot.v1"
	"github.com/eaciit/toolkit"

	. "eaciit/wfdemo-git/library/core"
)

type LoginController struct {
	App
}

func CreateLoginController() *LoginController {
	var controller = new(LoginController)
	return controller
}

func (l *LoginController) GetSession(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson
	sessionId := r.Session("sessionid", "")
	return helper.CreateResult(true, sessionId, "")
}

func (l *LoginController) CheckCurrentSession(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson
	sessionid := r.Session("sessionid", "")

	// toolkit.Printf("CheckCurrentSession: %#v \v", sessionid)

	if !acl.IsSessionIDActive(toolkit.ToString(sessionid)) {
		r.SetSession("sessionid", "")
		return helper.CreateResult(false, false, "inactive")
	}
	return helper.CreateResult(true, true, "active")
}

func (l *LoginController) GetMenuList(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson
	menuList, err := GetListOfMenu(toolkit.ToString(r.Session("sessionid", "")))
	if err != nil {
		return helper.CreateResult(false, "", err.Error())
	}

	// remarked by ams, 2016-10-15
	// issue ServerAddress is localhost blablabla
	// suggestion : if you want to check with the real address please put it (the address / base url) in the configuration file
	//              if not, please find by segment or split by /

	payload := toolkit.M{}
	if err := r.GetPayload(&payload); err != nil {
		return helper.CreateResult(false, "", err.Error())
	}

	maxURLLen := 4
	urlSplit := strings.SplitN(payload.GetString("url"), "/", maxURLLen)
	if len(urlSplit) == maxURLLen {
		url := "/" + urlSplit[maxURLLen-1]

		isFound := false
		if len(MenuList) > 0 {
			for _, val := range MenuList {
				if val == url {
					isFound = true
				}
			}
			if url == "/web/page/login" {
				isFound = true
			}
			if !isFound {

				return helper.CreateResult(false, "", "You don't have access to this page")
			}
		}
	}

	return helper.CreateResult(true, menuList, "success")
}

func getMenus(r *knot.WebContext) (interface{}, error) {
	menuList, err := GetListOfMenu(toolkit.ToString(r.Session("sessionid", "")))
	if err != nil {
		return nil, err
	}

	payload := toolkit.M{}
	if err := r.GetPayload(&payload); err != nil {
		return nil, err
	}

	maxURLLen := 4
	urlSplit := strings.SplitN(payload.GetString("url"), "/", maxURLLen)
	if len(urlSplit) == maxURLLen {
		url := "/" + urlSplit[maxURLLen-1]

		isFound := false
		if len(MenuList) > 0 {
			for _, val := range MenuList {
				if val == url {
					isFound = true
				}
			}
			if url == "/web/page/login" {
				isFound = true
			}
			if !isFound {
				return nil, err
			}
		}
	}

	return menuList, err
}

func (l *LoginController) GetUserName(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson
	sessionId := r.Session("sessionid", "")

	if toolkit.ToString(sessionId) == "" {
		err := error(errors.New("Sessionid is not found"))
		return helper.CreateResult(false, nil, err.Error())
	}
	tUser, err := GetUserName(sessionId)

	if err != nil {
		return helper.CreateResult(false, nil, "Get username failed")
	}

	return helper.CreateResult(true, tUser.LoginID, "")
}

func (l *LoginController) ProcessLogin(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	lastDateData, _ := time.Parse("2006-01-02 15:04", "2016-10-31 23:59")

	payload := toolkit.M{}
	if err := r.GetPayload(&payload); err != nil {
		return helper.CreateResult(false, "", err.Error())
	}
	MenuList = []string{}
	menus, sessid, err := LoginProcess(payload)
	if err != nil {
		return helper.CreateResult(false, "", err.Error())
	}
	WriteLog(sessid, "login", r.Request.URL.String())
	r.SetSession("sessionid", sessid)
	r.SetSession("menus", menus)
	MenuList = menus

	// temporary add last date hardcode, then will change to get it from database automatically
	// add by ams, 2016-10-04

	query := DB().Connection.NewQuery().From(new(ScadaData).TableName()).Order("-timestamp").Take(1)

	csr, e := query.Cursor(nil)
	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	Result := make([]ScadaData, 0)
	e = csr.Fetch(&Result, 0, false)

	csr.Close()

	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	for _, val := range Result {
		// toolkit.Printf("Result : %s \n", val.TimeStamp.UTC())
		lastDateData = val.TimeStamp.UTC()
	}

	// toolkit.Printf("Result : %s \n", lastDateData)
	lastDateData = lastDateData.UTC()
	r.SetSession("lastdate_data", lastDateData)

	// Get Available Date All Collection
	latestDataPeriods := make([]LatestDataPeriod, 0)
	csr, e = DB().Connection.NewQuery().From(NewLatestDataPeriod().TableName()).Cursor(nil)
	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	e = csr.Fetch(&latestDataPeriods, 0, false)
	csr.Close()

	// toolkit.Println(latestDataPeriods)

	type availdatedata struct {
		ScadaData         []time.Time
		DGRData           []time.Time
		Alarm             []time.Time
		JMR               []time.Time
		MET               []time.Time
		Duration          []time.Time
		ScadaAnomaly      []time.Time
		AlarmOverlapping  []time.Time
		AlarmScadaAnomaly []time.Time
	}

	datePeriod := new(availdatedata)
	xdp := reflect.ValueOf(datePeriod).Elem()
	for _, d := range latestDataPeriods {
		f := xdp.FieldByName(d.Type)
		if f.IsValid() {
			if f.CanSet() {
				f.Set(reflect.ValueOf(d.Data))
			}
		}
	}

	r.SetSession("availdate", datePeriod)

	data := toolkit.M{
		"status":    true,
		"sessionid": sessid,
	}

	return helper.CreateResult(true, data, "Login Success")
}

func (l *LoginController) Logout(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	err := SetExpired(toolkit.M{"_id": r.Session("sessionid", "")})
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	WriteLog(r.Session("sessionid", ""), "logout", r.Request.URL.String())
	r.SetSession("sessionid", "")

	return helper.CreateResult(true, nil, "Logout Success")
}

func (l *LoginController) ResetPassword(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := toolkit.M{}
	err := r.GetPayload(&payload)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	if err = ResetPassword(payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	return helper.CreateResult(true, nil, "Reset Password Success")
}

func (l *LoginController) SavePassword(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := toolkit.M{}
	err := r.GetPayload(&payload)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	if err = SavePassword(payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	return helper.CreateResult(true, nil, "Save Password Success")
}

func (l *LoginController) Authenticate(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := toolkit.M{}

	if err := r.GetPayload(&payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	result, err := AuthenticateProc(payload)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	return helper.CreateResult(true, result, "Authenticate Success")
}
<commit_msg>bug fix empty session<commit_after>package controller

import (
	. "eaciit/wfdemo-git/library/models"
	"eaciit/wfdemo-git/web/helper"
	"errors"
	"reflect"
	"strings"
	"time"

	"github.com/eaciit/acl/v1.0"
	// "github.com/eaciit/dbox"
	"github.com/eaciit/knot/knot.v1"
	"github.com/eaciit/toolkit"

	. "eaciit/wfdemo-git/library/core"
)

type LoginController struct {
	App
}

func CreateLoginController() *LoginController {
	var controller = new(LoginController)
	return controller
}

func (l *LoginController) GetSession(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson
	sessionId := r.Session("sessionid", "")
	return helper.CreateResult(true, sessionId, "")
}

func (l *LoginController) CheckCurrentSession(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson
	sessionid := r.Session("sessionid", "")

	// toolkit.Printf("CheckCurrentSession: %#v \v", sessionid)

	if !acl.IsSessionIDActive(toolkit.ToString(sessionid)) {
		r.SetSession("sessionid", "")
		return helper.CreateResult(false, false, "inactive")
	}
	return helper.CreateResult(true, true, "active")
}

func (l *LoginController) GetMenuList(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson
	menuList, err := GetListOfMenu(toolkit.ToString(r.Session("sessionid", "")))
	if err != nil {
		return helper.CreateResult(false, "", err.Error())
	}

	// remarked by ams, 2016-10-15
	// issue ServerAddress is localhost blablabla
	// suggestion : if you want to check with the real address please put it (the address / base url) in the configuration file
	//              if not, please find by segment or split by /

	payload := toolkit.M{}
	if err := r.GetPayload(&payload); err != nil {
		return helper.CreateResult(false, "", err.Error())
	}

	maxURLLen := 4
	urlSplit := strings.SplitN(payload.GetString("url"), "/", maxURLLen)
	if len(urlSplit) == maxURLLen {
		url := "/" + urlSplit[maxURLLen-1]

		isFound := false
		if len(MenuList) > 0 {
			for _, val := range MenuList {
				if val == url {
					isFound = true
				}
			}
			if url == "/web/page/login" {
				isFound = true
			}
			if !isFound {

				return helper.CreateResult(false, "", "You don't have access to this page")
			}
		}
	}

	return helper.CreateResult(true, menuList, "success")
}

func getMenus(r *knot.WebContext) (interface{}, error) {
	menuList, err := GetListOfMenu(toolkit.ToString(r.Session("sessionid", "")))
	if err != nil {
		return nil, err
	}

	payload := toolkit.M{}
	if err := r.GetPayload(&payload); err != nil {
		return nil, err
	}

	maxURLLen := 4
	urlSplit := strings.SplitN(payload.GetString("url"), "/", maxURLLen)
	if len(urlSplit) == maxURLLen {
		url := "/" + urlSplit[maxURLLen-1]

		isFound := false
		if len(MenuList) > 0 {
			for _, val := range MenuList {
				if val == url {
					isFound = true
				}
			}
			if url == "/web/page/login" {
				isFound = true
			}
			if !isFound {
				return nil, err
			}
		}
	}

	return menuList, err
}

func (l *LoginController) GetUserName(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson
	sessionId := r.Session("sessionid", "")

	if toolkit.ToString(sessionId) == "" {
		err := error(errors.New("Sessionid is not found"))
		return helper.CreateResult(false, nil, err.Error())
	}
	tUser, err := GetUserName(sessionId)

	if err != nil {
		return helper.CreateResult(false, nil, "Get username failed")
	}

	return helper.CreateResult(true, tUser.LoginID, "")
}

func (l *LoginController) ProcessLogin(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	lastDateData, _ := time.Parse("2006-01-02 15:04", "2016-10-31 23:59")

	payload := toolkit.M{}
	if err := r.GetPayload(&payload); err != nil {
		return helper.CreateResult(false, "", err.Error())
	}
	MenuList = []string{}
	menus, sessid, err := LoginProcess(payload)
	if err != nil {
		return helper.CreateResult(false, "", err.Error())
	}
	WriteLog(sessid, "login", r.Request.URL.String())
	r.SetSession("sessionid", sessid)
	r.SetSession("menus", menus)
	helper.WC = r
	MenuList = menus

	// temporary add last date hardcode, then will change to get it from database automatically
	// add by ams, 2016-10-04

	query := DB().Connection.NewQuery().From(new(ScadaData).TableName()).Order("-timestamp").Take(1)

	csr, e := query.Cursor(nil)
	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	Result := make([]ScadaData, 0)
	e = csr.Fetch(&Result, 0, false)

	csr.Close()

	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	for _, val := range Result {
		// toolkit.Printf("Result : %s \n", val.TimeStamp.UTC())
		lastDateData = val.TimeStamp.UTC()
	}

	// toolkit.Printf("Result : %s \n", lastDateData)
	lastDateData = lastDateData.UTC()
	r.SetSession("lastdate_data", lastDateData)

	// Get Available Date All Collection
	latestDataPeriods := make([]LatestDataPeriod, 0)
	csr, e = DB().Connection.NewQuery().From(NewLatestDataPeriod().TableName()).Cursor(nil)
	if e != nil {
		return helper.CreateResult(false, nil, e.Error())
	}

	e = csr.Fetch(&latestDataPeriods, 0, false)
	csr.Close()

	// toolkit.Println(latestDataPeriods)

	type availdatedata struct {
		ScadaData         []time.Time
		DGRData           []time.Time
		Alarm             []time.Time
		JMR               []time.Time
		MET               []time.Time
		Duration          []time.Time
		ScadaAnomaly      []time.Time
		AlarmOverlapping  []time.Time
		AlarmScadaAnomaly []time.Time
	}

	datePeriod := new(availdatedata)
	xdp := reflect.ValueOf(datePeriod).Elem()
	for _, d := range latestDataPeriods {
		f := xdp.FieldByName(d.Type)
		if f.IsValid() {
			if f.CanSet() {
				f.Set(reflect.ValueOf(d.Data))
			}
		}
	}

	r.SetSession("availdate", datePeriod)

	data := toolkit.M{
		"status":    true,
		"sessionid": sessid,
	}

	return helper.CreateResult(true, data, "Login Success")
}

func (l *LoginController) Logout(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	err := SetExpired(toolkit.M{"_id": r.Session("sessionid", "")})
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	WriteLog(r.Session("sessionid", ""), "logout", r.Request.URL.String())
	r.SetSession("sessionid", "")

	return helper.CreateResult(true, nil, "Logout Success")
}

func (l *LoginController) ResetPassword(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := toolkit.M{}
	err := r.GetPayload(&payload)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}
	if err = ResetPassword(payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	return helper.CreateResult(true, nil, "Reset Password Success")
}

func (l *LoginController) SavePassword(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := toolkit.M{}
	err := r.GetPayload(&payload)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	if err = SavePassword(payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	return helper.CreateResult(true, nil, "Save Password Success")
}

func (l *LoginController) Authenticate(r *knot.WebContext) interface{} {
	r.Config.OutputType = knot.OutputJson

	payload := toolkit.M{}

	if err := r.GetPayload(&payload); err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	result, err := AuthenticateProc(payload)
	if err != nil {
		return helper.CreateResult(false, nil, err.Error())
	}

	return helper.CreateResult(true, result, "Authenticate Success")
}
<|endoftext|>


<commit_before>package ntlmssp

import (
	"bytes"
	"encoding/base64"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
)

//Negotiator is a http.Roundtripper decorator that automatically
//converts basic authentication to NTLM/Negotiate authentication when appropriate.
type Negotiator struct{ http.RoundTripper }

//RoundTrip sends the request to the server, handling any authentication
//re-sends as needed.
func (l Negotiator) RoundTrip(req *http.Request) (res *http.Response, err error) {
	// Use default round tripper if not provided
	rt := l.RoundTripper
	if rt == nil {
		rt = http.DefaultTransport
	}
	// If it is not basic auth, just round trip the request as usual
	reqauth := authheader(req.Header.Get("Authorization"))
	if !reqauth.IsBasic() {
		return rt.RoundTrip(req)
	}
	// Save request body
	body := bytes.Buffer{}
	if req.Body != nil {
		_, err = body.ReadFrom(req.Body)
		if err != nil {
			return nil, err
		}

		req.Body.Close()
		req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))
	}
	// first try anonymous, in case the server still finds us
	// authenticated from previous traffic
	req.Header.Del("Authorization")
	res, err = rt.RoundTrip(req)
	if err != nil {
		return nil, err
	}
	if res.StatusCode != http.StatusUnauthorized {
		return res, err
	}

	resauth := authheader(res.Header.Get("Www-Authenticate"))
	if !resauth.IsNegotiate() && !resauth.IsNTLM() {
		// Unauthorized, Negotiate not requested, let's try with basic auth
		req.Header.Set("Authorization", string(reqauth))
		io.Copy(ioutil.Discard, res.Body)
		res.Body.Close()
		req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))

		res, err = rt.RoundTrip(req)
		if err != nil {
			return nil, err
		}
		if res.StatusCode != http.StatusUnauthorized {
			return res, err
		}
		resauth = authheader(res.Header.Get("Www-Authenticate"))
	}

	if resauth.IsNegotiate() || resauth.IsNTLM() {
		// 401 with request:Basic and response:Negotiate
		io.Copy(ioutil.Discard, res.Body)
		res.Body.Close()

		// recycle credentials
		u, p, err := reqauth.GetBasicCreds()
		if err != nil {
			return nil, err
		}

       // parse domain name from username
       domain := ""

       if strings.Contains(u, "\\") {
            u_components := strings.Split(u, "\\")
            domain = u_components[0]
            u = u_components[1]
       }

       // send negotiate
       negotiateMessage, err := NewNegotiateMessage(domain, "")
       if err != nil {
           return nil, err
       }
       if resauth.IsNTLM() {
			req.Header.Set("Authorization", "NTLM "+base64.StdEncoding.EncodeToString(negotiateMessage))
		} else {
			req.Header.Set("Authorization", "Negotiate "+base64.StdEncoding.EncodeToString(negotiateMessage))
		}

		req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))

		res, err = rt.RoundTrip(req)
		if err != nil {
			return nil, err
		}

		// receive challenge?
		resauth = authheader(res.Header.Get("Www-Authenticate"))
		challengeMessage, err := resauth.GetData()
		if err != nil {
			return nil, err
		}
		if !(resauth.IsNegotiate() || resauth.IsNTLM()) || len(challengeMessage) == 0 {
			// Negotiation failed, let client deal with response
			return res, nil
		}
		io.Copy(ioutil.Discard, res.Body)
		res.Body.Close()

		// send authenticate
		authenticateMessage, err := ProcessChallenge(challengeMessage, u, p)
		if err != nil {
			return nil, err
		}
		if resauth.IsNTLM() {
			req.Header.Set("Authorization", "NTLM "+base64.StdEncoding.EncodeToString(authenticateMessage))
		} else {
			req.Header.Set("Authorization", "Negotiate "+base64.StdEncoding.EncodeToString(authenticateMessage))
		}

		req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))

		res, err = rt.RoundTrip(req)
	}

	return res, err
}
<commit_msg>Remove underscore from var<commit_after>package ntlmssp

import (
	"bytes"
	"encoding/base64"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
)

//Negotiator is a http.Roundtripper decorator that automatically
//converts basic authentication to NTLM/Negotiate authentication when appropriate.
type Negotiator struct{ http.RoundTripper }

//RoundTrip sends the request to the server, handling any authentication
//re-sends as needed.
func (l Negotiator) RoundTrip(req *http.Request) (res *http.Response, err error) {
	// Use default round tripper if not provided
	rt := l.RoundTripper
	if rt == nil {
		rt = http.DefaultTransport
	}
	// If it is not basic auth, just round trip the request as usual
	reqauth := authheader(req.Header.Get("Authorization"))
	if !reqauth.IsBasic() {
		return rt.RoundTrip(req)
	}
	// Save request body
	body := bytes.Buffer{}
	if req.Body != nil {
		_, err = body.ReadFrom(req.Body)
		if err != nil {
			return nil, err
		}

		req.Body.Close()
		req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))
	}
	// first try anonymous, in case the server still finds us
	// authenticated from previous traffic
	req.Header.Del("Authorization")
	res, err = rt.RoundTrip(req)
	if err != nil {
		return nil, err
	}
	if res.StatusCode != http.StatusUnauthorized {
		return res, err
	}

	resauth := authheader(res.Header.Get("Www-Authenticate"))
	if !resauth.IsNegotiate() && !resauth.IsNTLM() {
		// Unauthorized, Negotiate not requested, let's try with basic auth
		req.Header.Set("Authorization", string(reqauth))
		io.Copy(ioutil.Discard, res.Body)
		res.Body.Close()
		req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))

		res, err = rt.RoundTrip(req)
		if err != nil {
			return nil, err
		}
		if res.StatusCode != http.StatusUnauthorized {
			return res, err
		}
		resauth = authheader(res.Header.Get("Www-Authenticate"))
	}

	if resauth.IsNegotiate() || resauth.IsNTLM() {
		// 401 with request:Basic and response:Negotiate
		io.Copy(ioutil.Discard, res.Body)
		res.Body.Close()

		// recycle credentials
		u, p, err := reqauth.GetBasicCreds()
		if err != nil {
			return nil, err
		}

       // parse domain name from username
       domain := ""

       if strings.Contains(u, "\\") {
            ucomponents := strings.Split(u, "\\")
            domain = ucomponents[0]
            u = ucomponents[1]
       }

       // send negotiate
       negotiateMessage, err := NewNegotiateMessage(domain, "")
       if err != nil {
           return nil, err
       }
       if resauth.IsNTLM() {
			req.Header.Set("Authorization", "NTLM "+base64.StdEncoding.EncodeToString(negotiateMessage))
		} else {
			req.Header.Set("Authorization", "Negotiate "+base64.StdEncoding.EncodeToString(negotiateMessage))
		}

		req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))

		res, err = rt.RoundTrip(req)
		if err != nil {
			return nil, err
		}

		// receive challenge?
		resauth = authheader(res.Header.Get("Www-Authenticate"))
		challengeMessage, err := resauth.GetData()
		if err != nil {
			return nil, err
		}
		if !(resauth.IsNegotiate() || resauth.IsNTLM()) || len(challengeMessage) == 0 {
			// Negotiation failed, let client deal with response
			return res, nil
		}
		io.Copy(ioutil.Discard, res.Body)
		res.Body.Close()

		// send authenticate
		authenticateMessage, err := ProcessChallenge(challengeMessage, u, p)
		if err != nil {
			return nil, err
		}
		if resauth.IsNTLM() {
			req.Header.Set("Authorization", "NTLM "+base64.StdEncoding.EncodeToString(authenticateMessage))
		} else {
			req.Header.Set("Authorization", "Negotiate "+base64.StdEncoding.EncodeToString(authenticateMessage))
		}

		req.Body = ioutil.NopCloser(bytes.NewReader(body.Bytes()))

		res, err = rt.RoundTrip(req)
	}

	return res, err
}
<|endoftext|>