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

Functional tests in golang #518

Closed
wants to merge 2 commits into from

Conversation

procrypt
Copy link
Contributor

@procrypt procrypt commented Mar 27, 2017

This is the work I had done last week for writing functional test in golang. Here I am providing the output.json file to ioutil.ReadFile and then comparing it with the stdout of kompose convert.

In context to #432
@kadel @cdrage @containscafeine Let me know if this is the correct way to proceed.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Mar 27, 2017
@cdrage
Copy link
Member

cdrage commented Mar 29, 2017

@procrypt

This looks great to me! 👍 Awesome work!

Just missing ExpectFailure right?

@procrypt
Copy link
Contributor Author

procrypt commented Apr 3, 2017

@cdrage Thanks. I'll finish it soon ☺️

@procrypt procrypt force-pushed the functional_tests branch 3 times, most recently from 82aedf2 to 96e5705 Compare April 17, 2017 04:48
@procrypt
Copy link
Contributor Author

@cdrage Please review.

func main() {
ExpectSuccessK8s()
ExpectSuccessOpenShift()
ExpectSuccessAndWarningK8s()
Copy link
Member

Choose a reason for hiding this comment

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

gofmt issue?

Copy link
Member

Choose a reason for hiding this comment

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

hence travis failing

@cdrage
Copy link
Member

cdrage commented Apr 26, 2017

Travis still failing / not working :(

script/test/cmd/tests.go:121: not enough arguments in call to ExpectSuccessK8s
script/test/cmd/tests.go:122: not enough arguments in call to ExpectSuccessOpenShift
script/test/cmd/tests.go:123: not enough arguments in call to ExpectSuccessAndWarningK8s
script/test/cmd/tests.go:124: not enough arguments in call to ExpectSuccessAndWarningOpenShift
script/test/cmd/tests.go:125: not enough arguments in call to ExpectFailureK8s
script/test/cmd/tests.go:126: not enough arguments in call to ExpectFailureOpenShift

ping @procrypt

"strings"
)

func ExpectSuccessK8s(dockerComposeFile, result string) {
Copy link
Contributor

Choose a reason for hiding this comment

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

How about prefixing the test cases with Test?

ExpectSuccessAndWarningOpenShift()
ExpectFailureK8s()
ExpectFailureOpenShift()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd highly suggest doing this using the testing library. Please go through - https://golang.org/pkg/testing/

Copy link
Contributor

@concaf concaf left a comment

Choose a reason for hiding this comment

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

@procrypt nice work. Wanted to know what is the scope of these tests, have you moved all the kompose convert tests to golang, or just a few?

ExpectSuccessAndWarningOpenShift()
ExpectFailureK8s()
ExpectFailureOpenShift()
}
Copy link
Contributor

@concaf concaf Apr 26, 2017

Choose a reason for hiding this comment

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

It would also be great if you could do it using the golang subtests way, please read about it, and you could also use this as a reference - https://github.com/redhat-developer/opencompose/blob/master/pkg/encoding/v1/encoding_test.go
Check for the use of tt.Run() in this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@containscafeine These tests are just comparing the output of kompose convert, so I recommended we use these tests like the way they are.

@procrypt
Copy link
Contributor Author

procrypt commented May 2, 2017

@containscafeine I have moved all kompose convert test to golang.

@procrypt
Copy link
Contributor Author

procrypt commented May 8, 2017

Ping @cdrage @surajssd

@procrypt procrypt force-pushed the functional_tests branch 4 times, most recently from f973b17 to 3e16596 Compare May 8, 2017 13:16
@cdrage
Copy link
Member

cdrage commented May 8, 2017

@procrypt Tests still failing :(

@procrypt procrypt force-pushed the functional_tests branch 6 times, most recently from a50c24f to a06e5ac Compare May 9, 2017 06:01
@procrypt procrypt force-pushed the functional_tests branch 5 times, most recently from 1b11ec1 to 6b44f13 Compare June 1, 2017 06:45
@procrypt
Copy link
Contributor Author

procrypt commented Jun 1, 2017

@cdrage Done.

Copy link
Contributor

@concaf concaf left a comment

Choose a reason for hiding this comment

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

Instead of defining so many functions for every kompose command, it'd be great if we use one function signature to encompass all/most of the kompose CLI options, WDYT?

if err != nil || fileNotExist(cmd) {
home := os.Getenv("HOME")
if home == "" {
fmt.Println("No $HOME environment variable found")
Copy link
Contributor

Choose a reason for hiding this comment

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

@procrypt did you make any changes to this? The error is still not getting handled, what am I missing?

cmdArgs := []string{"rev-parse", "--abbrev-ref", "HEAD"}
cmdOut, err := exec.Command(cmdName, cmdArgs...).CombinedOutput()
if err != nil {
fmt.Println("")
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we printing here?

}

//UpdateUri Replaces variables with current branch and uri
func UpdateURI(uri, branch, inputfile, output string) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

So, currently this function is tied to replacing only uri and branch, what do you think about making this more generic?
So, as an input we accept a map[string]string, in which pass key value pairs that we want to replace, which in this case will be, "%URI%": uri, and "%REF", branch, and then we iterate over the map and replace all the occurrences; this way we can replace any parameter from now.

cmdArgs := []string{"remote", "get-url", "origin"}
cmdOut, err := exec.Command(cmdName, cmdArgs...).CombinedOutput()
if err != nil {
fmt.Println("")
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we printing here?

if err != nil {
return errors.Wrapf(err, "Error in %s application", file[1])
}
er := ioutil.WriteFile(outFile, out, 0644)
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's do err here, and reuse the err variable already created without using :=

cmdArgs := []string{command, "--provider", provider, "-f", dockerComposeFile, "--stdout", "-j"}
out, err := exec.Command(cmdName, cmdArgs...).CombinedOutput()
if err != nil {
fmt.Println("\x1b[31;1m===> Test Fail <===\x1b[0m")
Copy link
Contributor

Choose a reason for hiding this comment

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

"Test Failed"

}

// Kompose command
func Kompose(command, provider, dockerComposeFile, result string) (cmd, output string, error error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think about returning and accepting pointers to string instead of values of string?

Copy link
Contributor

Choose a reason for hiding this comment

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

Same for all the functions

}

// Kompose command for Multiple files
func MultipleFiles(command, provider, dockerComposeFileOne, dockerComposeFiletwo, result string) (cmd, output string, error error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

There is a lot of repeated code here; so, if I understand correctly, this function is the same as the function above, but accepts 2 docker compose files.
So, how about removing this and refactoring the function above to accept a []string as docker compose file and iterate on it. This way we can pass one or as many docker compose files that we want, without having to define the function again.

Copy link
Contributor Author

@procrypt procrypt Jun 5, 2017

Choose a reason for hiding this comment

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

[]string will not work here as we provide multiple compose files as f <file1> -f <file2> not as -f <file1> <file2>

}

// Kompose command for bundle
func KomposeBundle(command, dockerComposeFile, result string) (cmd, output string, error error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Even for this, we should have one Kompose function to which we should be able to pass which kompose subcommand to run, and if we pass bundle there, then the --bundle flag should get substituted accordingly.
WDYT?

return cmd, output, nil
}

//GenerateArtifacts generates artifacts in file with -o command
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above

procrypt added a commit to procrypt/kompose that referenced this pull request Jun 6, 2017
@procrypt procrypt mentioned this pull request Jun 6, 2017
@procrypt
Copy link
Contributor Author

procrypt commented Jun 7, 2017

@containscafeine review please.

procrypt added a commit to procrypt/kompose that referenced this pull request Jun 12, 2017
added functional in golang for the test cases present in script/test/cmd/test.sh
moved fixtures from script/test to script/test/cmd because according to the go best pactices fixtures should be in the same directory where the test files are
@kadel
Copy link
Member

kadel commented Jun 12, 2017

Interesting, If I run make test-cmd couple times in the row, somethings "BuildConfig" test fails

@procrypt
Copy link
Contributor Author

@kadel this is because of the environment variables, PR #631 will fix this.

procrypt added a commit to procrypt/kompose that referenced this pull request Jun 12, 2017
@kadel
Copy link
Member

kadel commented Jun 12, 2017

@kadel this is because of the environment variables, PR #631 will fix this.

But it's affecting only BuildConfig and nothing else

Copy link
Member

@kadel kadel left a comment

Choose a reason for hiding this comment

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

This is just a first part, haven looked at everything yet ;-)

if err != nil || fileNotExist(cmd) {
home := os.Getenv("HOME")
if home == "" {
fmt.Println("No $HOME environment variable found")
Copy link
Member

Choose a reason for hiding this comment

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

Why is $HOME tested?
Haven't found anything that would depend on $HOME

"testing"
)

func fileNotExist(path string) bool {
Copy link
Member

Choose a reason for hiding this comment

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

why this function even exists?
it just call sand verifies findExectuable, that function could be called directly

if m := d.Mode(); !m.IsDir() {
return nil
}
return os.ErrPermission
Copy link
Member

Choose a reason for hiding this comment

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

This function is called findExecutable but all it does is it verifies that file is not a dir.
And if its dir it returns osErrPermission, why?

}

//Git get the branch
func Git() (branch string, error error) {
Copy link
Member

Choose a reason for hiding this comment

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

We already have function getGitCurrentBranch in openshift.go that is doing a similar thing.
It would be better to reuse that. (may require small refactoring and should be handled in separate PR). We could put all git related stuff into new 'git' package.

}

//Get origin
func GitOrigin() (origin, branch string, error error) {
Copy link
Member

Choose a reason for hiding this comment

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

again, this might be similar to "getGitCurrentRemoteURL" in openshift.go

}

// Kompose command for buildContext
func KomposeCommand(command, provider, outFile, dockerComposeFile string) (error error) {
Copy link
Member

Choose a reason for hiding this comment

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

this name is ultra confusing :-)

}

//Exec runs the kompose command
func Exec(cmdName string, cmdArgs, dockerComposeFiles []string) (cmd string, err error) {
Copy link
Member

Choose a reason for hiding this comment

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

i don't think this function is even needed

@fejta-bot
Copy link

Issues go stale after 90d of inactivity.
Mark the issue as fresh with /remove-lifecycle stale.
Stale issues rot after an additional 30d of inactivity and eventually close.

Prevent issues from auto-closing with an /lifecycle frozen comment.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or @fejta.
/lifecycle stale

@k8s-ci-robot k8s-ci-robot added the lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. label Dec 27, 2017
@fejta-bot
Copy link

Stale issues rot after 30d of inactivity.
Mark the issue as fresh with /remove-lifecycle rotten.
Rotten issues close after an additional 30d of inactivity.

If this issue is safe to close now please do so with /close.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/lifecycle rotten
/remove-lifecycle stale

@k8s-ci-robot k8s-ci-robot added lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed. and removed lifecycle/stale Denotes an issue or PR has remained open with no activity and has become stale. labels Jan 26, 2018
@fejta-bot
Copy link

Rotten issues close after 30d of inactivity.
Reopen the issue with /reopen.
Mark the issue as fresh with /remove-lifecycle rotten.

Send feedback to sig-testing, kubernetes/test-infra and/or fejta.
/close

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lifecycle/rotten Denotes an issue or PR that has aged beyond stale and will be auto-closed.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants