<commit_before>// Copyright 2016 Cisco Systems, 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 index

import (
	"sync"
	"testing"
	"time"

	"github.com/Sirupsen/logrus"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/runtime"
	v1 "k8s.io/client-go/pkg/api/v1"
	v1beta1 "k8s.io/client-go/pkg/apis/extensions/v1beta1"
	"k8s.io/client-go/tools/cache"
	framework "k8s.io/client-go/tools/cache/testing"
	"k8s.io/kubernetes/pkg/controller"

	tu "github.com/noironetworks/aci-containers/pkg/testutil"
)

type testIndex struct {
	stopCh chan struct{}

	fakeNamespaceSource *framework.FakeControllerSource
	fakePodSource       *framework.FakeControllerSource
	fakeObjSource       *framework.FakeControllerSource

	si *PodSelectorIndex

	mutex   sync.Mutex
	updates map[string]bool
}

type TestKubeObj struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`

	selector []PodSelector
}

func newTestIndex(log *logrus.Logger, dep bool) *testIndex {
	log.Level = logrus.DebugLevel

	testIndex := &testIndex{
		stopCh:              make(chan struct{}),
		fakeNamespaceSource: framework.NewFakeControllerSource(),
		fakePodSource:       framework.NewFakeControllerSource(),
		fakeObjSource:       framework.NewFakeControllerSource(),
	}
	namespaceInformer := cache.NewSharedIndexInformer(
		&cache.ListWatch{
			ListFunc:  testIndex.fakeNamespaceSource.List,
			WatchFunc: testIndex.fakeNamespaceSource.Watch,
		},
		&v1.Namespace{},
		controller.NoResyncPeriodFunc(),
		cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
	)
	namespaceInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
		AddFunc: func(obj interface{}) {
			testIndex.si.UpdateNamespace(obj.(*v1.Namespace))
		},
		UpdateFunc: func(_ interface{}, obj interface{}) {
			testIndex.si.UpdateNamespace(obj.(*v1.Namespace))
		},
		DeleteFunc: func(obj interface{}) {
			testIndex.si.DeleteNamespace(obj.(*v1.Namespace))
		},
	})
	podInformer := cache.NewSharedIndexInformer(
		&cache.ListWatch{
			ListFunc:  testIndex.fakePodSource.List,
			WatchFunc: testIndex.fakePodSource.Watch,
		},
		&v1.Pod{},
		controller.NoResyncPeriodFunc(),
		cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
	)
	podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
		AddFunc: func(obj interface{}) {
			testIndex.si.UpdatePod(obj.(*v1.Pod))
		},
		UpdateFunc: func(_ interface{}, obj interface{}) {
			testIndex.si.UpdatePod(obj.(*v1.Pod))
		},
		DeleteFunc: func(obj interface{}) {
			testIndex.si.DeletePod(obj.(*v1.Pod))
		},
	})
	var objtype runtime.Object
	if dep {
		objtype = &v1beta1.Deployment{}
	} else {
		objtype = &TestKubeObj{}
	}
	objInformer := cache.NewSharedIndexInformer(
		&cache.ListWatch{
			ListFunc:  testIndex.fakeObjSource.List,
			WatchFunc: testIndex.fakeObjSource.Watch,
		},
		objtype,
		controller.NoResyncPeriodFunc(),
		cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
	)
	objInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
		AddFunc: func(obj interface{}) {
			testIndex.si.UpdateSelectorObj(obj)
		},
		UpdateFunc: func(_ interface{}, obj interface{}) {
			testIndex.si.UpdateSelectorObj(obj)
		},
		DeleteFunc: func(obj interface{}) {
			testIndex.si.DeleteSelectorObj(obj)
		},
	})

	updateCb := func(key string) {
		testIndex.mutex.Lock()
		testIndex.updates[key] = true
		testIndex.mutex.Unlock()
	}

	if dep {
		testIndex.si = NewPodSelectorIndex(
			log, podInformer, namespaceInformer, objInformer,
			cache.MetaNamespaceKeyFunc,
			func(obj interface{}) []PodSelector {
				dep := obj.(*v1beta1.Deployment)
				return PodSelectorFromNsAndSelector(dep.ObjectMeta.Namespace,
					dep.Spec.Selector)
			})
		testIndex.si.SetPodUpdateCallback(updateCb)
	} else {
		testIndex.si = NewPodSelectorIndex(
			log, podInformer, namespaceInformer, objInformer,
			cache.MetaNamespaceKeyFunc,
			func(obj interface{}) []PodSelector {
				to := obj.(*TestKubeObj)
				return to.selector
			})
		testIndex.si.SetObjUpdateCallback(updateCb)
	}

	go podInformer.Run(testIndex.stopCh)
	go namespaceInformer.Run(testIndex.stopCh)
	go objInformer.Run(testIndex.stopCh)

	return testIndex
}

func (i *testIndex) stop() {
	close(i.stopCh)
}

func pod(namespace string, name string, labels map[string]string) *v1.Pod {
	return &v1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Namespace: namespace,
			Name:      name,
			Labels:    labels,
		},<commit_msg>Fix unit test failure (missed file in previous commit)<commit_after>// Copyright 2016 Cisco Systems, 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 index

import (
	"sync"
	"testing"
	"time"

	"github.com/Sirupsen/logrus"

	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/labels"
	"k8s.io/apimachinery/pkg/runtime"
	v1 "k8s.io/client-go/pkg/api/v1"
	v1beta1 "k8s.io/client-go/pkg/apis/extensions/v1beta1"
	"k8s.io/client-go/tools/cache"
	framework "k8s.io/client-go/tools/cache/testing"

	tu "github.com/noironetworks/aci-containers/pkg/testutil"
)

type testIndex struct {
	stopCh chan struct{}

	fakeNamespaceSource *framework.FakeControllerSource
	fakePodSource       *framework.FakeControllerSource
	fakeObjSource       *framework.FakeControllerSource

	si *PodSelectorIndex

	mutex   sync.Mutex
	updates map[string]bool
}

type TestKubeObj struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`

	selector []PodSelector
}

func newTestIndex(log *logrus.Logger, dep bool) *testIndex {
	log.Level = logrus.DebugLevel

	testIndex := &testIndex{
		stopCh:              make(chan struct{}),
		fakeNamespaceSource: framework.NewFakeControllerSource(),
		fakePodSource:       framework.NewFakeControllerSource(),
		fakeObjSource:       framework.NewFakeControllerSource(),
	}
	namespaceIndexer, namespaceInformer := cache.NewIndexerInformer(
		&cache.ListWatch{
			ListFunc:  testIndex.fakeNamespaceSource.List,
			WatchFunc: testIndex.fakeNamespaceSource.Watch,
		},
		&v1.Namespace{}, 0,
		cache.ResourceEventHandlerFuncs{
			AddFunc: func(obj interface{}) {
				testIndex.si.UpdateNamespace(obj.(*v1.Namespace))
			},
			UpdateFunc: func(_ interface{}, obj interface{}) {
				testIndex.si.UpdateNamespace(obj.(*v1.Namespace))
			},
			DeleteFunc: func(obj interface{}) {
				testIndex.si.DeleteNamespace(obj.(*v1.Namespace))
			},
		},
		cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
	)
	podIndexer, podInformer := cache.NewIndexerInformer(
		&cache.ListWatch{
			ListFunc:  testIndex.fakePodSource.List,
			WatchFunc: testIndex.fakePodSource.Watch,
		},
		&v1.Pod{}, 0,
		cache.ResourceEventHandlerFuncs{
			AddFunc: func(obj interface{}) {
				testIndex.si.UpdatePod(obj.(*v1.Pod))
			},
			UpdateFunc: func(_ interface{}, obj interface{}) {
				testIndex.si.UpdatePod(obj.(*v1.Pod))
			},
			DeleteFunc: func(obj interface{}) {
				testIndex.si.DeletePod(obj.(*v1.Pod))
			},
		},
		cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
	)
	var objtype runtime.Object
	if dep {
		objtype = &v1beta1.Deployment{}
	} else {
		objtype = &TestKubeObj{}
	}
	objIndexer, objInformer := cache.NewIndexerInformer(
		&cache.ListWatch{
			ListFunc:  testIndex.fakeObjSource.List,
			WatchFunc: testIndex.fakeObjSource.Watch,
		},
		objtype, 0,
		cache.ResourceEventHandlerFuncs{
			AddFunc: func(obj interface{}) {
				testIndex.si.UpdateSelectorObj(obj)
			},
			UpdateFunc: func(_ interface{}, obj interface{}) {
				testIndex.si.UpdateSelectorObj(obj)
			},
			DeleteFunc: func(obj interface{}) {
				testIndex.si.DeleteSelectorObj(obj)
			},
		},
		cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc},
	)

	updateCb := func(key string) {
		testIndex.mutex.Lock()
		testIndex.updates[key] = true
		testIndex.mutex.Unlock()
	}

	if dep {
		testIndex.si = NewPodSelectorIndex(
			log, podIndexer, namespaceIndexer, objIndexer,
			cache.MetaNamespaceKeyFunc,
			func(obj interface{}) []PodSelector {
				dep := obj.(*v1beta1.Deployment)
				return PodSelectorFromNsAndSelector(dep.ObjectMeta.Namespace,
					dep.Spec.Selector)
			})
		testIndex.si.SetPodUpdateCallback(updateCb)
	} else {
		testIndex.si = NewPodSelectorIndex(
			log, podIndexer, namespaceIndexer, objIndexer,
			cache.MetaNamespaceKeyFunc,
			func(obj interface{}) []PodSelector {
				to := obj.(*TestKubeObj)
				return to.selector
			})
		testIndex.si.SetObjUpdateCallback(updateCb)
	}

	go podInformer.Run(testIndex.stopCh)
	go namespaceInformer.Run(testIndex.stopCh)
	go objInformer.Run(testIndex.stopCh)

	return testIndex
}

func (i *testIndex) stop() {
	close(i.stopCh)
}

func pod(namespace string, name string, labels map[string]string) *v1.Pod {
	return &v1.Pod{
		ObjectMeta: metav1.ObjectMeta{
			Namespace: namespace,
			Name:      name,
			Labels:    labels,
		},
{'fraction_non_alphanumeric': 0.1228140703517588, 'fraction_numerical': 0.00864321608040201, 'mean_word_length': 4.35287789133943, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1064617', 'n_tokens_mistral': 3582, 'n_tokens_neox': 3287, 'n_words': 634}