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

e2e tests for dynamic configuration and Lua features and a bug fix #2254

Merged
merged 5 commits into from
Apr 1, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 23 additions & 23 deletions internal/ingress/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,41 +169,41 @@ func (n *NGINXController) syncIngress(item interface{}) error {
if !n.isForceReload() && n.runningConfig.Equal(&pcfg) {
glog.V(3).Infof("skipping backend reload (no changes detected)")
return nil
} else if !n.isForceReload() && n.cfg.DynamicConfigurationEnabled && n.IsDynamicallyConfigurable(&pcfg) {
err := n.ConfigureDynamically(&pcfg)
if err == nil {
glog.Infof("dynamic reconfiguration succeeded, skipping reload")
n.runningConfig = &pcfg
return nil
}

glog.Warningf("falling back to reload, could not dynamically reconfigure: %v", err)
}

glog.Infof("backend reload required")
if n.cfg.DynamicConfigurationEnabled && n.IsDynamicConfigurationEnough(&pcfg) && !n.isForceReload() {
glog.Infof("skipping reload")
} else {
glog.Infof("backend reload required")

err := n.OnUpdate(pcfg)
if err != nil {
incReloadErrorCount()
glog.Errorf("unexpected failure restarting the backend: \n%v", err)
return err
err := n.OnUpdate(pcfg)
if err != nil {
incReloadErrorCount()
glog.Errorf("unexpected failure restarting the backend: \n%v", err)
return err
}

glog.Infof("ingress backend successfully reloaded...")
incReloadCount()
setSSLExpireTime(servers)
}

glog.Infof("ingress backend successfully reloaded...")
incReloadCount()
setSSLExpireTime(servers)
if n.cfg.DynamicConfigurationEnabled {
isFirstSync := n.runningConfig.Equal(&ingress.Configuration{})
go func(isFirstSync bool) {
if isFirstSync {
glog.Infof("first sync of Nginx configuration")

if n.isForceReload() && n.cfg.DynamicConfigurationEnabled {
go func() {
// it takes time for Nginx to start listening on the port
time.Sleep(1 * time.Second)
// it takes time for Nginx to start listening on the port
time.Sleep(1 * time.Second)
}
err := n.ConfigureDynamically(&pcfg)
if err == nil {
glog.Infof("dynamic reconfiguration succeeded")
} else {
glog.Warningf("could not dynamically reconfigure: %v", err)
}
}()
}(isFirstSync)
}

n.runningConfig = &pcfg
Expand Down
4 changes: 2 additions & 2 deletions internal/ingress/controller/nginx.go
Original file line number Diff line number Diff line change
Expand Up @@ -751,8 +751,8 @@ func (n *NGINXController) setupSSLProxy() {
}()
}

// IsDynamicallyConfigurable decides if the new configuration can be dynamically configured without reloading
func (n *NGINXController) IsDynamicallyConfigurable(pcfg *ingress.Configuration) bool {
// IsDynamicConfigurationEnough decides if the new configuration changes can be dynamically applied without reloading
func (n *NGINXController) IsDynamicConfigurationEnough(pcfg *ingress.Configuration) bool {
var copyOfRunningConfig ingress.Configuration = *n.runningConfig
var copyOfPcfg ingress.Configuration = *pcfg

Expand Down
8 changes: 4 additions & 4 deletions internal/ingress/controller/nginx_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
"k8s.io/ingress-nginx/internal/ingress"
)

func TestIsDynamicallyConfigurable(t *testing.T) {
func TestIsDynamicConfigurationEnough(t *testing.T) {
backends := []*ingress.Backend{{
Name: "fakenamespace-myapp-80",
Endpoints: []ingress.Endpoint{
Expand Down Expand Up @@ -60,23 +60,23 @@ func TestIsDynamicallyConfigurable(t *testing.T) {
}

newConfig := commonConfig
if !n.IsDynamicallyConfigurable(newConfig) {
if !n.IsDynamicConfigurationEnough(newConfig) {
t.Errorf("When new config is same as the running config it should be deemed as dynamically configurable")
}

newConfig = &ingress.Configuration{
Backends: []*ingress.Backend{{Name: "another-backend-8081"}},
Servers: []*ingress.Server{{Hostname: "myapp1.fake"}},
}
if n.IsDynamicallyConfigurable(newConfig) {
if n.IsDynamicConfigurationEnough(newConfig) {
t.Errorf("Expected to not be dynamically configurable when there's more than just backends change")
}

newConfig = &ingress.Configuration{
Backends: []*ingress.Backend{{Name: "a-backend-8080"}},
Servers: servers,
}
if !n.IsDynamicallyConfigurable(newConfig) {
if !n.IsDynamicConfigurationEnough(newConfig) {
t.Errorf("Expected to be dynamically configurable when only backends change")
}

Expand Down
1 change: 1 addition & 0 deletions test/e2e/e2e.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
// tests to run
_ "k8s.io/ingress-nginx/test/e2e/annotations"
_ "k8s.io/ingress-nginx/test/e2e/defaultbackend"
_ "k8s.io/ingress-nginx/test/e2e/lua"
_ "k8s.io/ingress-nginx/test/e2e/settings"
_ "k8s.io/ingress-nginx/test/e2e/ssl"
)
Expand Down
24 changes: 24 additions & 0 deletions test/e2e/framework/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ import (
"strings"
"time"

appsv1beta1 "k8s.io/api/apps/v1beta1"
"k8s.io/api/core/v1"
apiextcs "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"

"github.com/golang/glog"
"github.com/pkg/errors"

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
Expand Down Expand Up @@ -255,3 +258,24 @@ func (f *Framework) matchNginxConditions(name string, matcher func(cfg string) b
return false, nil
}
}

// UpdateDeployment runs the given updateFunc on the deployment and waits for it to be updated
func UpdateDeployment(kubeClientSet kubernetes.Interface, namespace string, name string, replicas int, updateFunc func(d *appsv1beta1.Deployment) error) error {
deployment, err := kubeClientSet.AppsV1beta1().Deployments(namespace).Get(name, metav1.GetOptions{})
if err != nil {
return err
}

if err = updateFunc(deployment); err != nil {
return err
}

err = WaitForPodsReady(kubeClientSet, 60*time.Second, replicas, namespace, metav1.ListOptions{
LabelSelector: fields.SelectorFromSet(fields.Set(deployment.Spec.Template.ObjectMeta.Labels)).String(),
})
if err != nil {
return errors.Wrap(err, "failed to wait for nginx-ingress-controller pods to restart")
}

return nil
}
10 changes: 8 additions & 2 deletions test/e2e/framework/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes"
)

// EnsureSecret creates a Secret object or returns it if it already exists.
Expand Down Expand Up @@ -75,10 +76,15 @@ func (f *Framework) EnsureDeployment(deployment *extensions.Deployment) (*extens
return d, nil
}

// WaitForPodsReady waits for a given amount of time until a group of Pods is running.
// WaitForPodsReady waits for a given amount of time until a group of Pods is running in the framework's namespace.
func (f *Framework) WaitForPodsReady(timeout time.Duration, expectedReplicas int, opts metav1.ListOptions) error {
return WaitForPodsReady(f.KubeClientSet, timeout, expectedReplicas, f.Namespace.Name, opts)
}

// WaitForPodsReady waits for a given amount of time until a group of Pods is running in the given namespace.
func WaitForPodsReady(kubeClientSet kubernetes.Interface, timeout time.Duration, expectedReplicas int, namespace string, opts metav1.ListOptions) error {
return wait.Poll(time.Second, timeout, func() (bool, error) {
pl, err := f.KubeClientSet.CoreV1().Pods(f.Namespace.Name).List(opts)
pl, err := kubeClientSet.CoreV1().Pods(namespace).List(opts)
if err != nil {
return false, err
}
Expand Down
Loading