Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test TestAllSourcesWithFileOutput on CI #249

Closed
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ COPY . .
RUN go build -o /bin/exclude-prefixes .

FROM build as test
CMD go test -test.v ./...
CMD go test -test.v ./... -count=15000 -timeout 1000m

FROM test as debug
CMD dlv -l :40000 --headless=true --api-version=2 test -test.v ./...
Expand Down
295 changes: 0 additions & 295 deletions internal/prefixcollector/collector_configmap_output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,17 @@ package prefixcollector_test
import (
"cmd-exclude-prefixes-k8s/internal/prefixcollector"
"cmd-exclude-prefixes-k8s/internal/prefixcollector/prefixsource"
"cmd-exclude-prefixes-k8s/internal/utils"
"context"
"fmt"
"os"
"path/filepath"
"testing"
"time"

"github.com/pkg/errors"

"github.com/ghodss/yaml"
"github.com/stretchr/testify/suite"
"go.uber.org/goleak"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake"
k8stest "k8s.io/client-go/testing"
)

const (
Expand Down Expand Up @@ -81,202 +73,6 @@ func (eps *ExcludedPrefixesSuite) TearDownTest() {
eps.deleteConfigMap(context.Background(), configMapNamespace, userConfigMapName)
}

func (eps *ExcludedPrefixesSuite) TestCollectorWithDummySources() {
defer goleak.VerifyNone(eps.T(), goleak.IgnoreCurrent())
notifyChan := make(chan struct{}, 1)
ctx, cancel := context.WithCancel(prefixcollector.WithKubernetesInterface(context.Background(), eps.clientSet))
defer cancel()

sources := []prefixcollector.PrefixSource{
newDummyPrefixSource(
[]string{
"127.0.0.1/16",
"127.0.2.1/16",
"168.92.0.1/24",
},
),
newDummyPrefixSource(
[]string{
"127.0.3.1/18",
"134.56.0.1/8",
"168.92.0.1/16",
},
),
}

expectedResult := []string{
"127.0.0.0/16",
"168.92.0.0/16",
"134.0.0.0/8",
}

eps.testCollectorWithConfigmapOutput(ctx, notifyChan, expectedResult, sources)
}

func (eps *ExcludedPrefixesSuite) TestConfigMapSource() {
defer goleak.VerifyNone(eps.T(), goleak.IgnoreCurrent())
expectedResult := []string{
"168.0.0.0/10",
"1.0.0.0/11",
}
notifyChan := make(chan struct{}, 1)

ctx, cancel := context.WithCancel(prefixcollector.WithKubernetesInterface(context.Background(), eps.clientSet))
defer cancel()
eps.createConfigMap(ctx, configMapNamespace, configMapPath)

sources := []prefixcollector.PrefixSource{
prefixsource.NewConfigMapPrefixSource(
ctx,
notifyChan,
userConfigMapName,
configMapNamespace,
userConfigMapKey,
),
}

eps.testCollectorWithConfigmapOutput(ctx, notifyChan, expectedResult, sources)
}

func (eps *ExcludedPrefixesSuite) TestConfigMapSourceRefresh() {
defer goleak.VerifyNone(eps.T(), goleak.IgnoreCurrent())
expectedResult := []string{
"168.0.0.0/10",
"1.0.0.0/11",
}
notifyChan := make(chan struct{}, 1)

ctx, cancel := context.WithCancel(prefixcollector.WithKubernetesInterface(context.Background(), eps.clientSet))
defer cancel()

clients := eps.clientSet.(*fake.Clientset)
countWatchers, stopAndDisableWatcher := interceptWatcher(clients)

sources := []prefixcollector.PrefixSource{
prefixsource.NewConfigMapPrefixSource(
ctx,
notifyChan,
userConfigMapName,
configMapNamespace,
userConfigMapKey,
),
}

eps.Eventually(func() bool { return countWatchers() == 1 }, time.Second, 10*time.Millisecond)
stopAndDisableWatcher()
eps.Eventually(func() bool { return countWatchers() == 2 }, time.Second, 10*time.Millisecond)

eps.createConfigMap(ctx, configMapNamespace, configMapPath)
eps.testCollectorWithConfigmapOutput(ctx, notifyChan, expectedResult, sources)
}

func (eps *ExcludedPrefixesSuite) TestKubeAdmConfigSource() {
defer goleak.VerifyNone(eps.T(), goleak.IgnoreCurrent())
expectedResult := []string{
"10.244.0.0/16",
"10.96.0.0/12",
}

notifyChan := make(chan struct{}, 1)
ctx, cancel := context.WithCancel(prefixcollector.WithKubernetesInterface(context.Background(), eps.clientSet))
defer cancel()

eps.createConfigMap(ctx, prefixsource.KubeNamespace, kubeConfigMapPath)

sources := []prefixcollector.PrefixSource{
prefixsource.NewKubeAdmPrefixSource(ctx, notifyChan),
}

eps.testCollectorWithConfigmapOutput(ctx, notifyChan, expectedResult, sources)
}

func (eps *ExcludedPrefixesSuite) TestKubeAdmConfigSourceRefresh() {
defer goleak.VerifyNone(eps.T(), goleak.IgnoreCurrent())
expectedResult := []string{
"10.244.0.0/16",
"10.96.0.0/12",
}

notifyChan := make(chan struct{}, 1)
ctx, cancel := context.WithCancel(prefixcollector.WithKubernetesInterface(context.Background(), eps.clientSet))
defer cancel()

clients := eps.clientSet.(*fake.Clientset)
countWatchers, stopAndDisableWatcher := interceptWatcher(clients)

sources := []prefixcollector.PrefixSource{
prefixsource.NewKubeAdmPrefixSource(ctx, notifyChan),
}

eps.Eventually(func() bool { return countWatchers() == 1 }, time.Second, 10*time.Millisecond)
stopAndDisableWatcher()
eps.Eventually(func() bool { return countWatchers() == 2 }, time.Second, 10*time.Millisecond)

eps.createConfigMap(ctx, prefixsource.KubeNamespace, kubeConfigMapPath)
eps.testCollectorWithConfigmapOutput(ctx, notifyChan, expectedResult, sources)
}

func (eps *ExcludedPrefixesSuite) TestKubeAdmConfigSourceIPv6() {
defer goleak.VerifyNone(eps.T(), goleak.IgnoreCurrent())
expectedResult := []string{
"10.244.0.0/16",
"10.96.0.0/16",
"fd00:10:244::/56",
"fd00:10:96::/112",
}

notifyChan := make(chan struct{}, 1)
ctx, cancel := context.WithCancel(prefixcollector.WithKubernetesInterface(context.Background(), eps.clientSet))
defer cancel()

eps.createConfigMap(ctx, prefixsource.KubeNamespace, kubeConfigMapPathIPv6)

sources := []prefixcollector.PrefixSource{
prefixsource.NewKubeAdmPrefixSource(ctx, notifyChan),
}

eps.testCollectorWithConfigmapOutput(ctx, notifyChan, expectedResult, sources)
}

func (eps *ExcludedPrefixesSuite) TestAllSources() {
defer goleak.VerifyNone(eps.T(), goleak.IgnoreCurrent())
expectedResult := []string{
"10.244.0.0/16",
"10.96.0.0/12",
"127.0.0.0/16",
"168.92.0.0/24",
"168.0.0.0/10",
"1.0.0.0/11",
}

notifyChan := make(chan struct{}, 1)
ctx, cancel := context.WithCancel(prefixcollector.WithKubernetesInterface(context.Background(), eps.clientSet))
defer cancel()

eps.createConfigMap(ctx, prefixsource.KubeNamespace, kubeConfigMapPath)
eps.createConfigMap(ctx, configMapNamespace, configMapPath)

sources := []prefixcollector.PrefixSource{
newDummyPrefixSource(
[]string{
"127.0.0.1/16",
"127.0.2.1/16",
"168.92.0.1/24",
},
),
prefixsource.NewKubeAdmPrefixSource(ctx, notifyChan),
prefixsource.NewConfigMapPrefixSource(
ctx,
notifyChan,
userConfigMapName,
configMapNamespace,
userConfigMapKey,
),
}

eps.testCollectorWithConfigmapOutput(ctx, notifyChan, expectedResult, sources)
}

func TestExcludedPrefixesSuite(t *testing.T) {
suite.Run(t, &ExcludedPrefixesSuite{})
}
Expand All @@ -299,78 +95,6 @@ func (eps *ExcludedPrefixesSuite) createConfigMap(ctx context.Context, namespace
}
}

func (eps *ExcludedPrefixesSuite) testCollectorWithConfigmapOutput(ctx context.Context, notifyChan chan struct{},
expectedResult []string, sources []prefixcollector.PrefixSource) {
collector := prefixcollector.NewExcludePrefixCollector(
prefixcollector.WithNotifyChan(notifyChan),
prefixcollector.WithConfigMapOutput(nsmConfigMapName, configMapNamespace, excludedPrefixesKey),
prefixcollector.WithSources(sources...),
)

ctx, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()

errCh := eps.watchConfigMap(ctx, len(sources)+2)

go collector.Serve(ctx)

if err := <-errCh; err != nil {
eps.T().Fatal("Error watching config map: ", err)
}

configMap, err := eps.clientSet.CoreV1().ConfigMaps(configMapNamespace).Get(ctx, nsmConfigMapName, metav1.GetOptions{})
if err != nil {
eps.T().Fatal("Error getting nsm config map: ", err)
}

prefixes, err := utils.YamlToPrefixes([]byte(configMap.Data[excludedPrefixesKey]))
if err != nil {
eps.T().Fatal("Error transforming yaml to prefixes: ", err)
}

eps.Require().ElementsMatch(expectedResult, prefixes)
}

func (eps *ExcludedPrefixesSuite) watchConfigMap(ctx context.Context, maxModifyCount int) <-chan error {
watcher, err := eps.clientSet.CoreV1().ConfigMaps(configMapNamespace).Watch(ctx, metav1.ListOptions{})
if err != nil {
eps.T().Fatalf("Error watching configmap: %v", err)
}

errorCh := make(chan error)
modifyCount := 0
go func() {
for {
select {
case event, ok := <-watcher.ResultChan():
if !ok {
errorCh <- errors.New("error watching configmap")
return
}
configMap := event.Object.(*v1.ConfigMap)
if event.Type == watch.Error {
errorCh <- errors.New("error watching configmap")
return
}

if configMap.Name == nsmConfigMapName && (event.Type == watch.Added || event.Type == watch.Modified) {
modifyCount++
fmt.Printf("event count : %v\n", modifyCount)
if modifyCount == maxModifyCount {
close(errorCh)
return
}
}
case <-ctx.Done():
close(errorCh)
return
}
}
}()

return errorCh
}

func getConfigMap(t *testing.T, filePath string) *v1.ConfigMap {
destination := v1.ConfigMap{}
bytes, err := os.ReadFile(filepath.Clean(filePath))
Expand All @@ -383,22 +107,3 @@ func getConfigMap(t *testing.T, filePath string) *v1.ConfigMap {

return &destination
}

func interceptWatcher(clients *fake.Clientset) (getCount func() int, stopAndDisable func()) {
enable := true
count := 0
watcher := watch.NewFake()

var reactionFunc k8stest.WatchReactionFunc = func(action k8stest.Action) (bool, watch.Interface, error) {
count++
return enable, watcher, nil
}

clients.PrependWatchReactor("configmaps", reactionFunc)

return func() int { return count },
func() {
enable = false
watcher.Stop()
}
}
3 changes: 2 additions & 1 deletion internal/prefixcollector/collector_file_output_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ func (eps *ExcludedPrefixesSuite) testCollectorWithFileOutput(ctx context.Contex
ctx, cancel := context.WithTimeout(ctx, time.Second)
defer cancel()

watcher, errCh := eps.watchFile(ctx, prefixesFilePath, len(sources))
watcher, errCh := eps.watchFile(ctx, prefixesFilePath, len(sources)*2)

go collector.Serve(ctx)

Expand Down Expand Up @@ -140,6 +140,7 @@ func (eps *ExcludedPrefixesSuite) watchFile(ctx context.Context, prefixesFilePat
close(errorCh)
return
}

if event.Op&fsnotify.Write == fsnotify.Write {
modifyCount++
if modifyCount == maxModifyCount {
Expand Down
Loading