-
Notifications
You must be signed in to change notification settings - Fork 440
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(experiment): Add test cases (#556)
* fix: Remove useless code Signed-off-by: Ce Gao <gaoce@caicloud.io> * feat(experiment): Abstract manager client Signed-off-by: Ce Gao <gaoce@caicloud.io> * feat: Add basic test cases Signed-off-by: Ce Gao <gaoce@caicloud.io>
- Loading branch information
1 parent
f71f0e8
commit 22ac009
Showing
17 changed files
with
447 additions
and
173 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 79 additions & 0 deletions
79
pkg/controller/v1alpha2/experiment/experiment_controller_suite_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
/* | ||
Copyright 2019 The Kubernetes Authors. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
package experiment | ||
|
||
import ( | ||
stdlog "log" | ||
"os" | ||
"path/filepath" | ||
"sync" | ||
"testing" | ||
|
||
"github.com/onsi/gomega" | ||
"k8s.io/client-go/kubernetes/scheme" | ||
"k8s.io/client-go/rest" | ||
"sigs.k8s.io/controller-runtime/pkg/envtest" | ||
"sigs.k8s.io/controller-runtime/pkg/manager" | ||
"sigs.k8s.io/controller-runtime/pkg/reconcile" | ||
|
||
"github.com/kubeflow/katib/pkg/api/operators/apis" | ||
) | ||
|
||
var cfg *rest.Config | ||
|
||
func TestMain(m *testing.M) { | ||
t := &envtest.Environment{ | ||
CRDDirectoryPaths: []string{ | ||
filepath.Join("..", "..", "..", "..", "manifests", "v1alpha2", "katib-controller"), | ||
filepath.Join("..", "..", "..", "..", "test", "unit", "v1alpha2", "crds"), | ||
}, | ||
} | ||
apis.AddToScheme(scheme.Scheme) | ||
|
||
var err error | ||
if cfg, err = t.Start(); err != nil { | ||
stdlog.Fatal(err) | ||
} | ||
|
||
code := m.Run() | ||
t.Stop() | ||
os.Exit(code) | ||
} | ||
|
||
// SetupTestReconcile returns a reconcile.Reconcile implementation that delegates to inner and | ||
// writes the request to requests after Reconcile is finished. | ||
func SetupTestReconcile(inner reconcile.Reconciler) (reconcile.Reconciler, chan reconcile.Request) { | ||
requests := make(chan reconcile.Request) | ||
fn := reconcile.Func(func(req reconcile.Request) (reconcile.Result, error) { | ||
result, err := inner.Reconcile(req) | ||
requests <- req | ||
return result, err | ||
}) | ||
return fn, requests | ||
} | ||
|
||
// StartTestManager adds recFn | ||
func StartTestManager(mgr manager.Manager, g *gomega.GomegaWithT) (chan struct{}, *sync.WaitGroup) { | ||
stop := make(chan struct{}) | ||
wg := &sync.WaitGroup{} | ||
wg.Add(1) | ||
go func() { | ||
defer wg.Done() | ||
g.Expect(mgr.Start(stop)).NotTo(gomega.HaveOccurred()) | ||
}() | ||
return stop, wg | ||
} |
103 changes: 103 additions & 0 deletions
103
pkg/controller/v1alpha2/experiment/experiment_controller_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
package experiment | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
"time" | ||
|
||
"github.com/golang/mock/gomock" | ||
"github.com/onsi/gomega" | ||
apierrors "k8s.io/apimachinery/pkg/api/errors" | ||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
"k8s.io/apimachinery/pkg/types" | ||
"sigs.k8s.io/controller-runtime/pkg/manager" | ||
"sigs.k8s.io/controller-runtime/pkg/reconcile" | ||
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" | ||
|
||
experimentsv1alpha2 "github.com/kubeflow/katib/pkg/api/operators/apis/experiment/v1alpha2" | ||
managerclientmock "github.com/kubeflow/katib/pkg/mock/v1alpha2/experiment/managerclient" | ||
manifestmock "github.com/kubeflow/katib/pkg/mock/v1alpha2/experiment/manifest" | ||
suggestionmock "github.com/kubeflow/katib/pkg/mock/v1alpha2/experiment/suggestion" | ||
) | ||
|
||
const ( | ||
experimentName = "foo" | ||
namespace = "default" | ||
|
||
timeout = time.Second * 20 | ||
) | ||
|
||
var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: experimentName, Namespace: namespace}} | ||
var trialKey = types.NamespacedName{Name: "test", Namespace: namespace} | ||
|
||
func init() { | ||
logf.SetLogger(logf.ZapLogger(true)) | ||
} | ||
|
||
func TestCreateExperiment(t *testing.T) { | ||
g := gomega.NewGomegaWithT(t) | ||
instance := newFakeInstance() | ||
|
||
mockCtrl := gomock.NewController(t) | ||
defer mockCtrl.Finish() | ||
mc := managerclientmock.NewMockManagerClient(mockCtrl) | ||
mc.EXPECT().CreateExperimentInDB(gomock.Any()).Return(nil).AnyTimes() | ||
mc.EXPECT().UpdateExperimentStatusInDB(gomock.Any()).Return(nil).AnyTimes() | ||
|
||
mockCtrl2 := gomock.NewController(t) | ||
defer mockCtrl2.Finish() | ||
suggestion := suggestionmock.NewMockSuggestion(mockCtrl) | ||
|
||
mockCtrl3 := gomock.NewController(t) | ||
defer mockCtrl3.Finish() | ||
generator := manifestmock.NewMockGenerator(mockCtrl) | ||
|
||
// Setup the Manager and Controller. Wrap the Controller Reconcile function so it writes each request to a | ||
// channel when it is finished. | ||
mgr, err := manager.New(cfg, manager.Options{}) | ||
g.Expect(err).NotTo(gomega.HaveOccurred()) | ||
c := mgr.GetClient() | ||
|
||
recFn, requests := SetupTestReconcile(&ReconcileExperiment{ | ||
Client: mgr.GetClient(), | ||
scheme: mgr.GetScheme(), | ||
ManagerClient: mc, | ||
Suggestion: suggestion, | ||
Generator: generator, | ||
updateStatusHandler: func(instance *experimentsv1alpha2.Experiment) error { | ||
if !instance.IsCreated() { | ||
t.Errorf("Expected got condition created") | ||
} | ||
return nil | ||
}, | ||
}) | ||
g.Expect(add(mgr, recFn)).NotTo(gomega.HaveOccurred()) | ||
|
||
stopMgr, mgrStopped := StartTestManager(mgr, g) | ||
|
||
defer func() { | ||
close(stopMgr) | ||
mgrStopped.Wait() | ||
}() | ||
|
||
// Create the Trial object and expect the Reconcile and Deployment to be created | ||
err = c.Create(context.TODO(), instance) | ||
// The instance object may not be a valid object because it might be missing some required fields. | ||
// Please modify the instance object by adding required fields and then remove the following if statement. | ||
if apierrors.IsInvalid(err) { | ||
t.Logf("failed to create object, got an invalid object error: %v", err) | ||
return | ||
} | ||
g.Expect(err).NotTo(gomega.HaveOccurred()) | ||
defer c.Delete(context.TODO(), instance) | ||
g.Eventually(requests, timeout).Should(gomega.Receive(gomega.Equal(expectedRequest))) | ||
} | ||
|
||
func newFakeInstance() *experimentsv1alpha2.Experiment { | ||
return &experimentsv1alpha2.Experiment{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: experimentName, | ||
Namespace: namespace, | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.