Skip to content
This repository has been archived by the owner on Nov 9, 2020. It is now read-only.

Add swarm_test to e2e test suite #1309

Merged
merged 8 commits into from
Jun 2, 2017
Merged

Add swarm_test to e2e test suite #1309

merged 8 commits into from
Jun 2, 2017

Conversation

shaominchen
Copy link
Contributor

@shaominchen shaominchen commented May 30, 2017

Add swarm_test to e2e test suite: fixes issue #1249.

Passed all e2e tests locally.

@shuklanirdesh82
Copy link
Contributor

@shaominchen can you please increase default timeout for running our e2e test to 30 mins -timeout 30m?

Copy link
Contributor

@shuklanirdesh82 shuklanirdesh82 left a comment

Choose a reason for hiding this comment

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

Overall looks OK to me, supplying some comments for your review.

log.Printf("START: swarm_test.TestDockerSwarm")

fullVolumeName := verification.GetFullVolumeName(s.master, s.volumeName)
opts := "--replicas 1 --mount type=volume,source=" + fullVolumeName + ",target=/vol,volume-driver=vsphere busybox tail -f /dev/null"
Copy link
Contributor

Choose a reason for hiding this comment

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

minor: better to reuse const from https://github.com/vmware/docker-volume-vsphere/blob/master/tests/constants/dockercli/cmd.go e.g. TestContainer, vDVSPluginName (need to export vDVSPluginName)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure.


containerName, err = verification.GetContainerName(host, s.serviceName+".1")
c.Assert(err, IsNil, Commentf("Failed to retrieve container name: %s", containerName))
out, err = dockercli.StopService(host, containerName)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: new line is required to maintain consistency.

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 intention here is to keep the logic of one test step in one single block.

Copy link
Contributor

Choose a reason for hiding this comment

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

Please see issue #1315, worth adding a test case that verifies vsphere volumes as "external" in the compose file and verify that the volume on a particular datastore is attached to the VM/container.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

First of all, if we need any test to cover new scenarios, that should be done in a separate PR. Moreover, I still don't follow why we need a e2e test for #1315. We can discuss that in the issue itself instead of in this PR.

@@ -97,6 +100,75 @@ func GetVolumePropertiesDockerCli(volName string, hostname string) string {
return op
}

// GetContainerName returns full container name based on given short name
func GetContainerName(hostName, shortName string) (string, error) {
cmd := dockercli.ListContainers + "--filter name='" + shortName + "' --format '{{.Names}}'"
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should create filter constants for docker volume properties .. e.g. --format '{{.Names}} .. it will be easier to make change in one shot to sync with docker framework's change.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I didn't define constant for "--format" because we are using quite some different formats: .Name, .Names, .Status, etc. As for "--filter", it needs a input parameter - defining a constant like "--filter name='" looks weird, as we need attach the matching quote ' separately.


// allContainersRunning returns true if all replicated containers are up and running; false otherwise.
func allContainersRunning(dockerHosts []string, serviceName string, replicas int) (bool, string) {
//TODO: It looks like all containers will always be spawned on one node. If this assumption
Copy link
Contributor

@shuklanirdesh82 shuklanirdesh82 Jun 1, 2017

Choose a reason for hiding this comment

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

It is better to avoid TODO in first revision ... do we still need this TODO?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, removed it for now.

cmd := dockercli.ListVolumes + "--filter name='" + volumeName + "' --format '{{.Name}}'"
fullName, err := ssh.InvokeCommand(hostName, cmd)
if err != nil {
log.Println(err)
Copy link
Contributor

Choose a reason for hiding this comment

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

this is redundant .. need to be removed.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed.

}

// allContainersRunning returns true if all replicated containers are up and running; false otherwise.
func allContainersRunning(dockerHosts []string, serviceName string, replicas int) (bool, string) {
Copy link
Contributor

Choose a reason for hiding this comment

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

allContainersRunning => areAllContainersRunning something more readable

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure - renamed it to isContainerRunning.

for _, host := range dockerHosts {
out, err := GetAllContainers(host, serviceName)
if err != nil {
log.Println(err)
Copy link
Contributor

Choose a reason for hiding this comment

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

this is redundant ... invokCommand routine takes care of printing error message.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed.


// VerifyDockerContainer returns true and the host IP if the containers are running on one of
// the given docker hosts with specified replicas; otherwise returns false and empty string.
func VerifyDockerContainer(dockerHosts []string, serviceName string, replicas int) (bool, string) {
Copy link
Contributor

@shuklanirdesh82 shuklanirdesh82 Jun 1, 2017

Choose a reason for hiding this comment

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

can you please help me to understand the advantage of returning host value here? IMO, there is no need but will look forward to your response.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please refer to swarm_test line 114 - the returned host is needed for the next steps: query the container name and stop the service on this specific host. My first version of this function does not return host actually. But the test failed in CI setup because the container might be spawned in any hosts. So when verifying the running containers, I need to return the host and then run subsequent steps on this specific host.

Copy link
Contributor

Choose a reason for hiding this comment

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

got it. Thanks @shaominchen for the explanation.

log.Printf("Checking running containers for docker service [%s] on docker hosts: %v\n", serviceName, dockerHosts)

//TODO: Need to implement generic polling logic for better reuse
for attempt := 0; attempt < maxAttempt; attempt++ {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would suggest to move out this code block into another method and put in place at misc.

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 should refactor this (and existing VerifyDetachedStatus) in a separate change.


// VerifyDockerService returns true if the given service is running on
// the specified VM with specified replicas; false otherwise.
func VerifyDockerService(hostName, serviceName string, replicas int) bool {
Copy link
Contributor

Choose a reason for hiding this comment

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

as this method is returning bool how about renaming to IsDockerServiceVerified?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed it to IsDockerServiceRunning.

}

// GetAllContainers returns all running containers on the give host based on the filtering criteria
func GetAllContainers(hostName, filter string) (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.

I think /volumeproperties.go is not the better home to hold such utils. I would suggest to create another file or place into existing suitable place.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Make sense. Will add a separate dockercontainer.go file.

Copy link
Contributor

@pshahzeb pshahzeb left a comment

Choose a reason for hiding this comment

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

Overall great.
I have a few minor comments.


import (
"log"

Copy link
Contributor

Choose a reason for hiding this comment

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

nit: no newline needed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure why gofmt does not take care of this. Fixed.


// ListService lists the tasks of a docker service
func ListService(ip, name string) (string, error) {
log.Printf("Listing docker services running on VM [%s]\n", ip)
Copy link
Contributor

Choose a reason for hiding this comment

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

minor: can log the service name as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure.

log.Println(err)
continue
}
if out != "" {
Copy link
Contributor

Choose a reason for hiding this comment

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

as per go suggestions, we can avoid nesting here.

if out == "" {
    continue
}
....
for loop...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

s.master = inputparams.GetSwarmManager1()
s.worker1 = inputparams.GetSwarmWorker1()
s.worker2 = inputparams.GetSwarmWorker2()
s.dockerHosts = []string{s.master, s.worker1, s.worker2}
Copy link
Contributor

Choose a reason for hiding this comment

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

if you think these vars need to be read just once for the entire test suite, you can have them in SetUpSuite instead of SetupTest.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure.

Copy link
Contributor

@govint govint left a comment

Choose a reason for hiding this comment

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

Comments around common code mostly and possibly consider a test to verify vsphere volumes defined as external in the compose file for a service.
[Sam] This should be taken care of in separate tests.

s.master = inputparams.GetSwarmManager1()
s.worker1 = inputparams.GetSwarmWorker1()
s.worker2 = inputparams.GetSwarmWorker2()
s.dockerHosts = []string{s.master, s.worker1, s.worker2}
Copy link
Contributor

Choose a reason for hiding this comment

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

These should be a function in inputparams that return a map of these values vs. each test duplicating this their setup functions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will add a GetSwarmNodes function in inputparams. I don't follow why we need a map here.

@@ -0,0 +1,68 @@
// Copyright 2017 VMware, Inc. All Rights Reserved.
//
Copy link
Contributor

Choose a reason for hiding this comment

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

Pls. make the changes for test infa/framework as a separate PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

As we discussed offline, we should keep each PR small enough so that it’s easier to review and also keep the dependency to the minimum. The current PR is probably a special case as there's only one test case, but it's still pretty big and complicated. Since the review is almost done, I'd prefer to keep the current PR as is instead of wasting time to split it into two.


containerName, err = verification.GetContainerName(host, s.serviceName+".1")
c.Assert(err, IsNil, Commentf("Failed to retrieve container name: %s", containerName))
out, err = dockercli.StopService(host, containerName)
Copy link
Contributor

Choose a reason for hiding this comment

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

Please see issue #1315, worth adding a test case that verifies vsphere volumes as "external" in the compose file and verify that the volume on a particular datastore is attached to the VM/container.

Copy link
Contributor

@shuklanirdesh82 shuklanirdesh82 left a comment

Choose a reason for hiding this comment

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

LGTM! Requesting two minor comments to address.

@@ -29,10 +29,6 @@ import (
"github.com/vmware/docker-volume-vsphere/tests/utils/ssh"
)

const (
Copy link
Contributor

Choose a reason for hiding this comment

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

It is better to have constant to modify the attempt count. I would suggest to add this back; it will be easier to adjust in the future instead of skimming line of code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I removed this because there's a conflict on this constant name after splitting this file into two. Also we need to refactor this part anyway (I've already added TODO on both functions). We should have a generic poller function, which accepts a maximum time limit instead of the maximum attempts as the input.

)

// GetContainerName returns full container name based on given short name
func GetContainerName(hostName, shortName string) (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.

GetContainerName & GetAllContainers should move out from verifier package ... both of them spoils the context of verifier .. /util/dockercli would be a better home.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good idea! Fixed.

Copy link
Contributor

@shuklanirdesh82 shuklanirdesh82 left a comment

Choose a reason for hiding this comment

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

LGTM! You may want to rebase with master to resolve merge conflict and squash unrelated commits.

@shuklanirdesh82
Copy link
Contributor

@shaominchen If this PR is targeted for #1249 ... it is better to add fixes #1249 to close the issue automatically with merge.

// 1. Create a docker service with replicas setting to 1
// 2. Verify the service is up and running with one node
// 3. Verify one container is spawned
// 5. Verify the volume is in attached status
Copy link
Contributor

Choose a reason for hiding this comment

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

The --replica option in swarm is not used to scale a stateful application. Instead, it should used to scale a stateless application. So why do we try to add the test with --replica 2 here? Any specific reason? @ashahi1

I think we should just verify the fail-over case here.

Copy link
Contributor Author

@shaominchen shaominchen Jun 1, 2017

Choose a reason for hiding this comment

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

@lipingxue Can we add this comment in the issue #601 itself? This PR is almost ready to merge. We can discuss your comment in the issue and once we have an agreement we can come back to update this test in a separate PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK. I reopened issue #601 to add my comments.

}

// isContainerRunning returns true if all replicated containers are up and running; false otherwise.
func isContainerRunning(dockerHosts []string, serviceName string, replicas int) (bool, string) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit:function name change to "IsContainerRunning", which is consistent with other func names

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is a convention in Go language: unexported identifiers should start with small letter; exported identifiers should start with capital letter.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok

Copy link
Contributor

@pshahzeb pshahzeb left a comment

Choose a reason for hiding this comment

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

LGTM

@shuklanirdesh82
Copy link
Contributor

@shaominchen Please revisit the commit history and clean that up correctly.

Copy link
Contributor

@shuklanirdesh82 shuklanirdesh82 left a comment

Choose a reason for hiding this comment

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

Please rebase correctly

Shaomin Chen added 6 commits June 1, 2017 17:09
@@ -287,7 +287,7 @@ CLEANESX_SH := $(DEPLOY_TOOLS) cleanesx
deploy-esx: clean-esx
$(DEPLOY_ESX_SH) "$(ESX)" "$(VIB_BIN)"

VMS= $(VM1) $(VM2) $(WORKER2)
VMS= $(VM1) $(VM2)
Copy link
Contributor

@shuklanirdesh82 shuklanirdesh82 Jun 2, 2017

Choose a reason for hiding this comment

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

this is required, isn't it? (I guess it's a victim of bad merge)

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, will fix.

@shuklanirdesh82 shuklanirdesh82 merged commit 43f26c0 into master Jun 2, 2017
@shuklanirdesh82 shuklanirdesh82 deleted the swarm_test branch June 2, 2017 03:47
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants