Skip to content

pkg/test: add in-cluster/in-image testing support #469

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

Merged
merged 39 commits into from
Sep 25, 2018

Conversation

AlexNPavel
Copy link
Contributor

Issue #435

@AlexNPavel AlexNPavel force-pushed the incluster-test branch 2 times, most recently from 749d6e0 to 0cbc804 Compare September 11, 2018 00:25
@@ -42,12 +56,79 @@ For example:
`,
Run: buildFunc,
}
buildCmd.Flags().BoolVarP(&enableTests, "enable-tests", "e", false, "Enable in-cluster testing by adding test binary to the image")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are keeping the default false for now and plan on changing it? I think eventually this should be a default of true? Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, we will keep it as default false. The SDK does not create any default tests for operators and the build would fail in that case. This is why we need a user to confirm that they have tests that they want to include. The test binary is also 34 MB, which may be undesirable to include by default.

dbcmd.Env = append(os.Environ(), fmt.Sprintf("IMAGE=%v", image))
intermediateImageName := image
if enableTests {
if namespacedManBuild == "" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if pulling this code block into its own function may make this more readable?

@AlexNPavel AlexNPavel changed the title pkg/test: add in-cluster/in-image testing support [WIP] pkg/test: add in-cluster/in-image testing support Sep 12, 2018
The cluster test has defers that need to run on error, which
would not run if cmdError is used due to its use of os.Exit().
Instead, we can just return an error, which allows the defer
functions to run.
This adds tests for the new incluster image testing mode as well as
fixes some bugs that this test exposed
We don't need to do any extra operations anymore if a user does
not supply a namespaced manifest path, so we can just use a default
string
@AlexNPavel AlexNPavel changed the title [WIP] pkg/test: add in-cluster/in-image testing support pkg/test: add in-cluster/in-image testing support Sep 14, 2018
command: ["/go-test.sh"]
resources:
requests:
cpu: 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should specify resource requests by default. This could prevent the pod from being scheduled onto a node if there isn't enough cpu.
By not setting a default, the pod will either take on the default request and limit enforced by the namespace, or use as much as is available.

func renderTestManifest(image string) error {
namespacedBytes, err := ioutil.ReadFile(namespacedManBuild)
if err != nil {
log.Fatalf("could not read rbac manifest: %v", err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not rbac manifest(at least not in the test cluster case).
log.Fatalf("could not read namespaced manifest: %v", err)

log.Fatalf("could not read rbac manifest: %v", err)
}
if err = generator.RenderTestYaml(cmdutil.GetConfig(), image); err != nil {
cmdError.ExitWithError(cmdError.ExitError, fmt.Errorf("failed to generate deploy/test-pod.yaml: (%v)", err))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use log.Fatalf() instead of cmdError.ExitWithError(). It's the exact same thing except it returns a specific error code.
We're going to remove cmdError.ExitWithError since returning error codes isn't as useful as we thought initially, and we never specified more than two codes.

if err = generator.RenderTestYaml(cmdutil.GetConfig(), image); err != nil {
cmdError.ExitWithError(cmdError.ExitError, fmt.Errorf("failed to generate deploy/test-pod.yaml: (%v)", err))
}
return verifyDeploymentImage(namespacedBytes, image)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only error renderTestManifest() returns is actually just treated as a warning that's just printed out.

genWarning := renderTestManifest(image)
if genWarning != nil {
	fmt.Printf("%s\n", genWarning)
}

For the other two errors it just fails fast with log.Fatal.
So change renderTestManifest() to not return an error.
And print the warning message from verifyDeploymentImage() either here or outside this function by just checking the error returned directly from it.

@@ -562,7 +588,12 @@ fi
: ${IMAGE:?"Need to set IMAGE, e.g. gcr.io/<repo>/<your>-operator"}

echo "building container ${IMAGE}..."
docker build -t "${IMAGE}" -f tmp/build/Dockerfile .
docker build -t "${IMAGE}" -f tmp/build/Dockerfile . --build-arg NAMESPACEDMAN=$NAMESPACEDMAN
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're no longer using this docker-build.sh script anymore right? We're just calling docker build directly in operator-sdk build.
So we should probably not generate this anymore.

return err
}
return renderWriteFile(filepath.Join(buildDir, dockerfile), "tmp/build/Dockerfile", dockerFileTmpl, dTd)
return writeFileAndPrint(filepath.Join(buildDir, goTest), buf.Bytes(), os.FileMode(int(0755)))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the constant defaultExecFileMode .

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defaultExecMode is currently set to 0744, which doesn't work for this setup. Should I change defaultExecMode to 0755?

inCluster := false
if *kubeconfigPath == "incluster" {
// Work around https://github.com/kubernetes/kubernetes/issues/40973
// See https://github.com/coreos/etcd-operator/issues/731#issuecomment-283804819
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: We can remove the etcd-operator issue link since we're linking to the upstream issue in the line above.

ImagePullPolicy: pullPolicy,
Command: []string{"/go-test.sh"},
Env: []v1.EnvVar{{
Name: "TEST_NAMESPACE",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Define this as a constant somewhere. In pkg/test probably.

@@ -114,7 +138,11 @@ func AddToFrameworkScheme(addToScheme addToSchemeFunc, obj runtime.Object) error
Global.RestMapper.Reset()
Global.DynamicClient, err = dynclient.New(Global.KubeConfig, dynclient.Options{Scheme: Global.Scheme, Mapper: Global.RestMapper})
err = wait.PollImmediate(time.Second, time.Second*10, func() (done bool, err error) {
err = Global.DynamicClient.List(goctx.TODO(), &dynclient.ListOptions{Namespace: "default"}, obj)
if Global.InCluster {
err = Global.DynamicClient.List(goctx.TODO(), &dynclient.ListOptions{Namespace: os.Getenv("TEST_NAMESPACE")}, obj)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should verify that TEST_NAMESPACE is not empty in the incluster case above, before using it here and in ctx.GetNamespace().

}
testCmd.Flags().StringVarP(&testNamespace, "namespace", "n", "default", "Namespace to run tests in")
testCmd.Flags().StringVarP(&kubeconfigCluster, "kubeconfig", "k", defaultKubeConfig, "Kubeconfig path")
testCmd.Flags().StringVarP(&imagePullPolicy, "imagePullPolicy", "i", "Always", "Set test pod image pull policy. Allowed values: Always, Never")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more nit here: Is there a reason to ask people to capitalize the words "always" and "never"? It's somewhat unusual for a CLI.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason was that they are capitalized in the config file. I could change it, or maybe use strings.ToLower(...) and support both.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've decided to support both upper and lowercase

log.Fatalf("failed to generate deploy/test-pod.yaml: (%v)", err)
}
// the error from verifyDeploymentImage is just a warning, not fatal error
fmt.Printf("%v", verifyDeploymentImage(namespacedBytes, image))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this print <nil> every time if there's no error returned by verifyDeploymentImage()?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it does; I somehow missed that. I'll put a nil check there

@@ -238,20 +266,10 @@ func MemcachedCluster(t *testing.T) {
f := framework.Global
ctx := f.NewTestCtx(t)
defer ctx.Cleanup(t)
operatorYAML, err := ioutil.ReadFile("deploy/operator.yaml")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check the returned error.

@hasbro17
Copy link
Contributor

@AlexNPavel AlexNPavel merged commit fe6d2a3 into operator-framework:master Sep 25, 2018
@AlexNPavel AlexNPavel deleted the incluster-test branch September 25, 2018 18:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants