<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 e2e_node

import (
	"fmt"

	v1 "k8s.io/api/core/v1"
	schedulingv1 "k8s.io/api/scheduling/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	kubeapi "k8s.io/kubernetes/pkg/apis/core"
	"k8s.io/kubernetes/pkg/apis/scheduling"
	kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
	kubelettypes "k8s.io/kubernetes/pkg/kubelet/types"
	"k8s.io/kubernetes/test/e2e/framework"
	imageutils "k8s.io/kubernetes/test/utils/image"

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

const (
	criticalPodName            = "critical-pod"
	guaranteedPodName          = "guaranteed"
	burstablePodName           = "burstable"
	bestEffortPodName          = "best-effort"
	systemCriticalPriorityName = "critical-pod-test-high-priority"
)

var _ = framework.KubeDescribe("CriticalPod [Serial] [Disruptive] [NodeFeature:CriticalPod]", func() {
	f := framework.NewDefaultFramework("critical-pod-test")
	ginkgo.Context("when we need to admit a critical pod", func() {
		tempSetCurrentKubeletConfig(f, func(initialConfig *kubeletconfig.KubeletConfiguration) {
			if initialConfig.FeatureGates == nil {
				initialConfig.FeatureGates = make(map[string]bool)
			}
		})

		ginkgo.It("should be able to create and delete a critical pod", func() {
			configEnabled, err := isKubeletConfigEnabled(f)
			framework.ExpectNoError(err)
			if !configEnabled {
				framework.Skipf("unable to run test without dynamic kubelet config enabled.")
			}
			// because adminssion Priority enable, If the priority class is not found, the Pod is rejected.
			systemCriticalPriority := &schedulingv1.PriorityClass{ObjectMeta: metav1.ObjectMeta{Name: systemCriticalPriorityName}, Value: scheduling.SystemCriticalPriority}

			// Define test pods
			nonCriticalGuaranteed := getTestPod(false, guaranteedPodName, v1.ResourceRequirements{
				Requests: v1.ResourceList{
					v1.ResourceCPU:    resource.MustParse("100m"),
					v1.ResourceMemory: resource.MustParse("100Mi"),
				},
				Limits: v1.ResourceList{
					v1.ResourceCPU:    resource.MustParse("100m"),
					v1.ResourceMemory: resource.MustParse("100Mi"),
				},
			})
			nonCriticalBurstable := getTestPod(false, burstablePodName, v1.ResourceRequirements{
				Requests: v1.ResourceList{
					v1.ResourceCPU:    resource.MustParse("100m"),
					v1.ResourceMemory: resource.MustParse("100Mi"),
				},
			})
			nonCriticalBestEffort := getTestPod(false, bestEffortPodName, v1.ResourceRequirements{})
			criticalPod := getTestPod(true, criticalPodName, v1.ResourceRequirements{
				// request the entire resource capacity of the node, so that
				// admitting this pod requires the other pod to be preempted
				Requests: getNodeCPUAndMemoryCapacity(f),
			})

			_, err = f.ClientSet.SchedulingV1().PriorityClasses().Create(systemCriticalPriority)
			gomega.Expect(err == nil || errors.IsAlreadyExists(err)).To(gomega.BeTrue(), "failed to create PriorityClasses with an error: %v", err)

			// Create pods, starting with non-critical so that the critical preempts the other pods.
			f.PodClient().CreateBatch([]*v1.Pod{nonCriticalBestEffort, nonCriticalBurstable, nonCriticalGuaranteed})
			f.PodClientNS(kubeapi.NamespaceSystem).CreateSyncInNamespace(criticalPod, kubeapi.NamespaceSystem)

			// Check that non-critical pods other than the besteffort have been evicted
			updatedPodList, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).List(metav1.ListOptions{})
			framework.ExpectNoError(err)
			for _, p := range updatedPodList.Items {
				if p.Name == nonCriticalBestEffort.Name {
					gomega.Expect(p.Status.Phase).NotTo(gomega.Equal(v1.PodFailed), fmt.Sprintf("pod: %v should be preempted", p.Name))
				} else {
					framework.ExpectEqual(p.Status.Phase, v1.PodFailed, fmt.Sprintf("pod: %v should not be preempted", p.Name))
				}
			}
		})
		ginkgo.AfterEach(func() {
			// Delete Pods
			f.PodClient().DeleteSync(guaranteedPodName, &metav1.DeleteOptions{}, framework.DefaultPodDeletionTimeout)
			f.PodClient().DeleteSync(burstablePodName, &metav1.DeleteOptions{}, framework.DefaultPodDeletionTimeout)
			f.PodClient().DeleteSync(bestEffortPodName, &metav1.DeleteOptions{}, framework.DefaultPodDeletionTimeout)
			f.PodClientNS(kubeapi.NamespaceSystem).DeleteSyncInNamespace(criticalPodName, kubeapi.NamespaceSystem, &metav1.DeleteOptions{}, framework.DefaultPodDeletionTimeout)
			err := f.ClientSet.SchedulingV1().PriorityClasses().Delete(systemCriticalPriorityName, &metav1.DeleteOptions{})
			framework.ExpectNoError(err)
			// Log Events
			logPodEvents(f)
			logNodeEvents(f)

		})
	})
})

func getNodeCPUAndMemoryCapacity(f *framework.Framework) v1.ResourceList {
	nodeList, err := f.ClientSet.CoreV1().Nodes().List(metav1.ListOptions{})
	framework.ExpectNoError(err)
	// Assuming that there is only one node, because this is a node e2e test.
	framework.ExpectEqual(len(nodeList.Items), 1)
	capacity := nodeList.Items[0].Status.Allocatable
	return v1.ResourceList{
		v1.ResourceCPU:    capacity[v1.ResourceCPU],
		v1.ResourceMemory: capacity[v1.ResourceMemory],
	}
}

func getTestPod(critical bool, name string, resources v1.ResourceRequirements) *v1.Pod {
	value := scheduling.SystemCriticalPriority
	pod := &v1.Pod{
		TypeMeta: metav1.TypeMeta{
			Kind:       "Pod",
			APIVersion: "v1",
		},
		ObjectMeta: metav1.ObjectMeta{Name: name},
		Spec: v1.PodSpec{
			Containers: []v1.Container{
				{
					Name:      "container",
					Image:     imageutils.GetPauseImageName(),
					Resources: resources,
				},
			},
		},
	}
	if critical {
		pod.ObjectMeta.Namespace = kubeapi.NamespaceSystem
		pod.ObjectMeta.Annotations = map[string]string{
			kubelettypes.ConfigSourceAnnotationKey: kubelettypes.FileSource,
		}
		pod.Spec.PriorityClassName = systemCriticalPriorityName
		pod.Spec.Priority = &value

		gomega.Expect(kubelettypes.IsCriticalPod(pod)).To(gomega.BeTrue(), "pod should be a critical pod")
	} else {
		gomega.Expect(kubelettypes.IsCriticalPod(pod)).To(gomega.BeFalse(), "pod should not be a critical pod")
	}
	return pod
}
<commit_msg>Use framework.ExpectNotEqual()<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 e2e_node

import (
	"fmt"

	v1 "k8s.io/api/core/v1"
	schedulingv1 "k8s.io/api/scheduling/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/api/resource"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	kubeapi "k8s.io/kubernetes/pkg/apis/core"
	"k8s.io/kubernetes/pkg/apis/scheduling"
	kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
	kubelettypes "k8s.io/kubernetes/pkg/kubelet/types"
	"k8s.io/kubernetes/test/e2e/framework"
	imageutils "k8s.io/kubernetes/test/utils/image"

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

const (
	criticalPodName            = "critical-pod"
	guaranteedPodName          = "guaranteed"
	burstablePodName           = "burstable"
	bestEffortPodName          = "best-effort"
	systemCriticalPriorityName = "critical-pod-test-high-priority"
)

var _ = framework.KubeDescribe("CriticalPod [Serial] [Disruptive] [NodeFeature:CriticalPod]", func() {
	f := framework.NewDefaultFramework("critical-pod-test")
	ginkgo.Context("when we need to admit a critical pod", func() {
		tempSetCurrentKubeletConfig(f, func(initialConfig *kubeletconfig.KubeletConfiguration) {
			if initialConfig.FeatureGates == nil {
				initialConfig.FeatureGates = make(map[string]bool)
			}
		})

		ginkgo.It("should be able to create and delete a critical pod", func() {
			configEnabled, err := isKubeletConfigEnabled(f)
			framework.ExpectNoError(err)
			if !configEnabled {
				framework.Skipf("unable to run test without dynamic kubelet config enabled.")
			}
			// because adminssion Priority enable, If the priority class is not found, the Pod is rejected.
			systemCriticalPriority := &schedulingv1.PriorityClass{ObjectMeta: metav1.ObjectMeta{Name: systemCriticalPriorityName}, Value: scheduling.SystemCriticalPriority}

			// Define test pods
			nonCriticalGuaranteed := getTestPod(false, guaranteedPodName, v1.ResourceRequirements{
				Requests: v1.ResourceList{
					v1.ResourceCPU:    resource.MustParse("100m"),
					v1.ResourceMemory: resource.MustParse("100Mi"),
				},
				Limits: v1.ResourceList{
					v1.ResourceCPU:    resource.MustParse("100m"),
					v1.ResourceMemory: resource.MustParse("100Mi"),
				},
			})
			nonCriticalBurstable := getTestPod(false, burstablePodName, v1.ResourceRequirements{
				Requests: v1.ResourceList{
					v1.ResourceCPU:    resource.MustParse("100m"),
					v1.ResourceMemory: resource.MustParse("100Mi"),
				},
			})
			nonCriticalBestEffort := getTestPod(false, bestEffortPodName, v1.ResourceRequirements{})
			criticalPod := getTestPod(true, criticalPodName, v1.ResourceRequirements{
				// request the entire resource capacity of the node, so that
				// admitting this pod requires the other pod to be preempted
				Requests: getNodeCPUAndMemoryCapacity(f),
			})

			_, err = f.ClientSet.SchedulingV1().PriorityClasses().Create(systemCriticalPriority)
			gomega.Expect(err == nil || errors.IsAlreadyExists(err)).To(gomega.BeTrue(), "failed to create PriorityClasses with an error: %v", err)

			// Create pods, starting with non-critical so that the critical preempts the other pods.
			f.PodClient().CreateBatch([]*v1.Pod{nonCriticalBestEffort, nonCriticalBurstable, nonCriticalGuaranteed})
			f.PodClientNS(kubeapi.NamespaceSystem).CreateSyncInNamespace(criticalPod, kubeapi.NamespaceSystem)

			// Check that non-critical pods other than the besteffort have been evicted
			updatedPodList, err := f.ClientSet.CoreV1().Pods(f.Namespace.Name).List(metav1.ListOptions{})
			framework.ExpectNoError(err)
			for _, p := range updatedPodList.Items {
				if p.Name == nonCriticalBestEffort.Name {
					framework.ExpectNotEqual(p.Status.Phase, v1.PodFailed, fmt.Sprintf("pod: %v should be preempted", p.Name))
				} else {
					framework.ExpectEqual(p.Status.Phase, v1.PodFailed, fmt.Sprintf("pod: %v should not be preempted", p.Name))
				}
			}
		})
		ginkgo.AfterEach(func() {
			// Delete Pods
			f.PodClient().DeleteSync(guaranteedPodName, &metav1.DeleteOptions{}, framework.DefaultPodDeletionTimeout)
			f.PodClient().DeleteSync(burstablePodName, &metav1.DeleteOptions{}, framework.DefaultPodDeletionTimeout)
			f.PodClient().DeleteSync(bestEffortPodName, &metav1.DeleteOptions{}, framework.DefaultPodDeletionTimeout)
			f.PodClientNS(kubeapi.NamespaceSystem).DeleteSyncInNamespace(criticalPodName, kubeapi.NamespaceSystem, &metav1.DeleteOptions{}, framework.DefaultPodDeletionTimeout)
			err := f.ClientSet.SchedulingV1().PriorityClasses().Delete(systemCriticalPriorityName, &metav1.DeleteOptions{})
			framework.ExpectNoError(err)
			// Log Events
			logPodEvents(f)
			logNodeEvents(f)

		})
	})
})

func getNodeCPUAndMemoryCapacity(f *framework.Framework) v1.ResourceList {
	nodeList, err := f.ClientSet.CoreV1().Nodes().List(metav1.ListOptions{})
	framework.ExpectNoError(err)
	// Assuming that there is only one node, because this is a node e2e test.
	framework.ExpectEqual(len(nodeList.Items), 1)
	capacity := nodeList.Items[0].Status.Allocatable
	return v1.ResourceList{
		v1.ResourceCPU:    capacity[v1.ResourceCPU],
		v1.ResourceMemory: capacity[v1.ResourceMemory],
	}
}

func getTestPod(critical bool, name string, resources v1.ResourceRequirements) *v1.Pod {
	value := scheduling.SystemCriticalPriority
	pod := &v1.Pod{
		TypeMeta: metav1.TypeMeta{
			Kind:       "Pod",
			APIVersion: "v1",
		},
		ObjectMeta: metav1.ObjectMeta{Name: name},
		Spec: v1.PodSpec{
			Containers: []v1.Container{
				{
					Name:      "container",
					Image:     imageutils.GetPauseImageName(),
					Resources: resources,
				},
			},
		},
	}
	if critical {
		pod.ObjectMeta.Namespace = kubeapi.NamespaceSystem
		pod.ObjectMeta.Annotations = map[string]string{
			kubelettypes.ConfigSourceAnnotationKey: kubelettypes.FileSource,
		}
		pod.Spec.PriorityClassName = systemCriticalPriorityName
		pod.Spec.Priority = &value

		gomega.Expect(kubelettypes.IsCriticalPod(pod)).To(gomega.BeTrue(), "pod should be a critical pod")
	} else {
		gomega.Expect(kubelettypes.IsCriticalPod(pod)).To(gomega.BeFalse(), "pod should not be a critical pod")
	}
	return pod
}
<|endoftext|>


<commit_before>// Copied with small adaptations from the reflect package in the
// Go source tree.

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

// The deepdiff package implements a version of reflect.DeepEquals that
// also returns an error message describing the first difference found.
package checkers

import (
	"fmt"
	"reflect"
	"unsafe"
)

// During deepValueEqual, must keep track of checks that are
// in progress.  The comparison algorithm assumes that all
// checks in progress are true when it reencounters them.
// Visited comparisons are stored in a map indexed by visit.
type visit struct {
	a1  uintptr
	a2  uintptr
	typ reflect.Type
}

type mismatchError struct {
	v1, v2 reflect.Value
	path   string
	how    string
}

func (err *mismatchError) Error() string {
	path := err.path
	if path == "" {
		path = "top level"
	}
	return fmt.Sprintf("mismatch at %s: %s; obtained %#v; expected %#v", path, err.how, interfaceOf(err.v1), interfaceOf(err.v2))
}

// Tests for deep equality using reflected types. The map argument tracks
// comparisons that have already been seen, which allows short circuiting on
// recursive types.
func deepValueEqual(path string, v1, v2 reflect.Value, visited map[visit]bool, depth int) (ok bool, err error) {
	errorf := func(f string, a ...interface{}) error {
		return &mismatchError{
			v1:   v1,
			v2:   v2,
			path: path,
			how:  fmt.Sprintf(f, a...),
		}
	}
	if !v1.IsValid() || !v2.IsValid() {
		if v1.IsValid() == v2.IsValid() {
			return true, nil
		}
		return false, errorf("validity mismatch")
	}
	if v1.Type() != v2.Type() {
		return false, errorf("type mismatch %s vs %s", v1.Type(), v2.Type())
	}

	// if depth > 10 { panic("deepValueEqual") }	// for debugging
	hard := func(k reflect.Kind) bool {
		switch k {
		case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct:
			return true
		}
		return false
	}

	if v1.CanAddr() && v2.CanAddr() && hard(v1.Kind()) {
		addr1 := v1.UnsafeAddr()
		addr2 := v2.UnsafeAddr()
		if addr1 > addr2 {
			// Canonicalize order to reduce number of entries in visited.
			addr1, addr2 = addr2, addr1
		}

		// Short circuit if references are identical ...
		if addr1 == addr2 {
			return true, nil
		}

		// ... or already seen
		typ := v1.Type()
		v := visit{addr1, addr2, typ}
		if visited[v] {
			return true, nil
		}

		// Remember for later.
		visited[v] = true
	}

	switch v1.Kind() {
	case reflect.Array:
		if v1.Len() != v2.Len() {
			// can't happen!
			return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len())
		}
		for i := 0; i < v1.Len(); i++ {
			if ok, err := deepValueEqual(
				fmt.Sprintf("%s[%d]", path, i),
				v1.Index(i), v2.Index(i), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Slice:
		// We treat a nil slice the same as an empty slice.
		if v1.Len() != v2.Len() {
			return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len())
		}
		if v1.Pointer() == v2.Pointer() {
			return true, nil
		}
		for i := 0; i < v1.Len(); i++ {
			if ok, err := deepValueEqual(
				fmt.Sprintf("%s[%d]", path, i),
				v1.Index(i), v2.Index(i), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Interface:
		if v1.IsNil() || v2.IsNil() {
			if v1.IsNil() != v2.IsNil() {
				return false, fmt.Errorf("nil vs non-nil interface mismatch")
			}
			return true, nil
		}
		return deepValueEqual(path, v1.Elem(), v2.Elem(), visited, depth+1)
	case reflect.Ptr:
		return deepValueEqual("(*"+path+")", v1.Elem(), v2.Elem(), visited, depth+1)
	case reflect.Struct:
		for i, n := 0, v1.NumField(); i < n; i++ {
			path := path + "." + v1.Type().Field(i).Name
			if ok, err := deepValueEqual(path, v1.Field(i), v2.Field(i), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Map:
		if v1.IsNil() != v2.IsNil() {
			return false, errorf("nil vs non-nil mismatch")
		}
		if v1.Len() != v2.Len() {
			return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len())
		}
		if v1.Pointer() == v2.Pointer() {
			return true, nil
		}
		for _, k := range v1.MapKeys() {
			var p string
			if k.CanInterface() {
				p = path + "[" + fmt.Sprintf("%#v", k.Interface()) + "]"
			} else {
				p = path + "[someKey]"
			}
			if ok, err := deepValueEqual(p, v1.MapIndex(k), v2.MapIndex(k), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Func:
		if v1.IsNil() && v2.IsNil() {
			return true, nil
		}
		// Can't do better than this:
		return false, errorf("non-nil functions")
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		if v1.Int() != v2.Int() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Uint, reflect.Uintptr, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		if v1.Uint() != v2.Uint() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Float32, reflect.Float64:
		if v1.Float() != v2.Float() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Complex64, reflect.Complex128:
		if v1.Complex() != v2.Complex() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Bool:
		if v1.Bool() != v2.Bool() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.String:
		if v1.String() != v2.String() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Chan, reflect.UnsafePointer:
		if v1.Pointer() != v2.Pointer() {
			return false, errorf("unequal")
		}
		return true, nil
	default:
		panic("unexpected type " + v1.Type().String())
	}
}

// DeepEqual tests for deep equality. It uses normal == equality where
// possible but will scan elements of arrays, slices, maps, and fields
// of structs. In maps, keys are compared with == but elements use deep
// equality. DeepEqual correctly handles recursive types. Functions are
// equal only if they are both nil.
//
// DeepEqual differs from reflect.DeepEqual in that an empty slice is
// equal to a nil slice. If the two values compare unequal, the
// resulting error holds the first difference encountered.
func DeepEqual(a1, a2 interface{}) (bool, error) {
	errorf := func(f string, a ...interface{}) error {
		return &mismatchError{
			v1:   reflect.ValueOf(a1),
			v2:   reflect.ValueOf(a2),
			path: "",
			how:  fmt.Sprintf(f, a...),
		}
	}
	if a1 == nil || a2 == nil {
		return a1 == a2, errorf("nil vs non-nil mismatch")
	}
	v1 := reflect.ValueOf(a1)
	v2 := reflect.ValueOf(a2)
	if v1.Type() != v2.Type() {
		return false, errorf("type mismatch %s vs %s", v1.Type(), v2.Type())
	}
	return deepValueEqual("", v1, v2, make(map[visit]bool), 0)
}

// interfaceOf returns v.Interface() even if v.CanInterface() == false.
// This enables us to call fmt.Printf on a value even if it's derived
// from inside an unexported field.
func interfaceOf(v reflect.Value) interface{} {
	if !v.IsValid() {
		return nil
	}
	return bypassCanInterface(v).Interface()
}

type flag uintptr

// copied from reflect/value.go
const (
	flagRO flag = 1 << iota
)

var flagValOffset = func() uintptr {
	field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
	if !ok {
		panic("reflect.Value has no flag field")
	}
	return field.Offset
}()

func flagField(v *reflect.Value) *flag {
	return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))
}

// bypassCanInterface returns a version of v that
// bypasses the CanInterface check.
func bypassCanInterface(v reflect.Value) reflect.Value {
	if !v.IsValid() || v.CanInterface() {
		return v
	}
	*flagField(&v) &^= flagRO
	return v
}

// Sanity checks against future reflect package changes
// to the type or semantics of the Value.flag field.
func init() {
	field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
	if !ok {
		panic("reflect.Value has no flag field")
	}
	if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {
		panic("reflect.Value flag field has changed kind")
	}
	var t struct {
		a int
		A int
	}
	vA := reflect.ValueOf(t).FieldByName("A")
	va := reflect.ValueOf(t).FieldByName("a")
	flagA := *flagField(&vA)
	flaga := *flagField(&va)
	if flagA&flagRO != 0 || flaga&flagRO == 0 {
		panic("reflect.Value read-only flag has changed value")
	}
}
<commit_msg>testing/checkers: remove comment<commit_after>// Copied with small adaptations from the reflect package in the
// Go source tree.

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

package checkers

import (
	"fmt"
	"reflect"
	"unsafe"
)

// During deepValueEqual, must keep track of checks that are
// in progress.  The comparison algorithm assumes that all
// checks in progress are true when it reencounters them.
// Visited comparisons are stored in a map indexed by visit.
type visit struct {
	a1  uintptr
	a2  uintptr
	typ reflect.Type
}

type mismatchError struct {
	v1, v2 reflect.Value
	path   string
	how    string
}

func (err *mismatchError) Error() string {
	path := err.path
	if path == "" {
		path = "top level"
	}
	return fmt.Sprintf("mismatch at %s: %s; obtained %#v; expected %#v", path, err.how, interfaceOf(err.v1), interfaceOf(err.v2))
}

// Tests for deep equality using reflected types. The map argument tracks
// comparisons that have already been seen, which allows short circuiting on
// recursive types.
func deepValueEqual(path string, v1, v2 reflect.Value, visited map[visit]bool, depth int) (ok bool, err error) {
	errorf := func(f string, a ...interface{}) error {
		return &mismatchError{
			v1:   v1,
			v2:   v2,
			path: path,
			how:  fmt.Sprintf(f, a...),
		}
	}
	if !v1.IsValid() || !v2.IsValid() {
		if v1.IsValid() == v2.IsValid() {
			return true, nil
		}
		return false, errorf("validity mismatch")
	}
	if v1.Type() != v2.Type() {
		return false, errorf("type mismatch %s vs %s", v1.Type(), v2.Type())
	}

	// if depth > 10 { panic("deepValueEqual") }	// for debugging
	hard := func(k reflect.Kind) bool {
		switch k {
		case reflect.Array, reflect.Map, reflect.Slice, reflect.Struct:
			return true
		}
		return false
	}

	if v1.CanAddr() && v2.CanAddr() && hard(v1.Kind()) {
		addr1 := v1.UnsafeAddr()
		addr2 := v2.UnsafeAddr()
		if addr1 > addr2 {
			// Canonicalize order to reduce number of entries in visited.
			addr1, addr2 = addr2, addr1
		}

		// Short circuit if references are identical ...
		if addr1 == addr2 {
			return true, nil
		}

		// ... or already seen
		typ := v1.Type()
		v := visit{addr1, addr2, typ}
		if visited[v] {
			return true, nil
		}

		// Remember for later.
		visited[v] = true
	}

	switch v1.Kind() {
	case reflect.Array:
		if v1.Len() != v2.Len() {
			// can't happen!
			return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len())
		}
		for i := 0; i < v1.Len(); i++ {
			if ok, err := deepValueEqual(
				fmt.Sprintf("%s[%d]", path, i),
				v1.Index(i), v2.Index(i), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Slice:
		// We treat a nil slice the same as an empty slice.
		if v1.Len() != v2.Len() {
			return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len())
		}
		if v1.Pointer() == v2.Pointer() {
			return true, nil
		}
		for i := 0; i < v1.Len(); i++ {
			if ok, err := deepValueEqual(
				fmt.Sprintf("%s[%d]", path, i),
				v1.Index(i), v2.Index(i), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Interface:
		if v1.IsNil() || v2.IsNil() {
			if v1.IsNil() != v2.IsNil() {
				return false, fmt.Errorf("nil vs non-nil interface mismatch")
			}
			return true, nil
		}
		return deepValueEqual(path, v1.Elem(), v2.Elem(), visited, depth+1)
	case reflect.Ptr:
		return deepValueEqual("(*"+path+")", v1.Elem(), v2.Elem(), visited, depth+1)
	case reflect.Struct:
		for i, n := 0, v1.NumField(); i < n; i++ {
			path := path + "." + v1.Type().Field(i).Name
			if ok, err := deepValueEqual(path, v1.Field(i), v2.Field(i), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Map:
		if v1.IsNil() != v2.IsNil() {
			return false, errorf("nil vs non-nil mismatch")
		}
		if v1.Len() != v2.Len() {
			return false, errorf("length mismatch, %d vs %d", v1.Len(), v2.Len())
		}
		if v1.Pointer() == v2.Pointer() {
			return true, nil
		}
		for _, k := range v1.MapKeys() {
			var p string
			if k.CanInterface() {
				p = path + "[" + fmt.Sprintf("%#v", k.Interface()) + "]"
			} else {
				p = path + "[someKey]"
			}
			if ok, err := deepValueEqual(p, v1.MapIndex(k), v2.MapIndex(k), visited, depth+1); !ok {
				return false, err
			}
		}
		return true, nil
	case reflect.Func:
		if v1.IsNil() && v2.IsNil() {
			return true, nil
		}
		// Can't do better than this:
		return false, errorf("non-nil functions")
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		if v1.Int() != v2.Int() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Uint, reflect.Uintptr, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
		if v1.Uint() != v2.Uint() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Float32, reflect.Float64:
		if v1.Float() != v2.Float() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Complex64, reflect.Complex128:
		if v1.Complex() != v2.Complex() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Bool:
		if v1.Bool() != v2.Bool() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.String:
		if v1.String() != v2.String() {
			return false, errorf("unequal")
		}
		return true, nil
	case reflect.Chan, reflect.UnsafePointer:
		if v1.Pointer() != v2.Pointer() {
			return false, errorf("unequal")
		}
		return true, nil
	default:
		panic("unexpected type " + v1.Type().String())
	}
}

// DeepEqual tests for deep equality. It uses normal == equality where
// possible but will scan elements of arrays, slices, maps, and fields
// of structs. In maps, keys are compared with == but elements use deep
// equality. DeepEqual correctly handles recursive types. Functions are
// equal only if they are both nil.
//
// DeepEqual differs from reflect.DeepEqual in that an empty slice is
// equal to a nil slice. If the two values compare unequal, the
// resulting error holds the first difference encountered.
func DeepEqual(a1, a2 interface{}) (bool, error) {
	errorf := func(f string, a ...interface{}) error {
		return &mismatchError{
			v1:   reflect.ValueOf(a1),
			v2:   reflect.ValueOf(a2),
			path: "",
			how:  fmt.Sprintf(f, a...),
		}
	}
	if a1 == nil || a2 == nil {
		return a1 == a2, errorf("nil vs non-nil mismatch")
	}
	v1 := reflect.ValueOf(a1)
	v2 := reflect.ValueOf(a2)
	if v1.Type() != v2.Type() {
		return false, errorf("type mismatch %s vs %s", v1.Type(), v2.Type())
	}
	return deepValueEqual("", v1, v2, make(map[visit]bool), 0)
}

// interfaceOf returns v.Interface() even if v.CanInterface() == false.
// This enables us to call fmt.Printf on a value even if it's derived
// from inside an unexported field.
func interfaceOf(v reflect.Value) interface{} {
	if !v.IsValid() {
		return nil
	}
	return bypassCanInterface(v).Interface()
}

type flag uintptr

// copied from reflect/value.go
const (
	flagRO flag = 1 << iota
)

var flagValOffset = func() uintptr {
	field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
	if !ok {
		panic("reflect.Value has no flag field")
	}
	return field.Offset
}()

func flagField(v *reflect.Value) *flag {
	return (*flag)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + flagValOffset))
}

// bypassCanInterface returns a version of v that
// bypasses the CanInterface check.
func bypassCanInterface(v reflect.Value) reflect.Value {
	if !v.IsValid() || v.CanInterface() {
		return v
	}
	*flagField(&v) &^= flagRO
	return v
}

// Sanity checks against future reflect package changes
// to the type or semantics of the Value.flag field.
func init() {
	field, ok := reflect.TypeOf(reflect.Value{}).FieldByName("flag")
	if !ok {
		panic("reflect.Value has no flag field")
	}
	if field.Type.Kind() != reflect.TypeOf(flag(0)).Kind() {
		panic("reflect.Value flag field has changed kind")
	}
	var t struct {
		a int
		A int
	}
	vA := reflect.ValueOf(t).FieldByName("A")
	va := reflect.ValueOf(t).FieldByName("a")
	flagA := *flagField(&vA)
	flaga := *flagField(&va)
	if flagA&flagRO != 0 || flaga&flagRO == 0 {
		panic("reflect.Value read-only flag has changed value")
	}
}
<|endoftext|>


<commit_before>package service

import (
	"encoding/json"
	"net/http"

	"github.com/pkg/errors"
)

// GetHosts retrieves the list of all Hosts
func (c *Client) GetHosts() ([]HostResponse, error) {
	response, err := c.AuthenticatedDo("GET", "/api/v1/kolide/hosts", nil)
	if err != nil {
		return nil, errors.Wrap(err, "GET /api/v1/kolide/hosts")
	}
	defer response.Body.Close()

	if response.StatusCode != http.StatusOK {
		return nil, errors.Errorf(
			"get hosts received status %d %s",
			response.StatusCode,
			extractServerErrorText(response.Body),
		)
	}
	var responseBody listHostsResponse
	err = json.NewDecoder(response.Body).Decode(&responseBody)
	if err != nil {
		return nil, errors.Wrap(err, "decode list hosts response")
	}
	if responseBody.Err != nil {
		return nil, errors.Errorf("list hosts: %s", responseBody.Err)
	}

	return responseBody.Hosts, nil
}

// HostByIdentifier retrieves a host by the uuid, osquery_host_id, hostname, or
// node_key.
func (c *Client) HostByIdentifier(identifier string) (*HostResponse, error) {
	response, err := c.AuthenticatedDo("GET", "/api/v1/kolide/hosts/identifier/"+identifier, nil)
	if err != nil {
		return nil, errors.Wrap(err, "GET /api/v1/kolide/hosts/identifier")
	}
	defer response.Body.Close()

	if response.StatusCode != http.StatusOK {
		return nil, errors.Errorf(
			"get host by identifier received status %d %s",
			response.StatusCode,
			extractServerErrorText(response.Body),
		)
	}
	var responseBody getHostResponse
	err = json.NewDecoder(response.Body).Decode(&responseBody)
	if err != nil {
		return nil, errors.Wrap(err, "decode host response")
	}
	if responseBody.Err != nil {
		return nil, errors.Errorf("get host by identifier: %s", responseBody.Err)
	}

	return responseBody.Host, nil
}
<commit_msg>Add DeleteHost func to service pkg (#2312)<commit_after>package service

import (
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/pkg/errors"
)

// GetHosts retrieves the list of all Hosts
func (c *Client) GetHosts() ([]HostResponse, error) {
	response, err := c.AuthenticatedDo("GET", "/api/v1/kolide/hosts", nil)
	if err != nil {
		return nil, errors.Wrap(err, "GET /api/v1/kolide/hosts")
	}
	defer response.Body.Close()

	if response.StatusCode != http.StatusOK {
		return nil, errors.Errorf(
			"get hosts received status %d %s",
			response.StatusCode,
			extractServerErrorText(response.Body),
		)
	}
	var responseBody listHostsResponse
	err = json.NewDecoder(response.Body).Decode(&responseBody)
	if err != nil {
		return nil, errors.Wrap(err, "decode list hosts response")
	}
	if responseBody.Err != nil {
		return nil, errors.Errorf("list hosts: %s", responseBody.Err)
	}

	return responseBody.Hosts, nil
}

// HostByIdentifier retrieves a host by the uuid, osquery_host_id, hostname, or
// node_key.
func (c *Client) HostByIdentifier(identifier string) (*HostResponse, error) {
	response, err := c.AuthenticatedDo("GET", "/api/v1/kolide/hosts/identifier/"+identifier, nil)
	if err != nil {
		return nil, errors.Wrap(err, "GET /api/v1/kolide/hosts/identifier")
	}
	defer response.Body.Close()

	if response.StatusCode != http.StatusOK {
		return nil, errors.Errorf(
			"get host by identifier received status %d %s",
			response.StatusCode,
			extractServerErrorText(response.Body),
		)
	}
	var responseBody getHostResponse
	err = json.NewDecoder(response.Body).Decode(&responseBody)
	if err != nil {
		return nil, errors.Wrap(err, "decode host response")
	}
	if responseBody.Err != nil {
		return nil, errors.Errorf("get host by identifier: %s", responseBody.Err)
	}

	return responseBody.Host, nil
}

// DeleteHost deletes the host with the matching id.
func (c *Client) DeleteHost(id uint) error {
	verb := "DELETE"
	path := fmt.Sprintf("/api/v1/kolide/hosts/%d", id)
	response, err := c.AuthenticatedDo(verb, path, nil)
	if err != nil {
		return errors.Wrapf(err, "%s %s", verb, path)
	}
	defer response.Body.Close()

	switch response.StatusCode {
	case http.StatusNotFound:
		return notFoundErr{}
	}
	if response.StatusCode != http.StatusOK {
		return errors.Errorf(
			"delete host received status %d %s",
			response.StatusCode,
			extractServerErrorText(response.Body),
		)
	}

	var responseBody deleteHostResponse
	err = json.NewDecoder(response.Body).Decode(&responseBody)
	if err != nil {
		return errors.Wrap(err, "decode delete host response")
	}

	if responseBody.Err != nil {
		return errors.Errorf("delete host: %s", responseBody.Err)
	}

	return nil
}
<|endoftext|>


<commit_before>package bitbucket

import (
	"context"
	"crypto/sha256"
	"fmt"
	"net/http"
	"path/filepath"
	"strings"
	"sync"

	"github.com/reviewdog/reviewdog"
	"github.com/reviewdog/reviewdog/proto/rdf"
	"github.com/reviewdog/reviewdog/service/bitbucket/openapi"
)

var _ reviewdog.CommentService = &ReportAnnotator{}

const (
	logoURL  = "https://raw.githubusercontent.com/haya14busa/i/d598ed7dc49fefb0018e422e4c43e5ab8f207a6b/reviewdog/reviewdog.logo.png"
	reporter = "reviewdog"

	annotationTypeCodeSmell     = "CODE_SMELL"
	annotationTypeVulnerability = "VULNERABILITY"
	annotationTypeBug           = "BUG"

	annotationResultPassed  = "PASSED"
	annotationResultFailed  = "FAILED"
	annotationResultSkipped = "SKIPPED"
	annotationResultIgnored = "IGNORED"
	annotationResultPending = "PENDING"

	annotationSeverityHigh     = "HIGH"
	annotationSeverityMedium   = "MEDIUM"
	annotationSeverityLow      = "LOW"
	annotationSeverityCritical = "CRITICAL"

	reportTypeSecurity = "SECURITY"
	reportTypeCoverage = "COVERAGE"
	reportTypeTest     = "TEST"
	reportTypeBug      = "BUG"

	reportDataTypeBool       = "BOOLEAN"
	reportDataTypeDate       = "DATE"
	reportDataTypeDuration   = "DURATION"
	reportDataTypeLink       = "LINK"
	reportDataTypeNumber     = "NUMBER"
	reportDataTypePercentage = "PERCENTAGE"
	reportDataTypeText       = "TEXT"

	reportResultPassed  = "PASSED"
	reportResultFailed  = "FAILED"
	reportResultPending = "PENDING"
)

var severityMap = map[rdf.Severity]string{
	rdf.Severity_INFO:    annotationSeverityLow,
	rdf.Severity_WARNING: annotationSeverityMedium,
	rdf.Severity_ERROR:   annotationSeverityHigh,
}

// ReportAnnotator is a comment service for Bitbucket Code Insights reports.
//
// API:
//  https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Bworkspace%7D/%7Brepo_slug%7D/commit/%7Bcommit%7D/reports/%7BreportId%7D/annotations#post
//  POST /2.0/repositories/{username}/{repo_slug}/commit/{commit}/reports/{reportId}/annotations
type ReportAnnotator struct {
	ctx         context.Context
	cli         *openapi.APIClient
	sha         string
	owner, repo string
	reportTitle string

	muAnnotations sync.Mutex
	annotations   []openapi.ReportAnnotation
	issuesCount   map[rdf.Severity]int

	// wd is working directory relative to root of repository.
	wd       string
	reportID string
}

// NewReportAnnotator creates new Bitbucket Report Annotator
func NewReportAnnotator(cli *openapi.APIClient, reportTitle, owner, repo, sha string) *ReportAnnotator {
	if reportTitle == "" {
		reportTitle = "Reviewdog Report"
	}

	return &ReportAnnotator{
		cli:         cli,
		reportTitle: reportTitle,
		sha:         sha,
		owner:       owner,
		repo:        repo,
		reportID:    reporter + "-" + strings.ReplaceAll(reportTitle, " ", "_"),
	}
}

// Post accepts a comment and holds it. Flush method actually posts comments to
// Bitbucket in batch.
func (r *ReportAnnotator) Post(_ context.Context, c *reviewdog.Comment) error {
	c.Result.Diagnostic.GetLocation().Path = filepath.ToSlash(
		filepath.Join(r.wd, c.Result.Diagnostic.GetLocation().GetPath()))
	r.muAnnotations.Lock()
	defer r.muAnnotations.Unlock()

	r.issuesCount[c.Result.Diagnostic.GetSeverity()]++
	r.annotations = append(r.annotations, annotationFromReviewDogComment(*c))

	return nil
}

// Flush posts comments which has not been posted yet.
func (r *ReportAnnotator) Flush(ctx context.Context) error {
	r.muAnnotations.Lock()
	defer r.muAnnotations.Unlock()

	if len(r.annotations) == 0 {
		return r.createOrUpdateReport(ctx, reportResultPassed)
	}

	reportStatus := reportResultPending
	if r.issuesCount[rdf.Severity_ERROR] > 0 {
		reportStatus = reportResultFailed
	}

	if err := r.createOrUpdateReport(ctx, reportStatus); err != nil {
		return err
	}

	_, resp, err := r.cli.ReportsApi.BulkCreateOrUpdateAnnotations(
		ctx, r.owner, r.repo, r.sha, r.reportID,
	).Body(r.annotations).Execute()

	if err := checkAPIError(err, resp, http.StatusOK); err != nil {
		return fmt.Errorf("bitbucket.BulkCreateOrUpdateAnnotations: %s", err)
	}

	return nil
}

func annotationFromReviewDogComment(c reviewdog.Comment) openapi.ReportAnnotation {
	a := openapi.NewReportAnnotation()
	switch c.ToolName {
	// TODO: different type of annotation based on tool?
	default:
		a.SetAnnotationType(annotationTypeCodeSmell)
	}

	// hash the output of linter and use it as external id
	a.SetExternalId(hashString(c.Result.Diagnostic.OriginalOutput))
	a.SetSummary(c.Result.Diagnostic.GetMessage())
	a.SetDetails(fmt.Sprintf(`[%s] %s`, c.ToolName, c.Result.Diagnostic.GetMessage()))
	a.SetLine(c.Result.Diagnostic.GetLocation().GetRange().GetStart().GetLine())
	a.SetPath(c.Result.Diagnostic.GetLocation().GetPath())
	if v, ok := severityMap[c.Result.Diagnostic.GetSeverity()]; ok {
		a.SetSeverity(v)
	}
	if link := c.Result.Diagnostic.GetCode().GetUrl(); link != "" {
		a.SetLink(link)
	}

	return *a
}

func (r *ReportAnnotator) createOrUpdateReport(ctx context.Context, status string) error {
	var report = openapi.NewReport()
	report.SetTitle(r.reportTitle)
	// TODO: different report types?
	report.SetReportType(reportTypeBug)
	report.SetReporter(reporter)
	report.SetLogoUrl(logoURL)
	report.SetResult(status)
	report.SetDetails("Woof-Woof! This report generated for you by reviewdog")

	_, resp, err := r.cli.ReportsApi.CreateOrUpdateReport(
		ctx, r.owner, r.repo, r.sha, r.reportID,
	).Body(*report).Execute()

	if err := checkAPIError(err, resp, http.StatusOK); err != nil {
		return fmt.Errorf("bitbucket.CreateOrUpdateReport: %s", err)
	}

	return nil
}

func hashString(str string) string {
	h := sha256.New()
	h.Write([]byte(str))
	return fmt.Sprintf("%x", h.Sum(nil))
}
<commit_msg>fix empty map<commit_after>package bitbucket

import (
	"context"
	"crypto/sha256"
	"fmt"
	"net/http"
	"path/filepath"
	"strings"
	"sync"

	"github.com/reviewdog/reviewdog"
	"github.com/reviewdog/reviewdog/proto/rdf"
	"github.com/reviewdog/reviewdog/service/bitbucket/openapi"
)

var _ reviewdog.CommentService = &ReportAnnotator{}

const (
	logoURL  = "https://raw.githubusercontent.com/haya14busa/i/d598ed7dc49fefb0018e422e4c43e5ab8f207a6b/reviewdog/reviewdog.logo.png"
	reporter = "reviewdog"

	annotationTypeCodeSmell     = "CODE_SMELL"
	annotationTypeVulnerability = "VULNERABILITY"
	annotationTypeBug           = "BUG"

	annotationResultPassed  = "PASSED"
	annotationResultFailed  = "FAILED"
	annotationResultSkipped = "SKIPPED"
	annotationResultIgnored = "IGNORED"
	annotationResultPending = "PENDING"

	annotationSeverityHigh     = "HIGH"
	annotationSeverityMedium   = "MEDIUM"
	annotationSeverityLow      = "LOW"
	annotationSeverityCritical = "CRITICAL"

	reportTypeSecurity = "SECURITY"
	reportTypeCoverage = "COVERAGE"
	reportTypeTest     = "TEST"
	reportTypeBug      = "BUG"

	reportDataTypeBool       = "BOOLEAN"
	reportDataTypeDate       = "DATE"
	reportDataTypeDuration   = "DURATION"
	reportDataTypeLink       = "LINK"
	reportDataTypeNumber     = "NUMBER"
	reportDataTypePercentage = "PERCENTAGE"
	reportDataTypeText       = "TEXT"

	reportResultPassed  = "PASSED"
	reportResultFailed  = "FAILED"
	reportResultPending = "PENDING"
)

var severityMap = map[rdf.Severity]string{
	rdf.Severity_INFO:    annotationSeverityLow,
	rdf.Severity_WARNING: annotationSeverityMedium,
	rdf.Severity_ERROR:   annotationSeverityHigh,
}

// ReportAnnotator is a comment service for Bitbucket Code Insights reports.
//
// API:
//  https://developer.atlassian.com/bitbucket/api/2/reference/resource/repositories/%7Bworkspace%7D/%7Brepo_slug%7D/commit/%7Bcommit%7D/reports/%7BreportId%7D/annotations#post
//  POST /2.0/repositories/{username}/{repo_slug}/commit/{commit}/reports/{reportId}/annotations
type ReportAnnotator struct {
	ctx         context.Context
	cli         *openapi.APIClient
	sha         string
	owner, repo string
	reportTitle string

	muAnnotations sync.Mutex
	annotations   []openapi.ReportAnnotation
	issuesCount   map[rdf.Severity]int

	// wd is working directory relative to root of repository.
	wd       string
	reportID string
}

// NewReportAnnotator creates new Bitbucket Report Annotator
func NewReportAnnotator(cli *openapi.APIClient, reportTitle, owner, repo, sha string) *ReportAnnotator {
	if reportTitle == "" {
		reportTitle = "Reviewdog Report"
	}

	return &ReportAnnotator{
		cli:         cli,
		reportTitle: reportTitle,
		sha:         sha,
		owner:       owner,
		repo:        repo,
		reportID:    reporter + "-" + strings.ReplaceAll(reportTitle, " ", "_"),
		issuesCount: make(map[rdf.Severity]int),
	}
}

// Post accepts a comment and holds it. Flush method actually posts comments to
// Bitbucket in batch.
func (r *ReportAnnotator) Post(_ context.Context, c *reviewdog.Comment) error {
	c.Result.Diagnostic.GetLocation().Path = filepath.ToSlash(
		filepath.Join(r.wd, c.Result.Diagnostic.GetLocation().GetPath()))
	r.muAnnotations.Lock()
	defer r.muAnnotations.Unlock()

	r.issuesCount[c.Result.Diagnostic.GetSeverity()]++
	r.annotations = append(r.annotations, annotationFromReviewDogComment(*c))

	return nil
}

// Flush posts comments which has not been posted yet.
func (r *ReportAnnotator) Flush(ctx context.Context) error {
	r.muAnnotations.Lock()
	defer r.muAnnotations.Unlock()

	if len(r.annotations) == 0 {
		return r.createOrUpdateReport(ctx, reportResultPassed)
	}

	reportStatus := reportResultPending
	if r.issuesCount[rdf.Severity_ERROR] > 0 {
		reportStatus = reportResultFailed
	}

	if err := r.createOrUpdateReport(ctx, reportStatus); err != nil {
		return err
	}

	_, resp, err := r.cli.ReportsApi.BulkCreateOrUpdateAnnotations(
		ctx, r.owner, r.repo, r.sha, r.reportID,
	).Body(r.annotations).Execute()

	if err := checkAPIError(err, resp, http.StatusOK); err != nil {
		return fmt.Errorf("bitbucket.BulkCreateOrUpdateAnnotations: %s", err)
	}

	return nil
}

func annotationFromReviewDogComment(c reviewdog.Comment) openapi.ReportAnnotation {
	a := openapi.NewReportAnnotation()
	switch c.ToolName {
	// TODO: different type of annotation based on tool?
	default:
		a.SetAnnotationType(annotationTypeCodeSmell)
	}

	// hash the output of linter and use it as external id
	a.SetExternalId(hashString(c.Result.Diagnostic.OriginalOutput))
	a.SetSummary(c.Result.Diagnostic.GetMessage())
	a.SetDetails(fmt.Sprintf(`[%s] %s`, c.ToolName, c.Result.Diagnostic.GetMessage()))
	a.SetLine(c.Result.Diagnostic.GetLocation().GetRange().GetStart().GetLine())
	a.SetPath(c.Result.Diagnostic.GetLocation().GetPath())
	if v, ok := severityMap[c.Result.Diagnostic.GetSeverity()]; ok {
		a.SetSeverity(v)
	}
	if link := c.Result.Diagnostic.GetCode().GetUrl(); link != "" {
		a.SetLink(link)
	}

	return *a
}

func (r *ReportAnnotator) createOrUpdateReport(ctx context.Context, status string) error {
	var report = openapi.NewReport()
	report.SetTitle(r.reportTitle)
	// TODO: different report types?
	report.SetReportType(reportTypeBug)
	report.SetReporter(reporter)
	report.SetLogoUrl(logoURL)
	report.SetResult(status)
	report.SetDetails("Woof-Woof! This report generated for you by reviewdog")

	_, resp, err := r.cli.ReportsApi.CreateOrUpdateReport(
		ctx, r.owner, r.repo, r.sha, r.reportID,
	).Body(*report).Execute()

	if err := checkAPIError(err, resp, http.StatusOK); err != nil {
		return fmt.Errorf("bitbucket.CreateOrUpdateReport: %s", err)
	}

	return nil
}

func hashString(str string) string {
	h := sha256.New()
	h.Write([]byte(str))
	return fmt.Sprintf("%x", h.Sum(nil))
}
<|endoftext|>


<commit_before>// Copyright 2015 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package expressions

import (
	"fmt"

	"github.com/juju/errors"
	"github.com/pingcap/tidb/context"
	"github.com/pingcap/tidb/expression"
)

// ExistsSubQuery is the expression for "exists (select ...)".
// https://dev.mysql.com/doc/refman/5.7/en/exists-and-not-exists-subqueries.html
type ExistsSubQuery struct {
	// Sel is the sub query.
	Sel *SubQuery
	// Not is true, the expression is "not exists".
	Not bool
}

// Clone implements the Expression Clone interface.
func (es *ExistsSubQuery) Clone() (expression.Expression, error) {
	sel, err := es.Sel.Clone()
	if err != nil {
		return nil, errors.Trace(err)
	}

	return &ExistsSubQuery{Sel: sel.(*SubQuery), Not: es.Not}, nil
}

// IsStatic implements the Expression IsStatic interface.
func (es *ExistsSubQuery) IsStatic() bool {
	return es.Sel.IsStatic()
}

// String implements the Expression String interface.
func (es *ExistsSubQuery) String() string {
	if es.Not {
		return fmt.Sprintf("NOT EXISTS %s", es.Sel)
	}

	return fmt.Sprintf("EXISTS %s", es.Sel)
}

// Eval implements the Expression Eval interface.
func (es *ExistsSubQuery) Eval(ctx context.Context, args map[interface{}]interface{}) (interface{}, error) {
	if es.Sel.Value != nil {
		return !es.Not, nil
	}

	p, err := es.Sel.Plan(ctx)
	if err != nil {
		return nil, errors.Trace(err)
	}

	count := 0
	err = p.Do(ctx, func(id interface{}, data []interface{}) (bool, error) {
		if count > 0 {
			return false, nil
		}

		if len(data) == 1 {
			es.Sel.Value = data[0]
		} else {
			es.Sel.Value = data
		}

		count++
		return true, nil
	})
	if err != nil {
		return nil, errors.Trace(err)
	}

	if !es.Not {
		return es.Sel.Value != nil, nil
	}

	return es.Sel.Value == nil, nil
}

// NewExistsSubQuery creates a ExistsSubQuery object.
func NewExistsSubQuery(sel *SubQuery, not bool) *ExistsSubQuery {
	return &ExistsSubQuery{Sel: sel, Not: not}
}
<commit_msg>expression/expressions: fix exists subqueyr null value bug.<commit_after>// Copyright 2015 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package expressions

import (
	"fmt"

	"github.com/juju/errors"
	"github.com/pingcap/tidb/context"
	"github.com/pingcap/tidb/expression"
)

// ExistsSubQuery is the expression for "exists (select ...)".
// https://dev.mysql.com/doc/refman/5.7/en/exists-and-not-exists-subqueries.html
type ExistsSubQuery struct {
	// Sel is the sub query.
	Sel *SubQuery
	// Not is true, the expression is "not exists".
	Not bool
}

// Clone implements the Expression Clone interface.
func (es *ExistsSubQuery) Clone() (expression.Expression, error) {
	sel, err := es.Sel.Clone()
	if err != nil {
		return nil, errors.Trace(err)
	}

	return &ExistsSubQuery{Sel: sel.(*SubQuery), Not: es.Not}, nil
}

// IsStatic implements the Expression IsStatic interface.
func (es *ExistsSubQuery) IsStatic() bool {
	return es.Sel.IsStatic()
}

// String implements the Expression String interface.
func (es *ExistsSubQuery) String() string {
	if es.Not {
		return fmt.Sprintf("NOT EXISTS %s", es.Sel)
	}

	return fmt.Sprintf("EXISTS %s", es.Sel)
}

// Eval implements the Expression Eval interface.
func (es *ExistsSubQuery) Eval(ctx context.Context, args map[interface{}]interface{}) (interface{}, error) {
	if es.Sel.Value != nil {
		return !es.Not, nil
	}

	p, err := es.Sel.Plan(ctx)
	if err != nil {
		return nil, errors.Trace(err)
	}

	count := 0
	res := []interface{}{}
	err = p.Do(ctx, func(id interface{}, data []interface{}) (bool, error) {
		if count > 0 {
			return true, nil
		}

		if len(data) == 1 {
			res = append(res, data[0])
		} else {
			res = append(res, data)
		}

		count++
		return true, nil
	})
	if err != nil {
		return nil, errors.Trace(err)
	}

	es.Sel.Value = res

	if !es.Not {
		return es.Sel.Value != nil, nil
	}

	return es.Sel.Value == nil, nil
}

// NewExistsSubQuery creates a ExistsSubQuery object.
func NewExistsSubQuery(sel *SubQuery, not bool) *ExistsSubQuery {
	return &ExistsSubQuery{Sel: sel, Not: not}
}
<|endoftext|>


<commit_before>package analyze

import (
	"errors"
	"math"

	"github.com/eclesh/welford"
	"github.com/myrid/anode.exp/data"
)

type ThreeSigma struct {
	stats   *welford.Stats
	input   chan data.Datapoint
	outputs []chan data.Datapoint
	// Stores the three latest values for calculating a moving average.
	tailbuf [3]float64
}

func (t *ThreeSigma) Init(input chan data.Datapoint, outputs []chan data.Datapoint) error {
	if len(outputs) != 4 {
		return errors.New("Must supply 4 output channels")
	}
	t.stats = welford.New()
	t.input = input
	t.outputs = outputs
	return nil
}

func (t *ThreeSigma) Run() {
	for d := range t.input {
		// Add value to distribution, update mean and stddev.
		t.stats.Add(d.Value)
		stddev := t.stats.Stddev()
		mean := t.stats.Mean()

		// If difference between MA and mean > 3 sigma, send to output.
		ma := t.movingAvg(d.Value)
		if math.Abs(ma-mean) > 3*stddev {
			t.outputs[0] <- d
		}

		// Output mean.
		t.outputs[1] <- data.Datapoint{Timestamp: d.Timestamp, Value: mean}

		// Output mean +/- 3 standard deviations.
		upper := t.stats.Mean() + 3*stddev
		lower := t.stats.Mean() - 3*stddev
		t.outputs[2] <- data.Datapoint{Timestamp: d.Timestamp, Value: upper}
		t.outputs[3] <- data.Datapoint{Timestamp: d.Timestamp, Value: lower}
	}
}

// movinAvg returns the mean of the latest three values.
// TODO: tidy up handle fewer than 3 values correctly.
func (t *ThreeSigma) movingAvg(latest float64) float64 {
	t.tailbuf[0] = t.tailbuf[1]
	t.tailbuf[1] = t.tailbuf[2]
	t.tailbuf[2] = latest
	ma := (t.tailbuf[0] + t.tailbuf[1] + t.tailbuf[2]) / 3
	return ma
}
<commit_msg>Fix comment in analyze/threesigma.go<commit_after>package analyze

import (
	"errors"
	"math"

	"github.com/eclesh/welford"
	"github.com/myrid/anode.exp/data"
)

type ThreeSigma struct {
	stats   *welford.Stats
	input   chan data.Datapoint
	outputs []chan data.Datapoint
	// Stores the three latest values for calculating a moving average.
	tailbuf [3]float64
}

func (t *ThreeSigma) Init(input chan data.Datapoint, outputs []chan data.Datapoint) error {
	if len(outputs) != 4 {
		return errors.New("Must supply 4 output channels")
	}
	t.stats = welford.New()
	t.input = input
	t.outputs = outputs
	return nil
}

func (t *ThreeSigma) Run() {
	for d := range t.input {
		// Add value to distribution, update mean and stddev.
		t.stats.Add(d.Value)
		stddev := t.stats.Stddev()
		mean := t.stats.Mean()

		// If difference between MA and mean > 3 sigma, send to output.
		ma := t.movingAvg(d.Value)
		if math.Abs(ma-mean) > 3*stddev {
			t.outputs[0] <- d
		}

		// Output mean.
		t.outputs[1] <- data.Datapoint{Timestamp: d.Timestamp, Value: mean}

		// Output mean +/- 3 standard deviations.
		upper := t.stats.Mean() + 3*stddev
		lower := t.stats.Mean() - 3*stddev
		t.outputs[2] <- data.Datapoint{Timestamp: d.Timestamp, Value: upper}
		t.outputs[3] <- data.Datapoint{Timestamp: d.Timestamp, Value: lower}
	}
}

// movingAvg returns the mean of the latest three values.
// TODO: does not handle fewer than 3 values correctly.
func (t *ThreeSigma) movingAvg(latest float64) float64 {
	t.tailbuf[0] = t.tailbuf[1]
	t.tailbuf[1] = t.tailbuf[2]
	t.tailbuf[2] = latest
	ma := (t.tailbuf[0] + t.tailbuf[1] + t.tailbuf[2]) / 3
	return ma
}
<|endoftext|>


<commit_before>package testscript

import (
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"sync/atomic"
	"testing"
)

var profileId int32 = 0

// TestingM is implemented by *testing.M. It's defined as an interface
// to allow testscript to co-exist with other testing frameworks
// that might also wish to call M.Run.
type TestingM interface {
	Run() int
}

var ignoreMissedCoverage = false

// IgnoreMissedCoverage causes any missed coverage information
// (for example when a function passed to RunMain
// calls os.Exit, for example) to be ignored.
// This function should be called before calling RunMain.
func IgnoreMissedCoverage() {
	ignoreMissedCoverage = true
}

// RunMain should be called within a TestMain function to allow
// subcommands to be run in the testscript context.
//
// The commands map holds the set of command names, each
// with an associated run function which should return the
// code to pass to os.Exit. It's OK for a command function to
// exit itself, but this may result in loss of coverage information.
//
// This function returns an exit code to pass to os.Exit, after calling m.Run.
func RunMain(m TestingM, commands map[string]func() int) (exitCode int) {
	goCoverProfileMerge()
	cmdName := os.Getenv("TESTSCRIPT_COMMAND")
	if cmdName == "" {
		defer func() {
			if err := finalizeCoverProfile(); err != nil {
				log.Printf("cannot merge cover profiles: %v", err)
				exitCode = 2
			}
		}()
		// We're not in a subcommand.
		for name := range commands {
			name := name
			scriptCmds[name] = func(ts *TestScript, neg bool, args []string) {
				path, err := os.Executable()
				if err != nil {
					ts.Fatalf("cannot determine path to test binary: %v", err)
				}
				id := atomic.AddInt32(&profileId, 1) - 1
				oldEnvLen := len(ts.env)
				cprof := coverFilename(id)
				ts.env = append(ts.env,
					"TESTSCRIPT_COMMAND="+name,
					"TESTSCRIPT_COVERPROFILE="+cprof,
				)
				ts.cmdExec(neg, append([]string{path}, args...))
				ts.env = ts.env[0:oldEnvLen]
				if cprof == "" {
					return
				}
				f, err := os.Open(cprof)
				if err != nil {
					if ignoreMissedCoverage {
						return
					}
					ts.Fatalf("command %s (args %q) failed to generate coverage information", name, args)
					return
				}
				coverChan <- f
			}
		}
		return m.Run()
	}
	mainf := commands[cmdName]
	if mainf == nil {
		log.Printf("unknown command name %q", cmdName)
		return 2
	}
	// The command being registered is being invoked, so run it, then exit.
	os.Args[0] = cmdName
	cprof := os.Getenv("TESTSCRIPT_COVERPROFILE")
	if cprof == "" {
		// No coverage, act as normal.
		return mainf()
	}
	return runCoverSubcommand(cprof, mainf)
}

// runCoverSubcommand runs the given function, then writes any generated
// coverage information to the cprof file.
// This is called inside a separately run executable.
func runCoverSubcommand(cprof string, mainf func() int) (exitCode int) {
	// Change the error handling mode to PanicOnError
	// so that in the common case of calling flag.Parse in main we'll
	// be able to catch the panic instead of just exiting.
	flag.CommandLine.Init(flag.CommandLine.Name(), flag.PanicOnError)
	defer func() {
		panicErr := recover()
		if _, ok := panicErr.(error); ok {
			// The flag package will already have printed this error, assuming,
			// that is, that the error was created in the flag package.
			// TODO check the stack to be sure it was actually raised by the flag package.
			exitCode = 2
			panicErr = nil
		}
		// Set os.Args so that flag.Parse will tell testing the correct
		// coverprofile setting. Unfortunately this isn't sufficient because
		// the testing oackage explicitly avoids calling flag.Parse again
		// if flag.Parsed returns true, so we the coverprofile value directly
		// too.
		os.Args = []string{os.Args[0], "-test.coverprofile=" + cprof}
		setCoverProfile(cprof)

		// Suppress the chatty coverage and test report.
		devNull, err := os.Open(os.DevNull)
		if err != nil {
			panic(err)
		}
		os.Stdout = devNull
		os.Stderr = devNull

		// Run MainStart (recursively, but it we should be ok) with no tests
		// so that it writes the coverage profile.
		m := testing.MainStart(nopTestDeps{}, nil, nil, nil)
		if code := m.Run(); code != 0 && exitCode == 0 {
			exitCode = code
		}
		if _, err := os.Stat(cprof); err != nil {
			log.Printf("failed to write coverage profile %q", cprof)
		}
		if panicErr != nil {
			// The error didn't originate from the flag package (we know that
			// flag.PanicOnError causes an error value that implements error),
			// so carry on panicking.
			panic(panicErr)
		}
	}()
	return mainf()
}

func coverFilename(id int32) string {
	if cprof := coverProfile(); cprof != "" {
		return fmt.Sprintf("%s_%d", cprof, id)
	}
	return ""
}

func coverProfileFlag() flag.Getter {
	f := flag.CommandLine.Lookup("test.coverprofile")
	if f == nil {
		// We've imported testing so it definitely should be there.
		panic("cannot find test.coverprofile flag")
	}
	return f.Value.(flag.Getter)
}

func coverProfile() string {
	return coverProfileFlag().Get().(string)
}

func setCoverProfile(cprof string) {
	coverProfileFlag().Set(cprof)
}

type nopTestDeps struct{}

func (nopTestDeps) MatchString(pat, str string) (result bool, err error) {
	return false, nil
}

func (nopTestDeps) StartCPUProfile(w io.Writer) error {
	return nil
}

func (nopTestDeps) StopCPUProfile() {}

func (nopTestDeps) WriteProfileTo(name string, w io.Writer, debug int) error {
	return nil
}
func (nopTestDeps) ImportPath() string {
	return ""
}

func (nopTestDeps) StartTestLog(w io.Writer) {}

func (nopTestDeps) StopTestLog() error {
	return nil
}
<commit_msg>testscript: make it compile under Go 1.10<commit_after>package testscript

import (
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"sync/atomic"
	"testing"
)

var profileId int32 = 0

// TestingM is implemented by *testing.M. It's defined as an interface
// to allow testscript to co-exist with other testing frameworks
// that might also wish to call M.Run.
type TestingM interface {
	Run() int
}

var ignoreMissedCoverage = false

// IgnoreMissedCoverage causes any missed coverage information
// (for example when a function passed to RunMain
// calls os.Exit, for example) to be ignored.
// This function should be called before calling RunMain.
func IgnoreMissedCoverage() {
	ignoreMissedCoverage = true
}

// RunMain should be called within a TestMain function to allow
// subcommands to be run in the testscript context.
//
// The commands map holds the set of command names, each
// with an associated run function which should return the
// code to pass to os.Exit. It's OK for a command function to
// exit itself, but this may result in loss of coverage information.
//
// This function returns an exit code to pass to os.Exit, after calling m.Run.
func RunMain(m TestingM, commands map[string]func() int) (exitCode int) {
	goCoverProfileMerge()
	cmdName := os.Getenv("TESTSCRIPT_COMMAND")
	if cmdName == "" {
		defer func() {
			if err := finalizeCoverProfile(); err != nil {
				log.Printf("cannot merge cover profiles: %v", err)
				exitCode = 2
			}
		}()
		// We're not in a subcommand.
		for name := range commands {
			name := name
			scriptCmds[name] = func(ts *TestScript, neg bool, args []string) {
				path, err := os.Executable()
				if err != nil {
					ts.Fatalf("cannot determine path to test binary: %v", err)
				}
				id := atomic.AddInt32(&profileId, 1) - 1
				oldEnvLen := len(ts.env)
				cprof := coverFilename(id)
				ts.env = append(ts.env,
					"TESTSCRIPT_COMMAND="+name,
					"TESTSCRIPT_COVERPROFILE="+cprof,
				)
				ts.cmdExec(neg, append([]string{path}, args...))
				ts.env = ts.env[0:oldEnvLen]
				if cprof == "" {
					return
				}
				f, err := os.Open(cprof)
				if err != nil {
					if ignoreMissedCoverage {
						return
					}
					ts.Fatalf("command %s (args %q) failed to generate coverage information", name, args)
					return
				}
				coverChan <- f
			}
		}
		return m.Run()
	}
	mainf := commands[cmdName]
	if mainf == nil {
		log.Printf("unknown command name %q", cmdName)
		return 2
	}
	// The command being registered is being invoked, so run it, then exit.
	os.Args[0] = cmdName
	cprof := os.Getenv("TESTSCRIPT_COVERPROFILE")
	if cprof == "" {
		// No coverage, act as normal.
		return mainf()
	}
	return runCoverSubcommand(cprof, mainf)
}

// runCoverSubcommand runs the given function, then writes any generated
// coverage information to the cprof file.
// This is called inside a separately run executable.
func runCoverSubcommand(cprof string, mainf func() int) (exitCode int) {
	// Change the error handling mode to PanicOnError
	// so that in the common case of calling flag.Parse in main we'll
	// be able to catch the panic instead of just exiting.
	flag.CommandLine.Init(flag.CommandLine.Name(), flag.PanicOnError)
	defer func() {
		panicErr := recover()
		if _, ok := panicErr.(error); ok {
			// The flag package will already have printed this error, assuming,
			// that is, that the error was created in the flag package.
			// TODO check the stack to be sure it was actually raised by the flag package.
			exitCode = 2
			panicErr = nil
		}
		// Set os.Args so that flag.Parse will tell testing the correct
		// coverprofile setting. Unfortunately this isn't sufficient because
		// the testing oackage explicitly avoids calling flag.Parse again
		// if flag.Parsed returns true, so we the coverprofile value directly
		// too.
		os.Args = []string{os.Args[0], "-test.coverprofile=" + cprof}
		setCoverProfile(cprof)

		// Suppress the chatty coverage and test report.
		devNull, err := os.Open(os.DevNull)
		if err != nil {
			panic(err)
		}
		os.Stdout = devNull
		os.Stderr = devNull

		// Run MainStart (recursively, but it we should be ok) with no tests
		// so that it writes the coverage profile.
		m := testing.MainStart(nopTestDeps{}, nil, nil, nil)
		if code := m.Run(); code != 0 && exitCode == 0 {
			exitCode = code
		}
		if _, err := os.Stat(cprof); err != nil {
			log.Printf("failed to write coverage profile %q", cprof)
		}
		if panicErr != nil {
			// The error didn't originate from the flag package (we know that
			// flag.PanicOnError causes an error value that implements error),
			// so carry on panicking.
			panic(panicErr)
		}
	}()
	return mainf()
}

func coverFilename(id int32) string {
	if cprof := coverProfile(); cprof != "" {
		return fmt.Sprintf("%s_%d", cprof, id)
	}
	return ""
}

func coverProfileFlag() flag.Getter {
	f := flag.CommandLine.Lookup("test.coverprofile")
	if f == nil {
		// We've imported testing so it definitely should be there.
		panic("cannot find test.coverprofile flag")
	}
	return f.Value.(flag.Getter)
}

func coverProfile() string {
	return coverProfileFlag().Get().(string)
}

func setCoverProfile(cprof string) {
	coverProfileFlag().Set(cprof)
}

type nopTestDeps struct{}

func (nopTestDeps) MatchString(pat, str string) (result bool, err error) {
	return false, nil
}

func (nopTestDeps) StartCPUProfile(w io.Writer) error {
	return nil
}

func (nopTestDeps) StopCPUProfile() {}

func (nopTestDeps) WriteProfileTo(name string, w io.Writer, debug int) error {
	return nil
}
func (nopTestDeps) ImportPath() string {
	return ""
}
func (nopTestDeps) StartTestLog(w io.Writer) {}

func (nopTestDeps) StopTestLog() error {
	return nil
}

// Note: WriteHeapProfile is needed for Go 1.10 but not Go 1.11.
func (nopTestDeps) WriteHeapProfile(io.Writer) error {
	// Not needed for Go 1.10.
	return nil
}
<|endoftext|>


<commit_before>package service

import (
	"golang.org/x/net/html"
	curl "github.com/andelf/go-curl"
	"bytes"
	"github.com/PuerkitoBio/goquery"
	"net/url"
	"fmt"
	"strings"
)

type AhrefsService interface {
	SignIn(string, string) string
}

type ahrefsService struct{}

func (ahrefsService) SignInAndGetDashboard(email, password string, verbose bool) string {
	easy := curl.EasyInit()
	token := ""
	receivedHTML := ""
	defer easy.Cleanup()

	fooTest := func(body []byte, userdata interface{}) bool {
		receivedHTML += string(body)
		data, exists := getToken(body)
		if exists {
			token = data
		}

		return true
	}

	//first call
	easy.Setopt(curl.OPT_URL, "https://ahrefs.com/user/login")
	easy.Setopt(curl.OPT_SSL_VERIFYPEER, 1)
	easy.Setopt(curl.OPT_WRITEFUNCTION, fooTest)
	easy.Setopt(curl.OPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")
	easy.Setopt(curl.OPT_VERBOSE, verbose)
	easy.Setopt(curl.OPT_FOLLOWLOCATION, 1)
	easy.Setopt(curl.OPT_COOKIEJAR, "./cookiejar")
	easy.Setopt(curl.OPT_COOKIEFILE, "./cookiejar")
	easy.Setopt(curl.OPT_NOBODY, 0)
	easy.Perform()

	// lame and stupid method, but we have only callback for receiving data from curl_easy
	if strings.Contains(receivedHTML, "Dashboard") {
		return receivedHTML
	}

	receivedHTML = ""

	//second call in we need it (after first call we can be in Dashboard, thanks to cookieJar)
	easy.Setopt(curl.OPT_URL, "https://ahrefs.com/user/login")
	easy.Setopt(curl.OPT_HTTPHEADER, []string{
		"Referer: https://ahrefs.com/user/login",
		"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
		"Accept-Language: en-US,en;q=0.5",
		"Accept-Encoding: gzip, deflate",
		"Connection: keep-alive",
	})
	easy.Setopt(curl.OPT_POST, 1)
	form := url.Values{}
	form.Add("_token",    token)
	form.Add("email",     email)
	form.Add("password",  password)
	form.Add("return_to", "https://ahrefs.com/")
	postFields := form.Encode()
	fmt.Print(postFields + "\n")
	easy.Setopt(curl.OPT_POSTFIELDSIZE, len(postFields))
	easy.Setopt(curl.OPT_POSTFIELDS, postFields)
	easy.Perform()

	return receivedHTML
}

func getToken(body []byte) (string, bool) {
	rootNode, err := html.Parse(bytes.NewReader(body))
	if err != nil {
		return "", false
	}

	meta := goquery.NewDocumentFromNode(rootNode).Find("meta[name=_token]")
	token, exists := meta.Attr("content")
	if exists == false {
		return "", false
	}

	return token, true

}

func NewService() ahrefsService {
	return ahrefsService{}
}
<commit_msg>foo anon func was renamed to more attractive fashion<commit_after>package service

import (
	"golang.org/x/net/html"
	curl "github.com/andelf/go-curl"
	"bytes"
	"github.com/PuerkitoBio/goquery"
	"net/url"
	"fmt"
	"strings"
)

type AhrefsService interface {
	SignIn(string, string) string
}

type ahrefsService struct{}

func (ahrefsService) SignInAndGetDashboard(email, password string, verbose bool) string {
	easy := curl.EasyInit()
	token := ""
	receivedHTML := ""
	defer easy.Cleanup()

	getContent := func(body []byte, userdata interface{}) bool {
		receivedHTML += string(body)
		data, exists := getToken(body)
		if exists {
			token = data
		}

		return true
	}

	//first call
	easy.Setopt(curl.OPT_URL, "https://ahrefs.com/user/login")
	easy.Setopt(curl.OPT_SSL_VERIFYPEER, 1)
	easy.Setopt(curl.OPT_WRITEFUNCTION, getContent)
	easy.Setopt(curl.OPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko")
	easy.Setopt(curl.OPT_VERBOSE, verbose)
	easy.Setopt(curl.OPT_FOLLOWLOCATION, 1)
	easy.Setopt(curl.OPT_COOKIEJAR, "./cookiejar")
	easy.Setopt(curl.OPT_COOKIEFILE, "./cookiejar")
	easy.Setopt(curl.OPT_NOBODY, 0)
	easy.Perform()

	// lame and stupid method, but we have only callback for receiving data from curl_easy
	if strings.Contains(receivedHTML, "Dashboard") {
		return receivedHTML
	}

	receivedHTML = ""

	//second call in we need it (after first call we can be in Dashboard, thanks to cookieJar)
	easy.Setopt(curl.OPT_URL, "https://ahrefs.com/user/login")
	easy.Setopt(curl.OPT_HTTPHEADER, []string{
		"Referer: https://ahrefs.com/user/login",
		"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
		"Accept-Language: en-US,en;q=0.5",
		"Accept-Encoding: gzip, deflate",
		"Connection: keep-alive",
	})
	easy.Setopt(curl.OPT_POST, 1)
	form := url.Values{}
	form.Add("_token",    token)
	form.Add("email",     email)
	form.Add("password",  password)
	form.Add("return_to", "https://ahrefs.com/")
	postFields := form.Encode()
	fmt.Print(postFields + "\n")
	easy.Setopt(curl.OPT_POSTFIELDSIZE, len(postFields))
	easy.Setopt(curl.OPT_POSTFIELDS, postFields)
	easy.Perform()

	return receivedHTML
}

func getToken(body []byte) (string, bool) {
	rootNode, err := html.Parse(bytes.NewReader(body))
	if err != nil {
		return "", false
	}

	meta := goquery.NewDocumentFromNode(rootNode).Find("meta[name=_token]")
	token, exists := meta.Attr("content")
	if exists == false {
		return "", false
	}

	return token, true

}

func NewService() ahrefsService {
	return ahrefsService{}
}
<|endoftext|>


<commit_before>package server

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

// Version of IronFunctions
var Version = "0.0.70"

func handleVersion(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{"version": Version})
}
<commit_msg>functions: 0.0.71 release [skip ci]<commit_after>package server

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

// Version of IronFunctions
var Version = "0.0.71"

func handleVersion(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{"version": Version})
}
<|endoftext|>


<commit_before>package main

import (
	"net/smtp"
	"os"
)

var smtpConfigured bool
var smtpAuth smtp.Auth

func smtpConfigure() error {
	username := os.Getenv("SMTP_USERNAME")
	password := os.Getenv("SMTP_PASSWORD")
	host := os.Getenv("SMTP_HOST")
	port := os.Getenv("SMTP_PORT")
	if username == "" || password == "" || host == "" || port == "" {
		logger.Warningf("smtp not configured, no emails will be sent")
		smtpConfigured = false
		return nil
	}

	if os.Getenv("SMTP_FROM_ADDRESS") == "" {
		logger.Errorf("COMMENTO_SMTP_FROM_ADDRESS not set")
		smtpConfigured = false
		return errorMissingSmtpAddress
	}

	logger.Infof("configuring smtp: %s", host)
	smtpAuth = smtp.PlainAuth("", username, password, host)
	smtpConfigured = true
	return nil
}
<commit_msg>smtp_configure.go: allow empty username/password<commit_after>package main

import (
	"net/smtp"
	"os"
)

var smtpConfigured bool
var smtpAuth smtp.Auth

func smtpConfigure() error {
	username := os.Getenv("SMTP_USERNAME")
	password := os.Getenv("SMTP_PASSWORD")
	host := os.Getenv("SMTP_HOST")
	port := os.Getenv("SMTP_PORT")
	if host == "" || port == "" {
		logger.Warningf("smtp not configured, no emails will be sent")
		smtpConfigured = false
		return nil
	}

	if username == "" || password == "" {
		logger.Warningf("no SMTP username/password set, Commento will assume they aren't required")
	}

	if os.Getenv("SMTP_FROM_ADDRESS") == "" {
		logger.Errorf("COMMENTO_SMTP_FROM_ADDRESS not set")
		smtpConfigured = false
		return errorMissingSmtpAddress
	}

	logger.Infof("configuring smtp: %s", host)
	smtpAuth = smtp.PlainAuth("", username, password, host)
	smtpConfigured = true
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2015 CoreOS, Inc.
//
// 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 main

import (
	"os"
	"testing"
	"time"

	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/ThomasRooney/gexpect"
)

var interactiveTests = []struct {
	testName     string
	aciBuildArgs []string
	rktCmd       string
	say          string
	expect       string
}{
	{
		`Check tty without interactive`,
		[]string{"--exec=/inspect --check-tty"},
		`../bin/rkt --debug --insecure-skip-verify run rkt-inspect-interactive.aci`,
		``,
		`stdin is not a terminal`,
	},
	{
		`Check tty without interactive (with parameter)`,
		[]string{"--exec=/inspect"},
		`../bin/rkt --debug --insecure-skip-verify run rkt-inspect-interactive.aci -- --check-tty`,
		``,
		`stdin is not a terminal`,
	},
	{
		`Check tty with interactive`,
		[]string{"--exec=/inspect --check-tty"},
		`../bin/rkt --debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci`,
		``,
		`stdin is a terminal`,
	},
	{
		`Check tty with interactive (with parameter)`,
		[]string{"--exec=/inspect"},
		`../bin/rkt --debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci -- --check-tty`,
		``,
		`stdin is a terminal`,
	},
	{
		`Reading from stdin`,
		[]string{"--exec=/inspect --read-stdin"},
		`../bin/rkt --debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci`,
		`Saluton`,
		`Received text: Saluton`,
	},
	{
		`Reading from stdin (with parameter)`,
		[]string{"--exec=/inspect"},
		`../bin/rkt --debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci -- --read-stdin`,
		`Saluton`,
		`Received text: Saluton`,
	},
}

func TestInteractive(t *testing.T) {
	for i, tt := range interactiveTests {
		t.Logf("Running test #%v: %v", i, tt.testName)

		aciFileName := "rkt-inspect-interactive.aci"
		patchTestACI(aciFileName, tt.aciBuildArgs...)
		defer os.Remove(aciFileName)

		t.Logf("Command: %v", tt.rktCmd)
		child, err := gexpect.Spawn(tt.rktCmd)
		if err != nil {
			t.Fatalf("Cannot exec rkt #%v: %v", i, err)
		}
		if tt.say != "" {
			err = child.ExpectTimeout("Enter text:", time.Minute)
			if err != nil {
				t.Fatalf("Waited for the prompt but not found #%v", i)
			}

			err = child.SendLine(tt.say)
			if err != nil {
				t.Fatalf("Failed to send %q on the prompt #%v", tt.say, i)
			}
		}

		err = child.ExpectTimeout(tt.expect, time.Minute)
		if err != nil {
			t.Fatalf("Expected %q but not found #%v", tt.expect, i)
		}

		err = child.Wait()
		if err != nil {
			t.Fatalf("rkt didn't terminate correctly: %v", err)
		}
	}
}
<commit_msg>functional tests: Port interactive tests to rkt run context<commit_after>// Copyright 2015 CoreOS, Inc.
//
// 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 main

import (
	"fmt"
	"os"
	"testing"
	"time"

	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/ThomasRooney/gexpect"
)

var interactiveTests = []struct {
	testName     string
	aciBuildArgs []string
	rktArgs      string
	say          string
	expect       string
}{
	{
		`Check tty without interactive`,
		[]string{"--exec=/inspect --check-tty"},
		`--debug --insecure-skip-verify run rkt-inspect-interactive.aci`,
		``,
		`stdin is not a terminal`,
	},
	{
		`Check tty without interactive (with parameter)`,
		[]string{"--exec=/inspect"},
		`--debug --insecure-skip-verify run rkt-inspect-interactive.aci -- --check-tty`,
		``,
		`stdin is not a terminal`,
	},
	{
		`Check tty with interactive`,
		[]string{"--exec=/inspect --check-tty"},
		`--debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci`,
		``,
		`stdin is a terminal`,
	},
	{
		`Check tty with interactive (with parameter)`,
		[]string{"--exec=/inspect"},
		`--debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci -- --check-tty`,
		``,
		`stdin is a terminal`,
	},
	{
		`Reading from stdin`,
		[]string{"--exec=/inspect --read-stdin"},
		`--debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci`,
		`Saluton`,
		`Received text: Saluton`,
	},
	{
		`Reading from stdin (with parameter)`,
		[]string{"--exec=/inspect"},
		`--debug --insecure-skip-verify run --interactive rkt-inspect-interactive.aci -- --read-stdin`,
		`Saluton`,
		`Received text: Saluton`,
	},
}

func TestInteractive(t *testing.T) {
	ctx := newRktRunCtx()
	defer ctx.cleanup()

	for i, tt := range interactiveTests {
		t.Logf("Running test #%v: %v", i, tt.testName)

		aciFileName := "rkt-inspect-interactive.aci"
		patchTestACI(aciFileName, tt.aciBuildArgs...)
		defer os.Remove(aciFileName)

		rktCmd := fmt.Sprintf("%s %s", ctx.cmd(), tt.rktArgs)
		t.Logf("Command: %v", rktCmd)
		child, err := gexpect.Spawn(rktCmd)
		if err != nil {
			t.Fatalf("Cannot exec rkt #%v: %v", i, err)
		}
		if tt.say != "" {
			err = child.ExpectTimeout("Enter text:", time.Minute)
			if err != nil {
				t.Fatalf("Waited for the prompt but not found #%v", i)
			}

			err = child.SendLine(tt.say)
			if err != nil {
				t.Fatalf("Failed to send %q on the prompt #%v", tt.say, i)
			}
		}

		err = child.ExpectTimeout(tt.expect, time.Minute)
		if err != nil {
			t.Fatalf("Expected %q but not found #%v", tt.expect, i)
		}

		err = child.Wait()
		if err != nil {
			t.Fatalf("rkt didn't terminate correctly: %v", err)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"github.com/bmizerany/pat"
	"github.com/timeredbull/tsuru/api/app"
	"github.com/timeredbull/tsuru/api/auth"
	"github.com/timeredbull/tsuru/api/service"
	"github.com/timeredbull/tsuru/config"
	"github.com/timeredbull/tsuru/db"
	"github.com/timeredbull/tsuru/ec2"
	"github.com/timeredbull/tsuru/log"
	"github.com/timeredbull/tsuru/repository"
	stdlog "log"
	"log/syslog"
	"net/http"
)

func main() {
	var err error
	log.Target, err = syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags)
	if err != nil {
		panic(err)
	}
	configFile := flag.String("config", "/etc/tsuru/tsuru.conf", "tsuru config file")
	dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)")
	flag.Parse()
	err = config.ReadConfigFile(*configFile)
	if err != nil {
		log.Panic(err.Error())
	}
	connString, err := config.GetString("database:url")
	if err != nil {
		panic(err)
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		panic(err)
	}
	db.Session, err = db.Open(connString, dbName)
	if err != nil {
		log.Panic(err.Error())
	}
	defer db.Session.Close()
	_, err = ec2.Conn()
	if err != nil {
		log.Print("Got error while connecting with ec2:")
		log.Print(err.Error())
	}

	repository.RunAgent()
	m := pat.New()

	m.Get("/services/instances", AuthorizationRequiredHandler(service.ServicesInstancesHandler))
	m.Post("/services/instances", AuthorizationRequiredHandler(service.CreateInstanceHandler))
	m.Put("/services/instances/:instance/:app", AuthorizationRequiredHandler(app.BindHandler))
	m.Del("/services/instances/:instance/:app", AuthorizationRequiredHandler(app.UnbindHandler))
	m.Get("/services/instances/:instance/status", AuthorizationRequiredHandler(service.ServiceInstanceStatusHandler))

	m.Get("/services", AuthorizationRequiredHandler(service.ServicesHandler))
	m.Post("/services", AuthorizationRequiredHandler(service.CreateHandler))
	m.Put("/services", AuthorizationRequiredHandler(service.UpdateHandler))
	m.Del("/services/:name", AuthorizationRequiredHandler(service.DeleteHandler))
	m.Get("/services/:name", AuthorizationRequiredHandler(service.ServiceInfoHandler))
	m.Get("/services/:name/doc", AuthorizationRequiredHandler(service.GetDocHandler))
	m.Put("/services/:name/doc", AuthorizationRequiredHandler(service.AddDocHandler))
	m.Put("/services/:service/:team", AuthorizationRequiredHandler(service.GrantAccessToTeamHandler))
	m.Del("/services/:service/:team", AuthorizationRequiredHandler(service.RevokeAccessFromTeamHandler))

	m.Del("/apps/:name", AuthorizationRequiredHandler(app.AppDelete))
	m.Get("/apps/:name/repository/clone", Handler(app.CloneRepositoryHandler))
	m.Get("/apps/:name", AuthorizationRequiredHandler(app.AppInfo))
	m.Post("/apps/:name/run", AuthorizationRequiredHandler(app.RunCommand))
	m.Get("/apps/:name/env", AuthorizationRequiredHandler(app.GetEnv))
	m.Post("/apps/:name/env", AuthorizationRequiredHandler(app.SetEnv))
	m.Del("/apps/:name/env", AuthorizationRequiredHandler(app.UnsetEnv))
	m.Get("/apps", AuthorizationRequiredHandler(app.AppList))
	m.Post("/apps", AuthorizationRequiredHandler(app.CreateAppHandler))
	m.Put("/apps/:app/:team", AuthorizationRequiredHandler(app.GrantAccessToTeamHandler))
	m.Del("/apps/:app/:team", AuthorizationRequiredHandler(app.RevokeAccessFromTeamHandler))
	m.Get("/apps/:name/log", AuthorizationRequiredHandler(app.AppLog))

	m.Post("/users", Handler(auth.CreateUser))
	m.Post("/users/:email/tokens", Handler(auth.Login))
	m.Post("/users/keys", AuthorizationRequiredHandler(auth.AddKeyToUser))
	m.Del("/users/keys", AuthorizationRequiredHandler(auth.RemoveKeyFromUser))

	m.Get("/teams", AuthorizationRequiredHandler(auth.ListTeams))
	m.Post("/teams", AuthorizationRequiredHandler(auth.CreateTeam))
	m.Put("/teams/:team/:user", AuthorizationRequiredHandler(auth.AddUserToTeam))
	m.Del("/teams/:team/:user", AuthorizationRequiredHandler(auth.RemoveUserFromTeam))

	listen, err := config.GetString("listen")
	if err != nil {
		panic(err)
	}
	if !*dry {
		log.Fatal(http.ListenAndServe(listen, m))
	}
}
<commit_msg>api.webserver: Updating import paths of service api to use service/consumption and service/provision<commit_after>package main

import (
	"flag"
	"github.com/bmizerany/pat"
	"github.com/timeredbull/tsuru/api/app"
	"github.com/timeredbull/tsuru/api/auth"
	"github.com/timeredbull/tsuru/api/service/consumption"
	"github.com/timeredbull/tsuru/api/service/provision"
	"github.com/timeredbull/tsuru/config"
	"github.com/timeredbull/tsuru/db"
	"github.com/timeredbull/tsuru/ec2"
	"github.com/timeredbull/tsuru/log"
	"github.com/timeredbull/tsuru/repository"
	stdlog "log"
	"log/syslog"
	"net/http"
)

func main() {
	var err error
	log.Target, err = syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags)
	if err != nil {
		panic(err)
	}
	configFile := flag.String("config", "/etc/tsuru/tsuru.conf", "tsuru config file")
	dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)")
	flag.Parse()
	err = config.ReadConfigFile(*configFile)
	if err != nil {
		log.Panic(err.Error())
	}
	connString, err := config.GetString("database:url")
	if err != nil {
		panic(err)
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		panic(err)
	}
	db.Session, err = db.Open(connString, dbName)
	if err != nil {
		log.Panic(err.Error())
	}
	defer db.Session.Close()
	_, err = ec2.Conn()
	if err != nil {
		log.Print("Got error while connecting with ec2:")
		log.Print(err.Error())
	}

	repository.RunAgent()
	m := pat.New()

	m.Get("/services/instances", AuthorizationRequiredHandler(consumption.ServicesInstancesHandler))
	m.Post("/services/instances", AuthorizationRequiredHandler(consumption.CreateInstanceHandler))
	m.Put("/services/instances/:instance/:app", AuthorizationRequiredHandler(app.BindHandler))
	m.Del("/services/instances/:instance/:app", AuthorizationRequiredHandler(app.UnbindHandler))
	m.Get("/services/instances/:instance/status", AuthorizationRequiredHandler(consumption.ServiceInstanceStatusHandler))

	m.Get("/services", AuthorizationRequiredHandler(consumption.ServicesHandler))
	m.Post("/services", AuthorizationRequiredHandler(provision.CreateHandler))
	m.Put("/services", AuthorizationRequiredHandler(provision.UpdateHandler))
	m.Del("/services/:name", AuthorizationRequiredHandler(provision.DeleteHandler))
	m.Get("/services/:name", AuthorizationRequiredHandler(consumption.ServiceInfoHandler))
	m.Get("/services/:name/doc", AuthorizationRequiredHandler(provision.GetDocHandler))
	m.Put("/services/:name/doc", AuthorizationRequiredHandler(provision.AddDocHandler))
	m.Put("/services/:service/:team", AuthorizationRequiredHandler(provision.GrantAccessToTeamHandler))
	m.Del("/services/:service/:team", AuthorizationRequiredHandler(provision.RevokeAccessFromTeamHandler))

	m.Del("/apps/:name", AuthorizationRequiredHandler(app.AppDelete))
	m.Get("/apps/:name/repository/clone", Handler(app.CloneRepositoryHandler))
	m.Get("/apps/:name", AuthorizationRequiredHandler(app.AppInfo))
	m.Post("/apps/:name/run", AuthorizationRequiredHandler(app.RunCommand))
	m.Get("/apps/:name/env", AuthorizationRequiredHandler(app.GetEnv))
	m.Post("/apps/:name/env", AuthorizationRequiredHandler(app.SetEnv))
	m.Del("/apps/:name/env", AuthorizationRequiredHandler(app.UnsetEnv))
	m.Get("/apps", AuthorizationRequiredHandler(app.AppList))
	m.Post("/apps", AuthorizationRequiredHandler(app.CreateAppHandler))
	m.Put("/apps/:app/:team", AuthorizationRequiredHandler(app.GrantAccessToTeamHandler))
	m.Del("/apps/:app/:team", AuthorizationRequiredHandler(app.RevokeAccessFromTeamHandler))
	m.Get("/apps/:name/log", AuthorizationRequiredHandler(app.AppLog))

	m.Post("/users", Handler(auth.CreateUser))
	m.Post("/users/:email/tokens", Handler(auth.Login))
	m.Post("/users/keys", AuthorizationRequiredHandler(auth.AddKeyToUser))
	m.Del("/users/keys", AuthorizationRequiredHandler(auth.RemoveKeyFromUser))

	m.Get("/teams", AuthorizationRequiredHandler(auth.ListTeams))
	m.Post("/teams", AuthorizationRequiredHandler(auth.CreateTeam))
	m.Put("/teams/:team/:user", AuthorizationRequiredHandler(auth.AddUserToTeam))
	m.Del("/teams/:team/:user", AuthorizationRequiredHandler(auth.RemoveUserFromTeam))

	listen, err := config.GetString("listen")
	if err != nil {
		panic(err)
	}
	if !*dry {
		log.Fatal(http.ListenAndServe(listen, m))
	}
}
<|endoftext|>


<commit_before>package tool

import "testing"

func TestInArray(t *testing.T) {
	i, ok := InArray(1, []int{0, 1, 2, 3})
	if !ok {
		t.Errorf("failed to find needle")
	} else if i != 1 {
		t.Errorf("failed to to get needle index")
	}
}

func TestNotInArray(t *testing.T) {
	i, ok := InArray(4, []int{0, 1, 2, 3})
	if ok {
		t.Errorf("it should not be found")
	} else if i != -1 {
		t.Errorf("it should not have index")
	}
}
<commit_msg>good test report<commit_after>package tool

import "testing"

func TestInArray(t *testing.T) {
	assertEqual := func(exp interface{}, val interface{}) {
		if val != exp {
			t.Errorf("Expected %v, got %v.", exp, val)
		}
	}

	i, ok := InArray(1, []int{0, 1, 2, 3})
	assertEqual(true, ok)
	assertEqual(1, i)

	i, ok = InArray(4, []int{0, 1, 2, 3})
	assertEqual(false, ok)
	assertEqual(-1, i)
}
<|endoftext|>


<commit_before>package trackello

import (
	"fmt"
	"os"
	"testing"
)

func TestBoard(t *testing.T) {
	var boardTests = []struct {
		boardId  string
		hasError bool
	}{
		{"test", true},
		{"5532c8c02c1b8cbebb3e4de5", false},
		{"550ce6ae4285507e2c51f661", false},
		{"550ce6ae4285507e2c", true},
	}
	client, err := NewTrackello(os.Getenv("TRACKLLEO_TOKEN"), os.Getenv("TRACKELLO_APPKEY"))
	if err != nil {
		t.Fatal(err)
	}
	for _, tt := range boardTests {
		_, e := client.Board(tt.boardId)
		hasErr := (e != nil)
		if hasErr {
			fmt.Printf("Error %v\n", e)
		}
		if tt.hasError != hasErr {
			t.Fatalf("Expected %t for boardID '%s', got %t", tt.hasError, tt.boardId, hasErr)
		}
	}
}
<commit_msg>fix broken test<commit_after>package trackello

import (
	"os"
	"testing"
)

func TestBoard(t *testing.T) {
	var boardTests = []struct {
		boardId  string
		hasError bool
	}{
		{"test", true},
		{"5532c8c02c1b8cbebb3e4de5", false},
		{"550ce6ae4285507e2c51f661", false},
		{"550ce6ae4285507e2c", true},
	}
	client, err := NewTrackello(os.Getenv("TRACKELLO_TOKEN"), os.Getenv("TRACKELLO_APPKEY"))
	if err != nil {
		t.Fatal(err)
	}
	for _, tt := range boardTests {
		_, e := client.Board(tt.boardId)
		hasErr := (e != nil)
		if tt.hasError != hasErr {
			t.Fatalf("Expected %t for boardID '%s', got %t", tt.hasError, tt.boardId, hasErr)
		}
	}
}
<|endoftext|>