<commit_before>/*
Copyright 2014 Google Inc. All rights reserved.

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

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

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

package api

import (
	"github.com/fsouza/go-dockerclient"
)

// Common string formats
// ---------------------
// Many fields in this API have formatting requirements.  The commonly used
// formats are defined here.
//
// C_IDENTIFIER:  This is a string that conforms the definition of an "identifier"
//     in the C language.  This is captured by the following regex:
//         [A-Za-z_][A-Za-z0-9_]*
//     This defines the format, but not the length restriction, which should be
//     specified at the definition of any field of this type.
//
// DNS_LABEL:  This is a string that conforms to the definition of a "label"
//     in RFCs 1035 and 1123.  This is captured by the following regex:
//         [a-z0-9]([-a-z0-9]*[a-z0-9])?
//     This defines the format, but not the length restriction, which should be
//     specified at the definition of any field of this type.
//
//  DNS_SUBDOMAIN:  This is a string that conforms to the definition of a
//      "subdomain" in RFCs 1035 and 1123.  This is captured by the following regex:
//         [a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*
//     or more simply:
//         DNS_LABEL(\.DNS_LABEL)*
//     This defines the format, but not the length restriction, which should be
//     specified at the definition of any field of this type.

// ContainerManifest corresponds to the Container Manifest format, documented at:
// https://developers.google.com/compute/docs/containers/container_vms#container_manifest
// This is used as the representation of Kubernetes workloads.
type ContainerManifest struct {
	// Required: This must be a supported version string, such as "v1beta1".
	Version string `yaml:"version" json:"version"`
	// Required: This must be a DNS_SUBDOMAIN, 255 characters or less.
	ID         string      `yaml:"id" json:"id"`
	Volumes    []Volume    `yaml:"volumes" json:"volumes"`
	Containers []Container `yaml:"containers" json:"containers"`
}

// Volume represents a named volume in a pod that may be accessed by any containers in the pod.
type Volume struct {
	// Required: This must be a DNS_LABEL, 63 characters or less.  Each volume in a pod
	// must have a unique name.
	Name string `yaml:"name" json:"name"`
}

// Port represents a network port in a single container
type Port struct {
	// Optional: If specified, this must be a DNS_LABEL, 63 characters or less.  Each
	// container in a pod must have a unique name.
	Name string `yaml:"name,omitempty" json:"name,omitempty"`
	// Optional: Defaults to ContainerPort.
	HostPort int `yaml:"hostPort,omitempty" json:"hostPort,omitempty"`
	// Required: This must be a valid port number, 0 < x < 65536.
	ContainerPort int `yaml:"containerPort" json:"containerPort"`
	// Optional: Defaults to "TCP".
	Protocol string `yaml:"protocol,omitempty" json:"protocol,omitempty"`
}

// VolumeMount describes a mounting of a Volume within a container
type VolumeMount struct {
	// Required: This must match the Name of a Volume [above].
	Name string `yaml:"name" json:"name"`
	// Optional: Defaults to false (read-write).
	ReadOnly bool `yaml:"readOnly,omitempty" json:"readOnly,omitempty"`
	// Required.
	MountPath string `yaml:"mountPath,omitempty" json:"mountPath,omitempty"`
	// One of: "LOCAL" (local volume) or "HOST" (external mount from the host). Default: LOCAL.
	MountType string `yaml:"mountType,omitempty" json:"mountType,omitempty"`
}

// EnvVar represents an environment variable present in a Container
type EnvVar struct {
	// Required: This must be a C_IDENTIFIER.
	Name string `yaml:"name" json:"name"`
	// Optional: defaults to "".
	Value string `yaml:"value,omitempty" json:"value,omitempty"`
}

// Container represents a single container that is expected to be run on the host.
type Container struct {
	// Required: This must be a DNS_LABEL, 63 characters or less.  Each container in a
	// pod must have a unique name.
	Name string `yaml:"name" json:"name"`
	// Required.
	Image string `yaml:"image" json:"image"`
	// Optional: Defaults to whatever is defined in the image.
	Command []string `yaml:"command,omitempty" json:"command,omitempty"`
	// Optional: Defaults to Docker's default.
	WorkingDir string   `yaml:"workingDir,omitempty" json:"workingDir,omitempty"`
	Ports      []Port   `yaml:"ports,omitempty" json:"ports,omitempty"`
	Env        []EnvVar `yaml:"env,omitempty" json:"env,omitempty"`
	// Optional: Defaults to unlimited.
	Memory int `yaml:"memory,omitempty" json:"memory,omitempty"`
	// Optional: Defaults to unlimited.
	CPU          int           `yaml:"cpu,omitempty" json:"cpu,omitempty"`
	VolumeMounts []VolumeMount `yaml:"volumeMounts,omitempty" json:"volumeMounts,omitempty"`
}

// Percentile represents a pair which contains a percentage from 0 to 100 and
// its corresponding value.
type Percentile struct {
	Percentage int    `json:"percentage,omitempty"`
	Value      uint64 `json:"value,omitempty"`
}

// ContainerStats represents statistical information of a container
type ContainerStats struct {
	CpuUsagePercentiles    []Percentile `json:"cpu_usage_percentiles,omitempty"`
	MemoryUsagePercentiles []Percentile `json:"memory_usage_percentiles,omitempty"`
	MaxMemoryUsage         uint64       `json:"max_memory_usage,omitempty"`
}

// Event is the representation of an event logged to etcd backends
type Event struct {
	Event     string             `json:"event,omitempty"`
	Manifest  *ContainerManifest `json:"manifest,omitempty"`
	Container *Container         `json:"container,omitempty"`
	Timestamp int64              `json:"timestamp"`
}

// The below types are used by kube_client and api_server.

// JSONBase is shared by all objects sent to, or returned from the client
type JSONBase struct {
	Kind              string `json:"kind,omitempty" yaml:"kind,omitempty"`
	ID                string `json:"id,omitempty" yaml:"id,omitempty"`
	CreationTimestamp string `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"`
	SelfLink          string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"`
}

type PodStatus string

const (
	PodRunning PodStatus = "Running"
	PodPending PodStatus = "Pending"
	PodStopped PodStatus = "Stopped"
)

// PodState is the state of a pod, used as either input (desired state) or output (current state)
type PodState struct {
	Manifest ContainerManifest `json:"manifest,omitempty" yaml:"manifest,omitempty"`
	Status   PodStatus         `json:"status,omitempty" yaml:"status,omitempty"`
	Host     string            `json:"host,omitempty" yaml:"host,omitempty"`
	HostIP   string            `json:"hostIP,omitempty" yaml:"hostIP,omitempty"`

	// The key of this map is the *name* of the container within the manifest; it has one
	// entry per container in the manifest. The value of this map is currently the output
	// of `docker inspect`. This output format is *not* final and should not be relied
	// upon.
	// TODO: Make real decisions about what our info should look like.
	Info map[string]docker.Container `json:"info,omitempty" yaml:"info,omitempty"`
}

type PodList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Items    []Pod `json:"items" yaml:"items,omitempty"`
}

// Pod is a collection of containers, used as either input (create, update) or as output (list, get)
type Pod struct {
	JSONBase     `json:",inline" yaml:",inline"`
	Labels       map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
	DesiredState PodState          `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
	CurrentState PodState          `json:"currentState,omitempty" yaml:"currentState,omitempty"`
}

// ReplicationControllerState is the state of a replication controller, either input (create, update) or as output (list, get)
type ReplicationControllerState struct {
	Replicas        int               `json:"replicas" yaml:"replicas"`
	ReplicaSelector map[string]string `json:"replicaSelector,omitempty" yaml:"replicaSelector,omitempty"`
	PodTemplate     PodTemplate       `json:"podTemplate,omitempty" yaml:"podTemplate,omitempty"`
}

type ReplicationControllerList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Items    []ReplicationController `json:"items,omitempty" yaml:"items,omitempty"`
}

// ReplicationController represents the configuration of a replication controller
type ReplicationController struct {
	JSONBase     `json:",inline" yaml:",inline"`
	DesiredState ReplicationControllerState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
	Labels       map[string]string          `json:"labels,omitempty" yaml:"labels,omitempty"`
}

// PodTemplate holds the information used for creating pods
type PodTemplate struct {
	DesiredState PodState          `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
	Labels       map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
}

// ServiceList holds a list of services
type ServiceList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Items    []Service `json:"items" yaml:"items"`
}

// Defines a service abstraction by a name (for example, mysql) consisting of local port
// (for example 3306) that the proxy listens on, and the selector that determines which pods
// will answer requests sent through the proxy.
type Service struct {
	JSONBase `json:",inline" yaml:",inline"`
	Port     int `json:"port,omitempty" yaml:"port,omitempty"`

	// This service's labels.
	Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`

	// This service will route traffic to pods having labels matching this selector.
	Selector                   map[string]string `json:"selector,omitempty" yaml:"selector,omitempty"`
	CreateExternalLoadBalancer bool              `json:"createExternalLoadBalancer,omitempty" yaml:"createExternalLoadBalancer,omitempty"`
}

// Defines the endpoints that implement the actual service, for example:
// Name: "mysql", Endpoints: ["10.10.1.1:1909", "10.10.2.2:8834"]
type Endpoints struct {
	Name      string
	Endpoints []string
}

// Information about a single Minion; the name of the minion according to etcd
// is in JSONBase.ID.
type Minion struct {
	JSONBase `json:",inline" yaml:",inline"`
	// Queried from cloud provider, if available.
	HostIP string `json:"hostIP,omitempty" yaml:"hostIP,omitempty"`
}

// A list of minions.
type MinionList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Items    []Minion `json:"minions,omitempty" yaml:"minions,omitempty"`
}

// Status is a return value for calls that don't return other objects.
// Arguably, this could go in apiserver, but I'm including it here so clients needn't
// import both.
type Status struct {
	JSONBase `json:",inline" yaml:",inline"`
	// One of: "success", "failure", "working" (for operations not yet completed)
	// TODO: if "working", include an operation identifier so final status can be
	// checked.
	Status  string `json:"status,omitempty" yaml:"status,omitempty"`
	Details string `json:"details,omitempty" yaml:"details,omitempty"`
}

// Values of Status.Status
const (
	StatusSuccess = "success"
	StatusFailure = "failure"
	StatusWorking = "working"
)

// Operation information, as delivered to API clients.
type ServerOp struct {
	JSONBase `yaml:",inline" json:",inline"`
}

// Operation list, as delivered to API clients.
type ServerOpList struct {
	JSONBase `yaml:",inline" json:",inline"`
	Items    []ServerOp `yaml:"items,omitempty" json:"items,omitempty"`
}
<commit_msg>Change kublet to serve podInfo instead of containerInfo. Plumb through system.<commit_after>/*
Copyright 2014 Google Inc. All rights reserved.

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

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

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

package api

import (
	"github.com/fsouza/go-dockerclient"
)

// Common string formats
// ---------------------
// Many fields in this API have formatting requirements.  The commonly used
// formats are defined here.
//
// C_IDENTIFIER:  This is a string that conforms the definition of an "identifier"
//     in the C language.  This is captured by the following regex:
//         [A-Za-z_][A-Za-z0-9_]*
//     This defines the format, but not the length restriction, which should be
//     specified at the definition of any field of this type.
//
// DNS_LABEL:  This is a string that conforms to the definition of a "label"
//     in RFCs 1035 and 1123.  This is captured by the following regex:
//         [a-z0-9]([-a-z0-9]*[a-z0-9])?
//     This defines the format, but not the length restriction, which should be
//     specified at the definition of any field of this type.
//
//  DNS_SUBDOMAIN:  This is a string that conforms to the definition of a
//      "subdomain" in RFCs 1035 and 1123.  This is captured by the following regex:
//         [a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*
//     or more simply:
//         DNS_LABEL(\.DNS_LABEL)*
//     This defines the format, but not the length restriction, which should be
//     specified at the definition of any field of this type.

// ContainerManifest corresponds to the Container Manifest format, documented at:
// https://developers.google.com/compute/docs/containers/container_vms#container_manifest
// This is used as the representation of Kubernetes workloads.
type ContainerManifest struct {
	// Required: This must be a supported version string, such as "v1beta1".
	Version string `yaml:"version" json:"version"`
	// Required: This must be a DNS_SUBDOMAIN, 255 characters or less.
	ID         string      `yaml:"id" json:"id"`
	Volumes    []Volume    `yaml:"volumes" json:"volumes"`
	Containers []Container `yaml:"containers" json:"containers"`
}

// Volume represents a named volume in a pod that may be accessed by any containers in the pod.
type Volume struct {
	// Required: This must be a DNS_LABEL, 63 characters or less.  Each volume in a pod
	// must have a unique name.
	Name string `yaml:"name" json:"name"`
}

// Port represents a network port in a single container
type Port struct {
	// Optional: If specified, this must be a DNS_LABEL, 63 characters or less.  Each
	// container in a pod must have a unique name.
	Name string `yaml:"name,omitempty" json:"name,omitempty"`
	// Optional: Defaults to ContainerPort.
	HostPort int `yaml:"hostPort,omitempty" json:"hostPort,omitempty"`
	// Required: This must be a valid port number, 0 < x < 65536.
	ContainerPort int `yaml:"containerPort" json:"containerPort"`
	// Optional: Defaults to "TCP".
	Protocol string `yaml:"protocol,omitempty" json:"protocol,omitempty"`
}

// VolumeMount describes a mounting of a Volume within a container
type VolumeMount struct {
	// Required: This must match the Name of a Volume [above].
	Name string `yaml:"name" json:"name"`
	// Optional: Defaults to false (read-write).
	ReadOnly bool `yaml:"readOnly,omitempty" json:"readOnly,omitempty"`
	// Required.
	MountPath string `yaml:"mountPath,omitempty" json:"mountPath,omitempty"`
	// One of: "LOCAL" (local volume) or "HOST" (external mount from the host). Default: LOCAL.
	MountType string `yaml:"mountType,omitempty" json:"mountType,omitempty"`
}

// EnvVar represents an environment variable present in a Container
type EnvVar struct {
	// Required: This must be a C_IDENTIFIER.
	Name string `yaml:"name" json:"name"`
	// Optional: defaults to "".
	Value string `yaml:"value,omitempty" json:"value,omitempty"`
}

// Container represents a single container that is expected to be run on the host.
type Container struct {
	// Required: This must be a DNS_LABEL, 63 characters or less.  Each container in a
	// pod must have a unique name.
	Name string `yaml:"name" json:"name"`
	// Required.
	Image string `yaml:"image" json:"image"`
	// Optional: Defaults to whatever is defined in the image.
	Command []string `yaml:"command,omitempty" json:"command,omitempty"`
	// Optional: Defaults to Docker's default.
	WorkingDir string   `yaml:"workingDir,omitempty" json:"workingDir,omitempty"`
	Ports      []Port   `yaml:"ports,omitempty" json:"ports,omitempty"`
	Env        []EnvVar `yaml:"env,omitempty" json:"env,omitempty"`
	// Optional: Defaults to unlimited.
	Memory int `yaml:"memory,omitempty" json:"memory,omitempty"`
	// Optional: Defaults to unlimited.
	CPU          int           `yaml:"cpu,omitempty" json:"cpu,omitempty"`
	VolumeMounts []VolumeMount `yaml:"volumeMounts,omitempty" json:"volumeMounts,omitempty"`
}

// Percentile represents a pair which contains a percentage from 0 to 100 and
// its corresponding value.
type Percentile struct {
	Percentage int    `json:"percentage,omitempty"`
	Value      uint64 `json:"value,omitempty"`
}

// ContainerStats represents statistical information of a container
type ContainerStats struct {
	CpuUsagePercentiles    []Percentile `json:"cpu_usage_percentiles,omitempty"`
	MemoryUsagePercentiles []Percentile `json:"memory_usage_percentiles,omitempty"`
	MaxMemoryUsage         uint64       `json:"max_memory_usage,omitempty"`
}

// Event is the representation of an event logged to etcd backends
type Event struct {
	Event     string             `json:"event,omitempty"`
	Manifest  *ContainerManifest `json:"manifest,omitempty"`
	Container *Container         `json:"container,omitempty"`
	Timestamp int64              `json:"timestamp"`
}

// The below types are used by kube_client and api_server.

// JSONBase is shared by all objects sent to, or returned from the client
type JSONBase struct {
	Kind              string `json:"kind,omitempty" yaml:"kind,omitempty"`
	ID                string `json:"id,omitempty" yaml:"id,omitempty"`
	CreationTimestamp string `json:"creationTimestamp,omitempty" yaml:"creationTimestamp,omitempty"`
	SelfLink          string `json:"selfLink,omitempty" yaml:"selfLink,omitempty"`
}

type PodStatus string

const (
	PodRunning PodStatus = "Running"
	PodPending PodStatus = "Pending"
	PodStopped PodStatus = "Stopped"
)

// PodInfo contains one entry for every container with available info.
type PodInfo map[string]docker.Container

// PodState is the state of a pod, used as either input (desired state) or output (current state)
type PodState struct {
	Manifest ContainerManifest `json:"manifest,omitempty" yaml:"manifest,omitempty"`
	Status   PodStatus         `json:"status,omitempty" yaml:"status,omitempty"`
	Host     string            `json:"host,omitempty" yaml:"host,omitempty"`
	HostIP   string            `json:"hostIP,omitempty" yaml:"hostIP,omitempty"`

	// The key of this map is the *name* of the container within the manifest; it has one
	// entry per container in the manifest. The value of this map is currently the output
	// of `docker inspect`. This output format is *not* final and should not be relied
	// upon.
	// TODO: Make real decisions about what our info should look like.
	Info PodInfo `json:"info,omitempty" yaml:"info,omitempty"`
}

type PodList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Items    []Pod `json:"items" yaml:"items,omitempty"`
}

// Pod is a collection of containers, used as either input (create, update) or as output (list, get)
type Pod struct {
	JSONBase     `json:",inline" yaml:",inline"`
	Labels       map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
	DesiredState PodState          `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
	CurrentState PodState          `json:"currentState,omitempty" yaml:"currentState,omitempty"`
}

// ReplicationControllerState is the state of a replication controller, either input (create, update) or as output (list, get)
type ReplicationControllerState struct {
	Replicas        int               `json:"replicas" yaml:"replicas"`
	ReplicaSelector map[string]string `json:"replicaSelector,omitempty" yaml:"replicaSelector,omitempty"`
	PodTemplate     PodTemplate       `json:"podTemplate,omitempty" yaml:"podTemplate,omitempty"`
}

type ReplicationControllerList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Items    []ReplicationController `json:"items,omitempty" yaml:"items,omitempty"`
}

// ReplicationController represents the configuration of a replication controller
type ReplicationController struct {
	JSONBase     `json:",inline" yaml:",inline"`
	DesiredState ReplicationControllerState `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
	Labels       map[string]string          `json:"labels,omitempty" yaml:"labels,omitempty"`
}

// PodTemplate holds the information used for creating pods
type PodTemplate struct {
	DesiredState PodState          `json:"desiredState,omitempty" yaml:"desiredState,omitempty"`
	Labels       map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`
}

// ServiceList holds a list of services
type ServiceList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Items    []Service `json:"items" yaml:"items"`
}

// Defines a service abstraction by a name (for example, mysql) consisting of local port
// (for example 3306) that the proxy listens on, and the selector that determines which pods
// will answer requests sent through the proxy.
type Service struct {
	JSONBase `json:",inline" yaml:",inline"`
	Port     int `json:"port,omitempty" yaml:"port,omitempty"`

	// This service's labels.
	Labels map[string]string `json:"labels,omitempty" yaml:"labels,omitempty"`

	// This service will route traffic to pods having labels matching this selector.
	Selector                   map[string]string `json:"selector,omitempty" yaml:"selector,omitempty"`
	CreateExternalLoadBalancer bool              `json:"createExternalLoadBalancer,omitempty" yaml:"createExternalLoadBalancer,omitempty"`
}

// Defines the endpoints that implement the actual service, for example:
// Name: "mysql", Endpoints: ["10.10.1.1:1909", "10.10.2.2:8834"]
type Endpoints struct {
	Name      string
	Endpoints []string
}

// Information about a single Minion; the name of the minion according to etcd
// is in JSONBase.ID.
type Minion struct {
	JSONBase `json:",inline" yaml:",inline"`
	// Queried from cloud provider, if available.
	HostIP string `json:"hostIP,omitempty" yaml:"hostIP,omitempty"`
}

// A list of minions.
type MinionList struct {
	JSONBase `json:",inline" yaml:",inline"`
	Items    []Minion `json:"minions,omitempty" yaml:"minions,omitempty"`
}

// Status is a return value for calls that don't return other objects.
// Arguably, this could go in apiserver, but I'm including it here so clients needn't
// import both.
type Status struct {
	JSONBase `json:",inline" yaml:",inline"`
	// One of: "success", "failure", "working" (for operations not yet completed)
	// TODO: if "working", include an operation identifier so final status can be
	// checked.
	Status  string `json:"status,omitempty" yaml:"status,omitempty"`
	Details string `json:"details,omitempty" yaml:"details,omitempty"`
}

// Values of Status.Status
const (
	StatusSuccess = "success"
	StatusFailure = "failure"
	StatusWorking = "working"
)

// Operation information, as delivered to API clients.
type ServerOp struct {
	JSONBase `yaml:",inline" json:",inline"`
}

// Operation list, as delivered to API clients.
type ServerOpList struct {
	JSONBase `yaml:",inline" json:",inline"`
	Items    []ServerOp `yaml:"items,omitempty" json:"items,omitempty"`
}
<|endoftext|>


<commit_before>/*
Copyright The Helm 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 kube // import "helm.sh/helm/pkg/kube"

import (
	"fmt"
	"time"

	"github.com/pkg/errors"
	appsv1 "k8s.io/api/apps/v1"
	appsv1beta1 "k8s.io/api/apps/v1beta1"
	appsv1beta2 "k8s.io/api/apps/v1beta2"
	batchv1 "k8s.io/api/batch/v1"
	corev1 "k8s.io/api/core/v1"
	extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/kubernetes"
	deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
)

type waiter struct {
	c       kubernetes.Interface
	timeout time.Duration
	log     func(string, ...interface{})
}

// waitForResources polls to get the current status of all pods, PVCs, and Services
// until all are ready or a timeout is reached
func (w *waiter) waitForResources(created Result) error {
	w.log("beginning wait for %d resources with timeout of %v", len(created), w.timeout)

	return wait.Poll(2*time.Second, w.timeout, func() (bool, error) {
		for _, v := range created[:0] {
			var (
				ok  bool
				err error
			)
			switch value := asVersioned(v).(type) {
			case *corev1.Pod:
				pod, err := w.c.CoreV1().Pods(value.Namespace).Get(value.Name, metav1.GetOptions{})
				if err != nil || !w.isPodReady(pod) {
					return false, err
				}
			case *appsv1.Deployment:
				currentDeployment, err := w.c.AppsV1().Deployments(value.Namespace).Get(value.Name, metav1.GetOptions{})
				if err != nil {
					return false, err
				}
				// Find RS associated with deployment
				newReplicaSet, err := deploymentutil.GetNewReplicaSet(currentDeployment, w.c.AppsV1())
				if err != nil || newReplicaSet == nil {
					return false, err
				}
				if !w.deploymentReady(newReplicaSet, currentDeployment) {
					return false, nil
				}
			case *appsv1beta1.Deployment:
				currentDeployment, err := w.c.AppsV1().Deployments(value.Namespace).Get(value.Name, metav1.GetOptions{})
				if err != nil {
					return false, err
				}
				// Find RS associated with deployment
				newReplicaSet, err := deploymentutil.GetNewReplicaSet(currentDeployment, w.c.AppsV1())
				if err != nil || newReplicaSet == nil {
					return false, err
				}
				if !w.deploymentReady(newReplicaSet, currentDeployment) {
					return false, nil
				}
			case *appsv1beta2.Deployment:
				currentDeployment, err := w.c.AppsV1().Deployments(value.Namespace).Get(value.Name, metav1.GetOptions{})
				if err != nil {
					return false, err
				}
				// Find RS associated with deployment
				newReplicaSet, err := deploymentutil.GetNewReplicaSet(currentDeployment, w.c.AppsV1())
				if err != nil || newReplicaSet == nil {
					return false, err
				}
				if !w.deploymentReady(newReplicaSet, currentDeployment) {
					return false, nil
				}
			case *extensionsv1beta1.Deployment:
				currentDeployment, err := w.c.AppsV1().Deployments(value.Namespace).Get(value.Name, metav1.GetOptions{})
				if err != nil {
					return false, err
				}
				// Find RS associated with deployment
				newReplicaSet, err := deploymentutil.GetNewReplicaSet(currentDeployment, w.c.AppsV1())
				if err != nil || newReplicaSet == nil {
					return false, err
				}
				if !w.deploymentReady(newReplicaSet, currentDeployment) {
					return false, nil
				}
			case *corev1.PersistentVolumeClaim:
				claim, err := w.c.CoreV1().PersistentVolumeClaims(value.Namespace).Get(value.Name, metav1.GetOptions{})
				if err != nil {
					return false, err
				}
				if !w.volumeReady(claim) {
					return false, nil
				}
			case *corev1.Service:
				svc, err := w.c.CoreV1().Services(value.Namespace).Get(value.Name, metav1.GetOptions{})
				if err != nil {
					return false, err
				}
				if !w.serviceReady(svc) {
					return false, nil
				}
			case *corev1.ReplicationController:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *extensionsv1beta1.DaemonSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *appsv1.DaemonSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *appsv1beta2.DaemonSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *appsv1.StatefulSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *appsv1beta1.StatefulSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *appsv1beta2.StatefulSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *extensionsv1beta1.ReplicaSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *appsv1beta2.ReplicaSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *appsv1.ReplicaSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			}
			if !ok || err != nil {
				return false, err
			}
		}
		return true, nil
	})
}

func (w *waiter) podsReadyForObject(namespace string, obj runtime.Object) (bool, error) {
	pods, err := w.podsforObject(namespace, obj)
	if err != nil {
		return false, err
	}
	for _, pod := range pods {
		if !w.isPodReady(&pod) {
			return false, nil
		}
	}
	return true, nil
}

func (w *waiter) podsforObject(namespace string, obj runtime.Object) ([]corev1.Pod, error) {
	selector, err := selectorsForObject(obj)
	if err != nil {
		return nil, err
	}
	list, err := getPods(w.c, namespace, selector.String())
	return list, err
}

// isPodReady returns true if a pod is ready; false otherwise.
func (w *waiter) isPodReady(pod *corev1.Pod) bool {
	for _, c := range pod.Status.Conditions {
		if c.Type == corev1.PodReady && c.Status == corev1.ConditionTrue {
			return true
		}
	}
	w.log("Pod is not ready: %s/%s", pod.GetNamespace(), pod.GetName())
	return false
}

func (w *waiter) serviceReady(s *corev1.Service) bool {
	// ExternalName Services are external to cluster so helm shouldn't be checking to see if they're 'ready' (i.e. have an IP Set)
	if s.Spec.Type == corev1.ServiceTypeExternalName {
		return true
	}
	// Make sure the service is not explicitly set to "None" before checking the IP
	if s.Spec.ClusterIP != corev1.ClusterIPNone && !isServiceIPSet(s) ||
		// This checks if the service has a LoadBalancer and that balancer has an Ingress defined
		s.Spec.Type == corev1.ServiceTypeLoadBalancer && s.Status.LoadBalancer.Ingress == nil {
		w.log("Service is not ready: %s/%s", s.GetNamespace(), s.GetName())
		return false
	}
	return true
}

// isServiceIPSet aims to check if the service's ClusterIP is set or not
// the objective is not to perform validation here
func isServiceIPSet(service *corev1.Service) bool {
	return service.Spec.ClusterIP != corev1.ClusterIPNone && service.Spec.ClusterIP != ""
}

func (w *waiter) volumeReady(v *corev1.PersistentVolumeClaim) bool {
	if v.Status.Phase != corev1.ClaimBound {
		w.log("PersistentVolumeClaim is not ready: %s/%s", v.GetNamespace(), v.GetName())
		return false
	}
	return true
}

func (w *waiter) deploymentReady(replicaSet *appsv1.ReplicaSet, deployment *appsv1.Deployment) bool {
	if !(replicaSet.Status.ReadyReplicas >= *deployment.Spec.Replicas-deploymentutil.MaxUnavailable(*deployment)) {
		w.log("Deployment is not ready: %s/%s", deployment.GetNamespace(), deployment.GetName())
		return false
	}
	return true
}

func getPods(client kubernetes.Interface, namespace, selector string) ([]corev1.Pod, error) {
	list, err := client.CoreV1().Pods(namespace).List(metav1.ListOptions{
		LabelSelector: selector,
	})
	return list.Items, err
}

// selectorsForObject returns the pod label selector for a given object
//
// Modified version of https://github.com/kubernetes/kubernetes/blob/v1.14.1/pkg/kubectl/polymorphichelpers/helpers.go#L84
func selectorsForObject(object runtime.Object) (selector labels.Selector, err error) {
	switch t := object.(type) {
	case *extensionsv1beta1.ReplicaSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1.ReplicaSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1beta2.ReplicaSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *corev1.ReplicationController:
		selector = labels.SelectorFromSet(t.Spec.Selector)
	case *appsv1.StatefulSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1beta1.StatefulSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1beta2.StatefulSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *extensionsv1beta1.DaemonSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1.DaemonSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1beta2.DaemonSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *extensionsv1beta1.Deployment:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1.Deployment:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1beta1.Deployment:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1beta2.Deployment:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *batchv1.Job:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *corev1.Service:
		if t.Spec.Selector == nil || len(t.Spec.Selector) == 0 {
			return nil, fmt.Errorf("invalid service '%s': Service is defined without a selector", t.Name)
		}
		selector = labels.SelectorFromSet(t.Spec.Selector)

	default:
		return nil, fmt.Errorf("selector for %T not implemented", object)
	}

	return selector, errors.Wrap(err, "invalid label selector")
}
<commit_msg>fix(pkg/kube): Fixes wait functionality<commit_after>/*
Copyright The Helm 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 kube // import "helm.sh/helm/pkg/kube"

import (
	"fmt"
	"time"

	"github.com/pkg/errors"
	appsv1 "k8s.io/api/apps/v1"
	appsv1beta1 "k8s.io/api/apps/v1beta1"
	appsv1beta2 "k8s.io/api/apps/v1beta2"
	batchv1 "k8s.io/api/batch/v1"
	corev1 "k8s.io/api/core/v1"
	extensionsv1beta1 "k8s.io/api/extensions/v1beta1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/util/wait"
	"k8s.io/client-go/kubernetes"
	deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
)

type waiter struct {
	c       kubernetes.Interface
	timeout time.Duration
	log     func(string, ...interface{})
}

// waitForResources polls to get the current status of all pods, PVCs, and Services
// until all are ready or a timeout is reached
func (w *waiter) waitForResources(created Result) error {
	w.log("beginning wait for %d resources with timeout of %v", len(created), w.timeout)

	return wait.Poll(2*time.Second, w.timeout, func() (bool, error) {
		for _, v := range created {
			var (
				// This defaults to true, otherwise we get to a point where
				// things will always return false unless one of the objects
				// that manages pods has been hit
				ok  = true
				err error
			)
			switch value := asVersioned(v).(type) {
			case *corev1.Pod:
				pod, err := w.c.CoreV1().Pods(value.Namespace).Get(value.Name, metav1.GetOptions{})
				if err != nil || !w.isPodReady(pod) {
					return false, err
				}
			case *appsv1.Deployment:
				currentDeployment, err := w.c.AppsV1().Deployments(value.Namespace).Get(value.Name, metav1.GetOptions{})
				if err != nil {
					return false, err
				}
				// Find RS associated with deployment
				newReplicaSet, err := deploymentutil.GetNewReplicaSet(currentDeployment, w.c.AppsV1())
				if err != nil || newReplicaSet == nil {
					return false, err
				}
				if !w.deploymentReady(newReplicaSet, currentDeployment) {
					return false, nil
				}
			case *appsv1beta1.Deployment:
				currentDeployment, err := w.c.AppsV1().Deployments(value.Namespace).Get(value.Name, metav1.GetOptions{})
				if err != nil {
					return false, err
				}
				// Find RS associated with deployment
				newReplicaSet, err := deploymentutil.GetNewReplicaSet(currentDeployment, w.c.AppsV1())
				if err != nil || newReplicaSet == nil {
					return false, err
				}
				if !w.deploymentReady(newReplicaSet, currentDeployment) {
					return false, nil
				}
			case *appsv1beta2.Deployment:
				currentDeployment, err := w.c.AppsV1().Deployments(value.Namespace).Get(value.Name, metav1.GetOptions{})
				if err != nil {
					return false, err
				}
				// Find RS associated with deployment
				newReplicaSet, err := deploymentutil.GetNewReplicaSet(currentDeployment, w.c.AppsV1())
				if err != nil || newReplicaSet == nil {
					return false, err
				}
				if !w.deploymentReady(newReplicaSet, currentDeployment) {
					return false, nil
				}
			case *extensionsv1beta1.Deployment:
				currentDeployment, err := w.c.AppsV1().Deployments(value.Namespace).Get(value.Name, metav1.GetOptions{})
				if err != nil {
					return false, err
				}
				// Find RS associated with deployment
				newReplicaSet, err := deploymentutil.GetNewReplicaSet(currentDeployment, w.c.AppsV1())
				if err != nil || newReplicaSet == nil {
					return false, err
				}
				if !w.deploymentReady(newReplicaSet, currentDeployment) {
					return false, nil
				}
			case *corev1.PersistentVolumeClaim:
				claim, err := w.c.CoreV1().PersistentVolumeClaims(value.Namespace).Get(value.Name, metav1.GetOptions{})
				if err != nil {
					return false, err
				}
				if !w.volumeReady(claim) {
					return false, nil
				}
			case *corev1.Service:
				svc, err := w.c.CoreV1().Services(value.Namespace).Get(value.Name, metav1.GetOptions{})
				if err != nil {
					return false, err
				}
				if !w.serviceReady(svc) {
					return false, nil
				}
			case *corev1.ReplicationController:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			// TODO(Taylor): This works, but ends up with a possible race
			// condition if some pods have not been scheduled yet. This logic
			// should be refactored to do similar checks to what is done for
			// Deployments
			case *extensionsv1beta1.DaemonSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *appsv1.DaemonSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *appsv1beta2.DaemonSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *appsv1.StatefulSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *appsv1beta1.StatefulSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *appsv1beta2.StatefulSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *extensionsv1beta1.ReplicaSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *appsv1beta2.ReplicaSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			case *appsv1.ReplicaSet:
				ok, err = w.podsReadyForObject(value.Namespace, value)
			}
			if !ok || err != nil {
				return false, err
			}
		}
		return true, nil
	})
}

func (w *waiter) podsReadyForObject(namespace string, obj runtime.Object) (bool, error) {
	pods, err := w.podsforObject(namespace, obj)
	if err != nil {
		return false, err
	}
	for _, pod := range pods {
		if !w.isPodReady(&pod) {
			return false, nil
		}
	}
	return true, nil
}

func (w *waiter) podsforObject(namespace string, obj runtime.Object) ([]corev1.Pod, error) {
	selector, err := selectorsForObject(obj)
	if err != nil {
		return nil, err
	}
	list, err := getPods(w.c, namespace, selector.String())
	return list, err
}

// isPodReady returns true if a pod is ready; false otherwise.
func (w *waiter) isPodReady(pod *corev1.Pod) bool {
	for _, c := range pod.Status.Conditions {
		if c.Type == corev1.PodReady && c.Status == corev1.ConditionTrue {
			return true
		}
	}
	w.log("Pod is not ready: %s/%s", pod.GetNamespace(), pod.GetName())
	return false
}

func (w *waiter) serviceReady(s *corev1.Service) bool {
	// ExternalName Services are external to cluster so helm shouldn't be checking to see if they're 'ready' (i.e. have an IP Set)
	if s.Spec.Type == corev1.ServiceTypeExternalName {
		return true
	}

	// Make sure the service is not explicitly set to "None" before checking the IP
	if (s.Spec.ClusterIP != corev1.ClusterIPNone && s.Spec.ClusterIP == "") ||
		// This checks if the service has a LoadBalancer and that balancer has an Ingress defined
		(s.Spec.Type == corev1.ServiceTypeLoadBalancer && s.Status.LoadBalancer.Ingress == nil) {
		w.log("Service is not ready: %s/%s", s.GetNamespace(), s.GetName())
		return false
	}
	return true
}

func (w *waiter) volumeReady(v *corev1.PersistentVolumeClaim) bool {
	if v.Status.Phase != corev1.ClaimBound {
		w.log("PersistentVolumeClaim is not ready: %s/%s", v.GetNamespace(), v.GetName())
		return false
	}
	return true
}

func (w *waiter) deploymentReady(replicaSet *appsv1.ReplicaSet, deployment *appsv1.Deployment) bool {
	if !(replicaSet.Status.ReadyReplicas >= *deployment.Spec.Replicas-deploymentutil.MaxUnavailable(*deployment)) {
		w.log("Deployment is not ready: %s/%s", deployment.GetNamespace(), deployment.GetName())
		return false
	}
	return true
}

func getPods(client kubernetes.Interface, namespace, selector string) ([]corev1.Pod, error) {
	list, err := client.CoreV1().Pods(namespace).List(metav1.ListOptions{
		LabelSelector: selector,
	})
	return list.Items, err
}

// selectorsForObject returns the pod label selector for a given object
//
// Modified version of https://github.com/kubernetes/kubernetes/blob/v1.14.1/pkg/kubectl/polymorphichelpers/helpers.go#L84
func selectorsForObject(object runtime.Object) (selector labels.Selector, err error) {
	switch t := object.(type) {
	case *extensionsv1beta1.ReplicaSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1.ReplicaSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1beta2.ReplicaSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *corev1.ReplicationController:
		selector = labels.SelectorFromSet(t.Spec.Selector)
	case *appsv1.StatefulSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1beta1.StatefulSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1beta2.StatefulSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *extensionsv1beta1.DaemonSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1.DaemonSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1beta2.DaemonSet:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *extensionsv1beta1.Deployment:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1.Deployment:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1beta1.Deployment:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *appsv1beta2.Deployment:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *batchv1.Job:
		selector, err = metav1.LabelSelectorAsSelector(t.Spec.Selector)
	case *corev1.Service:
		if t.Spec.Selector == nil || len(t.Spec.Selector) == 0 {
			return nil, fmt.Errorf("invalid service '%s': Service is defined without a selector", t.Name)
		}
		selector = labels.SelectorFromSet(t.Spec.Selector)

	default:
		return nil, fmt.Errorf("selector for %T not implemented", object)
	}

	return selector, errors.Wrap(err, "invalid label selector")
}
<|endoftext|>


<commit_before>// errchk $G -e $D/$F.go

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

package main

func main() {
	x := ""
	x = +"hello"  // ERROR "invalid operation.*string"
	x = +x  // ERROR "invalid operation.*string"
}
<commit_msg>test: match gccgo error messages for bug330.go.<commit_after>// errchk $G -e $D/$F.go

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

package main

func main() {
	x := ""
	x = +"hello"  // ERROR "invalid operation.*string|expected numeric"
	x = +x  // ERROR "invalid operation.*string|expected numeric"
}
<|endoftext|>


<commit_before>package ui

import (
	"net/http"

	"github.com/gorilla/mux"
	"github.com/rancher/apiserver/pkg/parse"
	"github.com/rancher/rancher/pkg/cacerts"
	v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3"
)

func New(prefs v3.PreferenceCache, clusterRegistrationTokenCache v3.ClusterRegistrationTokenCache) http.Handler {
	router := mux.NewRouter()
	router.UseEncodedPath()

	router.Handle("/", vue.IndexFile())
	router.Handle("/cacerts", cacerts.Handler(clusterRegistrationTokenCache))
	router.Handle("/asset-manifest.json", ember.ServeAsset())
	router.Handle("/crossdomain.xml", ember.ServeAsset())
	router.Handle("/dashboard", http.RedirectHandler("/dashboard/", http.StatusFound))
	router.Handle("/dashboard/", vue.IndexFile())
	router.Handle("/humans.txt", ember.ServeAsset())
	router.Handle("/index.txt", ember.ServeAsset())
	router.Handle("/robots.txt", ember.ServeAsset())
	router.Handle("/VERSION.txt", ember.ServeAsset())
	router.Handle("/favicon.png", vue.ServeFaviconDashboard())
	router.Handle("/favicon.ico", vue.ServeFaviconDashboard())
	router.Path("/verify-auth-azure").Queries("state", "{state}").HandlerFunc(redirectAuth)
	router.Path("/verify-auth").Queries("state", "{state}").HandlerFunc(redirectAuth)
	router.PathPrefix("/api-ui").Handler(ember.ServeAsset())
	router.PathPrefix("/assets/rancher-ui-driver-linode").Handler(emberAlwaysOffline.ServeAsset())
	router.PathPrefix("/assets").Handler(ember.ServeAsset())
	router.PathPrefix("/dashboard/").Handler(vue.IndexFileOnNotFound())
	router.PathPrefix("/ember-fetch").Handler(ember.ServeAsset())
	router.PathPrefix("/engines-dist").Handler(ember.ServeAsset())
	router.PathPrefix("/static").Handler(ember.ServeAsset())
	router.PathPrefix("/translations").Handler(ember.ServeAsset())
	router.PathPrefix("/g").Handler(ember.IndexFile())
	router.NotFoundHandler = vueIndexUnlessAPI()

	return router
}

func vueIndexUnlessAPI() http.Handler {
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		if parse.IsBrowser(req, true) {
			vueIndex.ServeHTTP(rw, req)
		} else {
			http.NotFound(rw, req)
		}
	})
}
<commit_msg>Revert "Route /g* to ember index"<commit_after>package ui

import (
	"net/http"

	"github.com/gorilla/mux"
	"github.com/rancher/apiserver/pkg/parse"
	"github.com/rancher/rancher/pkg/cacerts"
	v3 "github.com/rancher/rancher/pkg/generated/controllers/management.cattle.io/v3"
)

func New(prefs v3.PreferenceCache, clusterRegistrationTokenCache v3.ClusterRegistrationTokenCache) http.Handler {
	router := mux.NewRouter()
	router.UseEncodedPath()

	router.Handle("/", vue.IndexFile())
	router.Handle("/cacerts", cacerts.Handler(clusterRegistrationTokenCache))
	router.Handle("/asset-manifest.json", ember.ServeAsset())
	router.Handle("/crossdomain.xml", ember.ServeAsset())
	router.Handle("/dashboard", http.RedirectHandler("/dashboard/", http.StatusFound))
	router.Handle("/dashboard/", vue.IndexFile())
	router.Handle("/humans.txt", ember.ServeAsset())
	router.Handle("/index.txt", ember.ServeAsset())
	router.Handle("/robots.txt", ember.ServeAsset())
	router.Handle("/VERSION.txt", ember.ServeAsset())
	router.Handle("/favicon.png", vue.ServeFaviconDashboard())
	router.Handle("/favicon.ico", vue.ServeFaviconDashboard())
	router.Path("/verify-auth-azure").Queries("state", "{state}").HandlerFunc(redirectAuth)
	router.Path("/verify-auth").Queries("state", "{state}").HandlerFunc(redirectAuth)
	router.PathPrefix("/api-ui").Handler(ember.ServeAsset())
	router.PathPrefix("/assets/rancher-ui-driver-linode").Handler(emberAlwaysOffline.ServeAsset())
	router.PathPrefix("/assets").Handler(ember.ServeAsset())
	router.PathPrefix("/dashboard/").Handler(vue.IndexFileOnNotFound())
	router.PathPrefix("/ember-fetch").Handler(ember.ServeAsset())
	router.PathPrefix("/engines-dist").Handler(ember.ServeAsset())
	router.PathPrefix("/static").Handler(ember.ServeAsset())
	router.PathPrefix("/translations").Handler(ember.ServeAsset())
	router.NotFoundHandler = vueIndexUnlessAPI()

	return router
}

func vueIndexUnlessAPI() http.Handler {
	return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		if parse.IsBrowser(req, true) {
			vueIndex.ServeHTTP(rw, req)
		} else {
			http.NotFound(rw, req)
		}
	})
}
<|endoftext|>


<commit_before>// compile

// Copyright 2012 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.

// Used to crash compiler in interface type equality check.

package p

type i1 interface {
      F() interface{i1}
}

type i2 interface {
      F() interface{i2}
}

var v1 i1
var v2 i2

func f() bool {
       return v1 == v2
}

// TODO(gri) Change test to use exported interfaces.
// See issue #15596 for details.<commit_msg>test: restore fixedbugs/bug398.go to original version<commit_after>// compile

// Copyright 2012 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.

// Used to crash compiler in interface type equality check.
// (This test used to have problems - see #15596.)

package p

// exported interfaces

type I1 interface {
      F() interface{I1}
}

type I2 interface {
      F() interface{I2}
}

var V1 I1
var V2 I2

func F() bool {
       return V1 == V2
}

// non-exported interfaces

type i1 interface {
      F() interface{i1}
}

type i2 interface {
      F() interface{i2}
}

var v1 i1
var v2 i2

func f() bool {
       return v1 == v2
}
<|endoftext|>


<commit_before>package check

import (

	"net/http"
	"techtraits.com/klaxon/router"
)

func init() {
	router.Register("/rest/internal/check/{project_id}", router.POST, nil, nil, getTick)
}

func getTick(request router.Request) (int, []byte) {

	return http.StatusOK, nil

}
<commit_msg>Fixing format<commit_after>package check

import (
	"net/http"
	"techtraits.com/klaxon/router"
)

func init() {
	router.Register("/rest/internal/check/{project_id}", router.POST, nil, nil, getTick)
}

func getTick(request router.Request) (int, []byte) {

	return http.StatusOK, nil

}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"sync"

	"github.com/litl/galaxy/log"
)

var (
	ErrNoService        = fmt.Errorf("service does not exist")
	ErrNoBackend        = fmt.Errorf("backend does not exist")
	ErrDuplicateService = fmt.Errorf("service already exists")
	ErrDuplicateBackend = fmt.Errorf("backend already exists")
)

// marshal whatever we've got with out default indentation
// swallowing errors.
func marshal(i interface{}) []byte {
	jsonBytes, err := json.MarshalIndent(i, "", "  ")
	if err != nil {
		log.Println("error encoding json:", err)
	}
	return append(jsonBytes, '\n')
}

// ServiceRegistry is a global container for all configured services.
type ServiceRegistry struct {
	sync.Mutex
	svcs map[string]*Service
}

func (s *ServiceRegistry) GetService(name string) *Service {
	s.Lock()
	defer s.Unlock()
	return s.svcs[name]
}

// Add a new service to the Registry.
// Do not replace an existing service.
func (s *ServiceRegistry) AddService(cfg ServiceConfig) error {
	s.Lock()
	defer s.Unlock()

	log.Debug("Adding service:", cfg.Name)
	if _, ok := s.svcs[cfg.Name]; ok {
		log.Debug("Service already exists:", cfg.Name)
		return ErrDuplicateService
	}

	service := NewService(cfg)
	s.svcs[service.Name] = service

	return service.start()
}

// Replace the service's configuration, or update its list of backends.
// Replacing a configuration will shutdown the existing service, and start a
// new one, which will cause the listening socket to be temporarily
// unavailable.
func (s *ServiceRegistry) UpdateService(newCfg ServiceConfig, backendsOnly bool) error {
	s.Lock()
	defer s.Unlock()

	log.Debug("Updating Service:", newCfg.Name)
	service, ok := s.svcs[newCfg.Name]
	if !ok {
		log.Debug("Service not found:", newCfg.Name)
		return ErrNoService
	}

	currentCfg := service.Config()

	// if we're not doing only the backends, just wipe the service and start fresh.
	// No need to stop the service if nothing has changed though.
	if !backendsOnly && !currentCfg.Equal(newCfg) {
		log.Debug("Replacing Service:", service.Name)
		delete(s.svcs, service.Name)
		service.stop()

		service = NewService(newCfg)
		s.svcs[service.Name] = service
		return service.start()
	}

	// Lots of looping here (including fetching the Config, but the cardinality
	// of Backends shouldn't be very large, and the default RoundRobin balancing
	// is much simpler with a slice.

	// we're going to update just the backends for this config
	// get a map of what's already running
	currentBackends := make(map[string]BackendConfig)
	for _, backendCfg := range currentCfg.Backends {
		currentBackends[backendCfg.Name] = backendCfg
	}

	// Keep existing backends when they have equivalent config.
	// Update changed backends, and add new ones.
	for _, newBackend := range newCfg.Backends {
		current, ok := currentBackends[newBackend.Name]
		if ok && current.Equal(newBackend) {
			log.Debugf("Backend %s/%s unchanged", service.Name, current.Name)
			// no change for this one
			delete(currentBackends, current.Name)
			continue
		}

		log.Debugf("Adding Backend %s/%s", service.Name, current.Name)
		service.add(NewBackend(current))
		delete(currentBackends, current.Name)
	}

	// remove any left over backends
	for name := range currentBackends {
		log.Debugf("Removing Backend %s/%s", service.Name, name)
		service.remove(name)
	}
	return nil
}

func (s *ServiceRegistry) RemoveService(name string) error {
	s.Lock()
	defer s.Unlock()

	svc, ok := s.svcs[name]
	if ok {
		log.Debugf("Removing Service %s", svc.Name)
		delete(s.svcs, name)
		svc.stop()
		return nil
	}
	return ErrNoService
}

func (s *ServiceRegistry) ServiceStats(serviceName string) (ServiceStat, error) {
	s.Lock()
	defer s.Unlock()

	service, ok := s.svcs[serviceName]
	if !ok {
		return ServiceStat{}, ErrNoService
	}
	return service.Stats(), nil
}

func (s *ServiceRegistry) ServiceConfig(serviceName string) (ServiceConfig, error) {
	s.Lock()
	defer s.Unlock()

	service, ok := s.svcs[serviceName]
	if !ok {
		return ServiceConfig{}, ErrNoService
	}
	return service.Config(), nil
}

func (s *ServiceRegistry) BackendStats(serviceName, backendName string) (BackendStat, error) {
	s.Lock()
	defer s.Unlock()

	service, ok := s.svcs[serviceName]
	if !ok {
		return BackendStat{}, ErrNoService
	}

	for _, backend := range service.Backends {
		if backendName == backend.Name {
			return backend.Stats(), nil
		}
	}
	return BackendStat{}, ErrNoBackend
}

// Add or update a Backend on an existing Service.
func (s *ServiceRegistry) AddBackend(svcName string, backendCfg BackendConfig) error {
	s.Lock()
	defer s.Unlock()

	service, ok := s.svcs[svcName]
	if !ok {
		return ErrNoService
	}

	log.Debugf("Adding Backend %s/%s", service.Name, backendCfg.Name)
	service.add(NewBackend(backendCfg))
	return nil
}

// Remove a Backend from an existing Service.
func (s *ServiceRegistry) RemoveBackend(svcName, backendName string) error {
	s.Lock()
	defer s.Unlock()

	log.Debugf("Removing Backend %s/%s", svcName, backendName)
	service, ok := s.svcs[svcName]
	if !ok {
		return ErrNoService
	}

	if !service.remove(backendName) {
		return ErrNoBackend
	}
	return nil
}

func (s *ServiceRegistry) Stats() []ServiceStat {
	s.Lock()
	defer s.Unlock()

	var stats []ServiceStat
	for _, service := range s.svcs {
		stats = append(stats, service.Stats())
	}

	return stats
}

func (s *ServiceRegistry) Config() []ServiceConfig {
	s.Lock()
	defer s.Unlock()

	var configs []ServiceConfig
	for _, service := range s.svcs {
		configs = append(configs, service.Config())
	}

	return configs
}

func (s *ServiceRegistry) String() string {
	return string(marshal(s.Config()))
}
<commit_msg>Don't return "null" for empty stats request<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"sync"

	"github.com/litl/galaxy/log"
)

var (
	ErrNoService        = fmt.Errorf("service does not exist")
	ErrNoBackend        = fmt.Errorf("backend does not exist")
	ErrDuplicateService = fmt.Errorf("service already exists")
	ErrDuplicateBackend = fmt.Errorf("backend already exists")
)

// marshal whatever we've got with out default indentation
// swallowing errors.
func marshal(i interface{}) []byte {
	jsonBytes, err := json.MarshalIndent(i, "", "  ")
	if err != nil {
		log.Println("error encoding json:", err)
	}
	return append(jsonBytes, '\n')
}

// ServiceRegistry is a global container for all configured services.
type ServiceRegistry struct {
	sync.Mutex
	svcs map[string]*Service
}

func (s *ServiceRegistry) GetService(name string) *Service {
	s.Lock()
	defer s.Unlock()
	return s.svcs[name]
}

// Add a new service to the Registry.
// Do not replace an existing service.
func (s *ServiceRegistry) AddService(cfg ServiceConfig) error {
	s.Lock()
	defer s.Unlock()

	log.Debug("Adding service:", cfg.Name)
	if _, ok := s.svcs[cfg.Name]; ok {
		log.Debug("Service already exists:", cfg.Name)
		return ErrDuplicateService
	}

	service := NewService(cfg)
	s.svcs[service.Name] = service

	return service.start()
}

// Replace the service's configuration, or update its list of backends.
// Replacing a configuration will shutdown the existing service, and start a
// new one, which will cause the listening socket to be temporarily
// unavailable.
func (s *ServiceRegistry) UpdateService(newCfg ServiceConfig, backendsOnly bool) error {
	s.Lock()
	defer s.Unlock()

	log.Debug("Updating Service:", newCfg.Name)
	service, ok := s.svcs[newCfg.Name]
	if !ok {
		log.Debug("Service not found:", newCfg.Name)
		return ErrNoService
	}

	currentCfg := service.Config()

	// if we're not doing only the backends, just wipe the service and start fresh.
	// No need to stop the service if nothing has changed though.
	if !backendsOnly && !currentCfg.Equal(newCfg) {
		log.Debug("Replacing Service:", service.Name)
		delete(s.svcs, service.Name)
		service.stop()

		service = NewService(newCfg)
		s.svcs[service.Name] = service
		return service.start()
	}

	// Lots of looping here (including fetching the Config, but the cardinality
	// of Backends shouldn't be very large, and the default RoundRobin balancing
	// is much simpler with a slice.

	// we're going to update just the backends for this config
	// get a map of what's already running
	currentBackends := make(map[string]BackendConfig)
	for _, backendCfg := range currentCfg.Backends {
		currentBackends[backendCfg.Name] = backendCfg
	}

	// Keep existing backends when they have equivalent config.
	// Update changed backends, and add new ones.
	for _, newBackend := range newCfg.Backends {
		current, ok := currentBackends[newBackend.Name]
		if ok && current.Equal(newBackend) {
			log.Debugf("Backend %s/%s unchanged", service.Name, current.Name)
			// no change for this one
			delete(currentBackends, current.Name)
			continue
		}

		log.Debugf("Adding Backend %s/%s", service.Name, current.Name)
		service.add(NewBackend(current))
		delete(currentBackends, current.Name)
	}

	// remove any left over backends
	for name := range currentBackends {
		log.Debugf("Removing Backend %s/%s", service.Name, name)
		service.remove(name)
	}
	return nil
}

func (s *ServiceRegistry) RemoveService(name string) error {
	s.Lock()
	defer s.Unlock()

	svc, ok := s.svcs[name]
	if ok {
		log.Debugf("Removing Service %s", svc.Name)
		delete(s.svcs, name)
		svc.stop()
		return nil
	}
	return ErrNoService
}

func (s *ServiceRegistry) ServiceStats(serviceName string) (ServiceStat, error) {
	s.Lock()
	defer s.Unlock()

	service, ok := s.svcs[serviceName]
	if !ok {
		return ServiceStat{}, ErrNoService
	}
	return service.Stats(), nil
}

func (s *ServiceRegistry) ServiceConfig(serviceName string) (ServiceConfig, error) {
	s.Lock()
	defer s.Unlock()

	service, ok := s.svcs[serviceName]
	if !ok {
		return ServiceConfig{}, ErrNoService
	}
	return service.Config(), nil
}

func (s *ServiceRegistry) BackendStats(serviceName, backendName string) (BackendStat, error) {
	s.Lock()
	defer s.Unlock()

	service, ok := s.svcs[serviceName]
	if !ok {
		return BackendStat{}, ErrNoService
	}

	for _, backend := range service.Backends {
		if backendName == backend.Name {
			return backend.Stats(), nil
		}
	}
	return BackendStat{}, ErrNoBackend
}

// Add or update a Backend on an existing Service.
func (s *ServiceRegistry) AddBackend(svcName string, backendCfg BackendConfig) error {
	s.Lock()
	defer s.Unlock()

	service, ok := s.svcs[svcName]
	if !ok {
		return ErrNoService
	}

	log.Debugf("Adding Backend %s/%s", service.Name, backendCfg.Name)
	service.add(NewBackend(backendCfg))
	return nil
}

// Remove a Backend from an existing Service.
func (s *ServiceRegistry) RemoveBackend(svcName, backendName string) error {
	s.Lock()
	defer s.Unlock()

	log.Debugf("Removing Backend %s/%s", svcName, backendName)
	service, ok := s.svcs[svcName]
	if !ok {
		return ErrNoService
	}

	if !service.remove(backendName) {
		return ErrNoBackend
	}
	return nil
}

func (s *ServiceRegistry) Stats() []ServiceStat {
	s.Lock()
	defer s.Unlock()

	stats := []ServiceStat{}
	for _, service := range s.svcs {
		stats = append(stats, service.Stats())
	}

	return stats
}

func (s *ServiceRegistry) Config() []ServiceConfig {
	s.Lock()
	defer s.Unlock()

	var configs []ServiceConfig
	for _, service := range s.svcs {
		configs = append(configs, service.Config())
	}

	return configs
}

func (s *ServiceRegistry) String() string {
	return string(marshal(s.Config()))
}
<|endoftext|>


<commit_before>package main

import (
	"reflect"
	"testing"
)

func TestInit(t *testing.T) {
	cases := []struct {
		before *Playlist
		want   *Playlist
	}{
		{
			InitPlaylist(),
			&Playlist{
				[]*PlaylistItem{},
				-1,
			},
		},
	}

	for _, c := range cases {
		if !reflect.DeepEqual(c.before, c.want) {
			t.Errorf("TestInit: %q != %q", c.before, c.want)
		}
	}
}

func TestEnqueue(t *testing.T) {
	cases := []struct {
		before      *Playlist
		item        *PlaylistItem
		index       int
		want        *Playlist
		shoulderror bool
	}{
		{
			InitPlaylist(),
			&PlaylistItem{"I am lorde ya ya ya", "aaa", true},
			0,
			&Playlist{
				[]*PlaylistItem{
					&PlaylistItem{"I am lorde ya ya ya", "aaa", true},
				},
				-1,
			},
			false,
		},
		// Test invalid index
		{
			InitPlaylist(),
			&PlaylistItem{"I am lorde ya ya ya", "aaa", true},
			1,
			&Playlist{
				[]*PlaylistItem{
					&PlaylistItem{"I am lorde ya ya ya", "aaa", true},
				},
				-1,
			},
			true,
		},
	}

	for caseno, c := range cases {
		_, err := c.before.Enqueue(c.index, c.item)
		if c.shoulderror != (err != nil) {
			if err != nil {
				t.Errorf("TestEnqueue: case %d returned err when should be nil(%s)", caseno, err.Error())
			} else {
				t.Errorf("TestEnqueue: case %d returned nil when should be err", caseno)
			}
		}
		if !reflect.DeepEqual(c.before, c.want) {
			t.Errorf("TestEnqueue: %q != %q", c.before, c.want)
		}
	}
}
<commit_msg>Fix test and add slightly more realistic data<commit_after>package main

import (
	"reflect"
	"testing"
)

func TestInit(t *testing.T) {
	cases := []struct {
		before *Playlist
		want   *Playlist
	}{
		{
			InitPlaylist(),
			&Playlist{
				[]*PlaylistItem{},
				-1,
			},
		},
	}

	for _, c := range cases {
		if !reflect.DeepEqual(c.before, c.want) {
			t.Errorf("TestInit: %q != %q", c.before, c.want)
		}
	}
}

func TestEnqueue(t *testing.T) {
	cases := []struct {
		before      *Playlist
		item        *PlaylistItem
		index       int
		want        *Playlist
		shoulderror bool
	}{
		{
			InitPlaylist(),
			&PlaylistItem{"/Music/theballadofbilbobaggins.mp3", "aaa", true},
			0,
			&Playlist{
				[]*PlaylistItem{
					&PlaylistItem{"/Music/theballadofbilbobaggins.mp3", "aaa", true},
				},
				-1,
			},
			false,
		},
		// Test invalid index
		{
			InitPlaylist(),
			&PlaylistItem{"/Music/iamlordeyayaya.wav", "aaa", true},
			1,
			&Playlist{
				[]*PlaylistItem{},
				-1,
			},
			true,
		},
	}

	for caseno, c := range cases {
		_, err := c.before.Enqueue(c.index, c.item)
		if c.shoulderror != (err != nil) {
			if err != nil {
				t.Errorf("TestEnqueue: case %d returned err when should be nil(%s)", caseno, err.Error())
			} else {
				t.Errorf("TestEnqueue: case %d returned nil when should be err", caseno)
			}
		}
		if !reflect.DeepEqual(c.before, c.want) {
			t.Errorf("TestEnqueue: %q != %q", c.before, c.want)
		}
	}
}
<|endoftext|>


<commit_before>//  Copyright (c) 2014 Couchbase, 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 test

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"math"
	"os"
	"path/filepath"
	"reflect"
	"regexp"
	"testing"

	"github.com/blevesearch/bleve"
	"github.com/blevesearch/bleve/mapping"

	// allow choosing alternate kvstores
	_ "github.com/blevesearch/bleve/config"
)

var dataset = flag.String("dataset", "", "only test datasets matching this regex")
var onlynum = flag.Int("testnum", -1, "only run the test with this number")
var keepIndex = flag.Bool("keepIndex", false, "keep the index after testing")

var indexType = flag.String("indexType", bleve.Config.DefaultIndexType, "index type to build")
var kvType = flag.String("kvType", bleve.Config.DefaultKVStore, "kv store type to build")

func TestIntegration(t *testing.T) {

	flag.Parse()

	bleve.Config.DefaultIndexType = *indexType
	bleve.Config.DefaultKVStore = *kvType
	t.Logf("using index type %s and kv type %s", *indexType, *kvType)

	var err error
	var datasetRegexp *regexp.Regexp
	if *dataset != "" {
		datasetRegexp, err = regexp.Compile(*dataset)
		if err != nil {
			t.Fatal(err)
		}
	}

	fis, err := ioutil.ReadDir("tests")
	if err != nil {
		t.Fatal(err)
	}
	for _, fi := range fis {
		if datasetRegexp != nil {
			if !datasetRegexp.MatchString(fi.Name()) {
				continue
			}
		}
		if fi.IsDir() {
			t.Logf("Running test: %s", fi.Name())
			runTestDir(t, "tests"+string(filepath.Separator)+fi.Name(), fi.Name())
		}
	}
}

func runTestDir(t *testing.T, dir, datasetName string) {
	// read the mapping
	mappingBytes, err := ioutil.ReadFile(dir + string(filepath.Separator) + "mapping.json")
	if err != nil {
		t.Errorf("error reading mapping: %v", err)
		return
	}
	var mapping mapping.IndexMappingImpl
	err = json.Unmarshal(mappingBytes, &mapping)
	if err != nil {
		t.Errorf("error unmarshalling mapping: %v", err)
		return
	}

	var index bleve.Index
	var cleanup func()

	// if there is a dir named 'data' open single index
	_, err = os.Stat(dir + string(filepath.Separator) + "data")
	if !os.IsNotExist(err) {

		index, cleanup, err = loadDataSet(t, datasetName, mapping, dir+string(filepath.Separator)+"data")
		if err != nil {
			t.Errorf("error loading dataset: %v", err)
			return
		}
		defer cleanup()
	} else {
		// if there is a dir named 'datasets' build alias over each index
		_, err = os.Stat(dir + string(filepath.Separator) + "datasets")
		if !os.IsNotExist(err) {
			index, cleanup, err = loadDataSets(t, datasetName, mapping, dir+string(filepath.Separator)+"datasets")
			if err != nil {
				t.Errorf("error loading dataset: %v", err)
				return
			}
			defer cleanup()
		}
	}

	// read the searches
	searchBytes, err := ioutil.ReadFile(dir + string(filepath.Separator) + "searches.json")
	if err != nil {
		t.Errorf("error reading searches: %v", err)
		return
	}
	var searches SearchTests
	err = json.Unmarshal(searchBytes, &searches)
	if err != nil {
		t.Errorf("error unmarshalling searches: %v", err)
		return
	}

	// run the searches
	for testNum, search := range searches {
		if *onlynum < 0 || (*onlynum > 0 && testNum == *onlynum) {
			res, err := index.Search(search.Search)
			if err != nil {
				t.Errorf("error running search: %v", err)
			}
			if res.Total != search.Result.Total {
				t.Errorf("test error - %s", search.Comment)
				t.Errorf("test %d - expected total: %d got %d", testNum, search.Result.Total, res.Total)
				continue
			}
			if len(res.Hits) != len(search.Result.Hits) {
				t.Errorf("test error - %s", search.Comment)
				t.Errorf("test %d - expected hits len: %d got %d", testNum, len(search.Result.Hits), len(res.Hits))
				t.Errorf("got hits: %v", res.Hits)
				continue
			}
			for hi, hit := range search.Result.Hits {
				if hit.ID != res.Hits[hi].ID {
					t.Errorf("test error - %s", search.Comment)
					t.Errorf("test %d - expected hit %d to have ID %s got %s", testNum, hi, hit.ID, res.Hits[hi].ID)
				}
				if hit.Fields != nil {
					if !reflect.DeepEqual(hit.Fields, res.Hits[hi].Fields) {
						t.Errorf("test error - %s", search.Comment)
						t.Errorf("test  %d - expected hit %d to have fields %#v got %#v", testNum, hi, hit.Fields, res.Hits[hi].Fields)
					}
				}
				if hit.Fragments != nil {
					if !reflect.DeepEqual(hit.Fragments, res.Hits[hi].Fragments) {
						t.Errorf("test error - %s", search.Comment)
						t.Errorf("test %d - expected hit %d to have fragments %#v got %#v", testNum, hi, hit.Fragments, res.Hits[hi].Fragments)
					}
				}
				if hit.Locations != nil {
					if !reflect.DeepEqual(hit.Locations, res.Hits[hi].Locations) {
						t.Errorf("test error - %s", search.Comment)
						t.Errorf("test %d - expected hit %d to have locations %#v got %#v", testNum, hi, hit.Locations, res.Hits[hi].Locations)
					}
				}
				// assert that none of the scores were NaN,+Inf,-Inf
				if math.IsInf(res.Hits[hi].Score, 0) || math.IsNaN(res.Hits[hi].Score) {
					t.Errorf("test error - %s", search.Comment)
					t.Errorf("test %d - invalid score %f", testNum, res.Hits[hi].Score)
				}
			}
			if search.Result.Facets != nil {
				if !reflect.DeepEqual(search.Result.Facets, res.Facets) {
					t.Errorf("test error - %s", search.Comment)
					t.Errorf("test %d - expected facets: %#v got %#v", testNum, search.Result.Facets, res.Facets)
				}
			}
			if _, ok := index.(bleve.IndexAlias); !ok {
				// check that custom index name is in results
				for _, hit := range res.Hits {
					if hit.Index != datasetName {
						t.Fatalf("expected name: %s, got: %s", datasetName, hit.Index)
					}
				}
			}
		}
	}
}

func loadDataSet(t *testing.T, datasetName string, mapping mapping.IndexMappingImpl, path string) (bleve.Index, func(), error) {
	idxPath := fmt.Sprintf("test-%s.bleve", datasetName)
	index, err := bleve.New(idxPath, &mapping)
	if err != nil {
		return nil, nil, fmt.Errorf("error creating new index: %v", err)
	}
	// set a custom index name
	index.SetName(datasetName)

	// index data
	fis, err := ioutil.ReadDir(path)
	if err != nil {
		return nil, nil, fmt.Errorf("error reading data dir: %v", err)
	}
	for _, fi := range fis {
		fileBytes, err := ioutil.ReadFile(path + string(filepath.Separator) + fi.Name())
		if err != nil {
			return nil, nil, fmt.Errorf("error reading data file: %v", err)
		}
		var fileDoc interface{}
		err = json.Unmarshal(fileBytes, &fileDoc)
		if err != nil {
			return nil, nil, fmt.Errorf("error parsing data file as json: %v", err)
		}
		filename := fi.Name()
		ext := filepath.Ext(filename)
		id := filename[0 : len(filename)-len(ext)]
		err = index.Index(id, fileDoc)
		if err != nil {
			return nil, nil, fmt.Errorf("error indexing data: %v", err)
		}
	}
	cleanup := func() {
		err := index.Close()
		if err != nil {
			t.Fatalf("error closing index: %v", err)
		}
		if !*keepIndex {
			err := os.RemoveAll(idxPath)
			if err != nil {
				t.Fatalf("error removing index: %v", err)
			}
		}
	}
	return index, cleanup, nil
}

func loadDataSets(t *testing.T, datasetName string, mapping mapping.IndexMappingImpl, path string) (bleve.Index, func(), error) {
	fis, err := ioutil.ReadDir(path)
	if err != nil {
		return nil, nil, fmt.Errorf("error reading datasets dir: %v", err)
	}
	var cleanups []func()
	alias := bleve.NewIndexAlias()
	for _, fi := range fis {
		idx, idxCleanup, err := loadDataSet(t, fi.Name(), mapping, path+string(filepath.Separator)+fi.Name())
		if err != nil {
			return nil, nil, fmt.Errorf("error loading dataset: %v", err)
		}
		cleanups = append(cleanups, idxCleanup)
		alias.Add(idx)
	}
	alias.SetName(datasetName)

	cleanupAll := func() {
		for _, cleanup := range cleanups {
			cleanup()
		}
	}

	return alias, cleanupAll, nil
}
<commit_msg>allow integration tests to force scorch segment type/ver (#1402)<commit_after>//  Copyright (c) 2014 Couchbase, 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 test

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"math"
	"os"
	"path/filepath"
	"reflect"
	"regexp"
	"testing"

	"github.com/blevesearch/bleve"
	"github.com/blevesearch/bleve/mapping"

	// allow choosing alternate kvstores
	_ "github.com/blevesearch/bleve/config"
)

var dataset = flag.String("dataset", "", "only test datasets matching this regex")
var onlynum = flag.Int("testnum", -1, "only run the test with this number")
var keepIndex = flag.Bool("keepIndex", false, "keep the index after testing")

var indexType = flag.String("indexType", bleve.Config.DefaultIndexType, "index type to build")
var kvType = flag.String("kvType", bleve.Config.DefaultKVStore, "kv store type to build")
var segType = flag.String("segType", "", "force scorch segment type")
var segVer = flag.Int("segVer", 0, "force scorch segment version")

func TestIntegration(t *testing.T) {

	flag.Parse()

	t.Logf("using index type %s and kv type %s", *indexType, *kvType)
	if *segType != "" {
		t.Logf("forcing segment type: %s", *segType)
	}
	if *segVer != 0 {
		t.Logf("forcing segment version: %d", *segVer)
	}

	var err error
	var datasetRegexp *regexp.Regexp
	if *dataset != "" {
		datasetRegexp, err = regexp.Compile(*dataset)
		if err != nil {
			t.Fatal(err)
		}
	}

	fis, err := ioutil.ReadDir("tests")
	if err != nil {
		t.Fatal(err)
	}
	for _, fi := range fis {
		if datasetRegexp != nil {
			if !datasetRegexp.MatchString(fi.Name()) {
				continue
			}
		}
		if fi.IsDir() {
			t.Logf("Running test: %s", fi.Name())
			runTestDir(t, "tests"+string(filepath.Separator)+fi.Name(), fi.Name())
		}
	}
}

func runTestDir(t *testing.T, dir, datasetName string) {
	// read the mapping
	mappingBytes, err := ioutil.ReadFile(dir + string(filepath.Separator) + "mapping.json")
	if err != nil {
		t.Errorf("error reading mapping: %v", err)
		return
	}
	var mapping mapping.IndexMappingImpl
	err = json.Unmarshal(mappingBytes, &mapping)
	if err != nil {
		t.Errorf("error unmarshalling mapping: %v", err)
		return
	}

	var index bleve.Index
	var cleanup func()

	// if there is a dir named 'data' open single index
	_, err = os.Stat(dir + string(filepath.Separator) + "data")
	if !os.IsNotExist(err) {

		index, cleanup, err = loadDataSet(t, datasetName, mapping, dir+string(filepath.Separator)+"data")
		if err != nil {
			t.Errorf("error loading dataset: %v", err)
			return
		}
		defer cleanup()
	} else {
		// if there is a dir named 'datasets' build alias over each index
		_, err = os.Stat(dir + string(filepath.Separator) + "datasets")
		if !os.IsNotExist(err) {
			index, cleanup, err = loadDataSets(t, datasetName, mapping, dir+string(filepath.Separator)+"datasets")
			if err != nil {
				t.Errorf("error loading dataset: %v", err)
				return
			}
			defer cleanup()
		}
	}

	// read the searches
	searchBytes, err := ioutil.ReadFile(dir + string(filepath.Separator) + "searches.json")
	if err != nil {
		t.Errorf("error reading searches: %v", err)
		return
	}
	var searches SearchTests
	err = json.Unmarshal(searchBytes, &searches)
	if err != nil {
		t.Errorf("error unmarshalling searches: %v", err)
		return
	}

	// run the searches
	for testNum, search := range searches {
		if *onlynum < 0 || (*onlynum > 0 && testNum == *onlynum) {
			res, err := index.Search(search.Search)
			if err != nil {
				t.Errorf("error running search: %v", err)
			}
			if res.Total != search.Result.Total {
				t.Errorf("test error - %s", search.Comment)
				t.Errorf("test %d - expected total: %d got %d", testNum, search.Result.Total, res.Total)
				continue
			}
			if len(res.Hits) != len(search.Result.Hits) {
				t.Errorf("test error - %s", search.Comment)
				t.Errorf("test %d - expected hits len: %d got %d", testNum, len(search.Result.Hits), len(res.Hits))
				t.Errorf("got hits: %v", res.Hits)
				continue
			}
			for hi, hit := range search.Result.Hits {
				if hit.ID != res.Hits[hi].ID {
					t.Errorf("test error - %s", search.Comment)
					t.Errorf("test %d - expected hit %d to have ID %s got %s", testNum, hi, hit.ID, res.Hits[hi].ID)
				}
				if hit.Fields != nil {
					if !reflect.DeepEqual(hit.Fields, res.Hits[hi].Fields) {
						t.Errorf("test error - %s", search.Comment)
						t.Errorf("test  %d - expected hit %d to have fields %#v got %#v", testNum, hi, hit.Fields, res.Hits[hi].Fields)
					}
				}
				if hit.Fragments != nil {
					if !reflect.DeepEqual(hit.Fragments, res.Hits[hi].Fragments) {
						t.Errorf("test error - %s", search.Comment)
						t.Errorf("test %d - expected hit %d to have fragments %#v got %#v", testNum, hi, hit.Fragments, res.Hits[hi].Fragments)
					}
				}
				if hit.Locations != nil {
					if !reflect.DeepEqual(hit.Locations, res.Hits[hi].Locations) {
						t.Errorf("test error - %s", search.Comment)
						t.Errorf("test %d - expected hit %d to have locations %#v got %#v", testNum, hi, hit.Locations, res.Hits[hi].Locations)
					}
				}
				// assert that none of the scores were NaN,+Inf,-Inf
				if math.IsInf(res.Hits[hi].Score, 0) || math.IsNaN(res.Hits[hi].Score) {
					t.Errorf("test error - %s", search.Comment)
					t.Errorf("test %d - invalid score %f", testNum, res.Hits[hi].Score)
				}
			}
			if search.Result.Facets != nil {
				if !reflect.DeepEqual(search.Result.Facets, res.Facets) {
					t.Errorf("test error - %s", search.Comment)
					t.Errorf("test %d - expected facets: %#v got %#v", testNum, search.Result.Facets, res.Facets)
				}
			}
			if _, ok := index.(bleve.IndexAlias); !ok {
				// check that custom index name is in results
				for _, hit := range res.Hits {
					if hit.Index != datasetName {
						t.Fatalf("expected name: %s, got: %s", datasetName, hit.Index)
					}
				}
			}
		}
	}
}

func loadDataSet(t *testing.T, datasetName string, mapping mapping.IndexMappingImpl, path string) (bleve.Index, func(), error) {
	idxPath := fmt.Sprintf("test-%s.bleve", datasetName)
	cfg := map[string]interface{}{}
	if *segType != "" {
		cfg["forceSegmentType"] = *segType
	}
	if *segVer != 0 {
		cfg["forceSegmentVersion"] = *segVer
	}

	index, err := bleve.NewUsing(idxPath, &mapping, *indexType, *kvType, cfg)
	if err != nil {
		return nil, nil, fmt.Errorf("error creating new index: %v", err)
	}
	// set a custom index name
	index.SetName(datasetName)

	// index data
	fis, err := ioutil.ReadDir(path)
	if err != nil {
		return nil, nil, fmt.Errorf("error reading data dir: %v", err)
	}
	for _, fi := range fis {
		fileBytes, err := ioutil.ReadFile(path + string(filepath.Separator) + fi.Name())
		if err != nil {
			return nil, nil, fmt.Errorf("error reading data file: %v", err)
		}
		var fileDoc interface{}
		err = json.Unmarshal(fileBytes, &fileDoc)
		if err != nil {
			return nil, nil, fmt.Errorf("error parsing data file as json: %v", err)
		}
		filename := fi.Name()
		ext := filepath.Ext(filename)
		id := filename[0 : len(filename)-len(ext)]
		err = index.Index(id, fileDoc)
		if err != nil {
			return nil, nil, fmt.Errorf("error indexing data: %v", err)
		}
	}
	cleanup := func() {
		err := index.Close()
		if err != nil {
			t.Fatalf("error closing index: %v", err)
		}
		if !*keepIndex {
			err := os.RemoveAll(idxPath)
			if err != nil {
				t.Fatalf("error removing index: %v", err)
			}
		}
	}
	return index, cleanup, nil
}

func loadDataSets(t *testing.T, datasetName string, mapping mapping.IndexMappingImpl, path string) (bleve.Index, func(), error) {
	fis, err := ioutil.ReadDir(path)
	if err != nil {
		return nil, nil, fmt.Errorf("error reading datasets dir: %v", err)
	}
	var cleanups []func()
	alias := bleve.NewIndexAlias()
	for _, fi := range fis {
		idx, idxCleanup, err := loadDataSet(t, fi.Name(), mapping, path+string(filepath.Separator)+fi.Name())
		if err != nil {
			return nil, nil, fmt.Errorf("error loading dataset: %v", err)
		}
		cleanups = append(cleanups, idxCleanup)
		alias.Add(idx)
	}
	alias.SetName(datasetName)

	cleanupAll := func() {
		for _, cleanup := range cleanups {
			cleanup()
		}
	}

	return alias, cleanupAll, nil
}
<|endoftext|>


<commit_before>package arn

import (
	"time"

	"github.com/aerogo/nano"
)

// Notification represents a user-associated notification.
type Notification struct {
	ID      string `json:"id"`
	UserID  string `json:"userId"`
	Created string `json:"created"`
	Seen    string `json:"seen"`
	PushNotification
}

// User retrieves the user the notification was sent to.
func (notification *Notification) User() *User {
	user, _ := GetUser(notification.UserID)
	return user
}

// CreatedTime returns the created date as a time object.
func (notification *Notification) CreatedTime() time.Time {
	t, _ := time.Parse(time.RFC3339, notification.Created)
	return t
}

// NewNotification creates a new notification.
func NewNotification(userID string, pushNotification *PushNotification) *Notification {
	return &Notification{
		ID:               GenerateID("Notification"),
		UserID:           userID,
		Created:          DateTimeUTC(),
		Seen:             "",
		PushNotification: *pushNotification,
	}
}

// GetNotification ...
func GetNotification(id string) (*Notification, error) {
	obj, err := DB.Get("Notification", id)

	if err != nil {
		return nil, err
	}

	return obj.(*Notification), nil
}

// StreamNotifications returns a stream of all notifications.
func StreamNotifications() chan *Notification {
	channel := make(chan *Notification, nano.ChannelBufferSize)

	go func() {
		for obj := range DB.All("Notification") {
			channel <- obj.(*Notification)
		}

		close(channel)
	}()

	return channel
}

// AllNotifications returns a slice of all notifications.
func AllNotifications() ([]*Notification, error) {
	var all []*Notification

	for obj := range StreamNotifications() {
		all = append(all, obj)
	}

	return all, nil
}
<commit_msg>Added notification.String<commit_after>package arn

import (
	"fmt"
	"time"

	"github.com/aerogo/nano"
)

// Notification represents a user-associated notification.
type Notification struct {
	ID      string `json:"id"`
	UserID  string `json:"userId"`
	Created string `json:"created"`
	Seen    string `json:"seen"`
	PushNotification
}

// User retrieves the user the notification was sent to.
func (notification *Notification) User() *User {
	user, _ := GetUser(notification.UserID)
	return user
}

// CreatedTime returns the created date as a time object.
func (notification *Notification) CreatedTime() time.Time {
	t, _ := time.Parse(time.RFC3339, notification.Created)
	return t
}

// String returns a string representation of the notification.
func (notification *Notification) String() string {
	return fmt.Sprintf("[%s] %s", notification.Type, notification.Title)
}

// NewNotification creates a new notification.
func NewNotification(userID string, pushNotification *PushNotification) *Notification {
	return &Notification{
		ID:               GenerateID("Notification"),
		UserID:           userID,
		Created:          DateTimeUTC(),
		Seen:             "",
		PushNotification: *pushNotification,
	}
}

// GetNotification ...
func GetNotification(id string) (*Notification, error) {
	obj, err := DB.Get("Notification", id)

	if err != nil {
		return nil, err
	}

	return obj.(*Notification), nil
}

// StreamNotifications returns a stream of all notifications.
func StreamNotifications() chan *Notification {
	channel := make(chan *Notification, nano.ChannelBufferSize)

	go func() {
		for obj := range DB.All("Notification") {
			channel <- obj.(*Notification)
		}

		close(channel)
	}()

	return channel
}

// AllNotifications returns a slice of all notifications.
func AllNotifications() ([]*Notification, error) {
	var all []*Notification

	for obj := range StreamNotifications() {
		all = append(all, obj)
	}

	return all, nil
}
<|endoftext|>