-
Notifications
You must be signed in to change notification settings - Fork 459
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
175 additions
and
15 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
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,14 @@ | ||
apiVersion: apiextensions.k8s.io/v1beta1 | ||
kind: CustomResourceDefinition | ||
metadata: | ||
name: trials.kubeflow.org | ||
spec: | ||
group: kubeflow.org | ||
version: v1alpha2 | ||
scope: Namespaced | ||
subresources: | ||
status: {} | ||
names: | ||
kind: Trial | ||
singular: trial | ||
plural: trials |
76 changes: 76 additions & 0 deletions
76
pkg/controller/v1alpha2/trial/trial_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,76 @@ | ||
/* | ||
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 trial | ||
|
||
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")}, | ||
} | ||
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 | ||
} |
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,85 @@ | ||
package trial | ||
|
||
import ( | ||
"testing" | ||
"time" | ||
|
||
"github.com/onsi/gomega" | ||
"golang.org/x/net/context" | ||
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" | ||
|
||
trialsv1alpha2 "github.com/kubeflow/katib/pkg/api/operators/apis/trial/v1alpha2" | ||
) | ||
|
||
const ( | ||
trialName = "foo" | ||
namespace = "default" | ||
|
||
timeout = time.Second * 5 | ||
) | ||
|
||
var expectedRequest = reconcile.Request{NamespacedName: types.NamespacedName{Name: trialName, Namespace: namespace}} | ||
|
||
func TestCreate(t *testing.T) { | ||
g := gomega.NewGomegaWithT(t) | ||
instance := newFakeTrial() | ||
|
||
// 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(newReconciler(mgr)) | ||
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 newFakeTrial() *trialsv1alpha2.Trial { | ||
t := &trialsv1alpha2.Trial{ | ||
ObjectMeta: metav1.ObjectMeta{ | ||
Name: trialName, | ||
Namespace: namespace, | ||
}, | ||
Spec: trialsv1alpha2.TrialSpec{ | ||
RunSpec: ` | ||
apiVersion: "kubeflow.org/v1beta1" | ||
kind: "TFJob" | ||
metadata: | ||
name: "dist-mnist-for-e2e-test" | ||
spec: | ||
tfReplicaSpecs: | ||
Worker: | ||
replicas: 1 | ||
restartPolicy: Never | ||
template: | ||
spec: | ||
containers: | ||
- name: tensorflow | ||
image: gaocegege/mnist:1`, | ||
}, | ||
} | ||
return t | ||
} |