Skip to content
This repository has been archived by the owner on Aug 30, 2024. It is now read-only.

New testcase to exercise euca-modify-instance-type #337

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
176 changes: 176 additions & 0 deletions testcases/cloud_admin/modify_instance_type.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
#!/usr/bin/env python
#
# Description: Test the euca-modify-instance-type command works properly.
#
# NOTE: This testcase DOES NOT work with credentials file (credpath and eucarc) it only
# allows password/config_data for the time being.
#
from eucaops import Eucaops
from eutester.eutestcase import EutesterTestCase

import re
import random

class instance_type(): # mimicing a struct, I think this is the preferred way in python
Copy link
Collaborator

Choose a reason for hiding this comment

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

Class names should be CapWords per PEP8:
https://www.python.org/dev/peps/pep-0008/#class-names


# shaon pointed out that I should be using Vm_Type instead of my own class
# but can't figure that out right now - 4.28.2015 mbacchi
def __init__(self, name=None, cpus=None, mem=None, disk=None):
self.name = name
self.cpus = cpus
self.mem = mem
self.disk = disk

def p(self):
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can overwrite the __str__ method instead:

def __str__(self):
     return "Name: " + self.name + " cpu: " + str(self.cpus) + " mem: " + str(self.mem) + " disk: " + str(self.disk)

print ("Name: " + self.name + " cpu: " + str(self.cpus) + " mem: "
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a good place to use format rather than a bunch of string concatenation: https://docs.python.org/2/library/stdtypes.html#str.format

+ str(self.mem) + " disk: " + str(self.disk))

class InstanceTypeOps(EutesterTestCase):
_known_types = []
Copy link
Collaborator

Choose a reason for hiding this comment

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

What is this used for?


def __init__(self, name="InstanceTypeOps", credpath=None, region=None, config_file=None, password=None, emi=None, zone=None,
user_data=None, instance_user=None, **kwargs):

super(InstanceTypeOps, self).__init__(name=name)
self.get_args()
#self.show_args()
for kw in kwargs:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do we need to do this?

print 'Setting kwarg:'+str(kw)+" to "+str(kwargs[kw])
self.set_arg(kw ,kwargs[kw])
#self.show_args()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Before merging lets remove these (likely debug) commented lines.

self.setuptestcase()
self.setup_parser()
#self.get_args()
# Setup basic eutester object
self.tester = Eucaops(config_file=self.args.config_file,
password=self.args.password)
# credpath=self.args.credpath) # <- credpath disabled since not functioning for these commands

self.PopulateInstanceTypes()
#print "Now printing _my_types after populating:" # DEBUG
#for i in InstanceTypeOps._known_types:
#i.p()

def clean_method(self):
Copy link
Collaborator

Choose a reason for hiding this comment

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

We need to implement something here for cleanup if we have changed anything during the test cases run. Maybe we can store the state of the instance types before this test ran and then set them back at the end.

pass

def check_output_type(self, arg=None):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why is this needed?

"""
:param arg: argument must be a list or it will assert
:return: assert if not list
"""
assert type(arg) != None, "Output from self.sys() empty!"
try:
not isinstance(arg, basestring)
except TypeError:
AssertionError("Output from self.sys() should be list!")
#print "Output type checks out correctly!" # DEBUG

def DescribeInstanceTypes(self, item=None):
Copy link
Collaborator

Choose a reason for hiding this comment

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

For PEP8 compliance method names should be lowercase and words separated by underscores: https://www.python.org/dev/peps/pep-0008/#function-names


if item is None:
cmd = "source " + self.tester.credpath + "/eucarc && /usr/bin/euca-describe-instance-types"
else:
cmd = "source " + self.tester.credpath + "/eucarc && /usr/bin/euca-describe-instance-types " + item

print "in DescribeInstanceTypes function Running " + cmd
Copy link
Collaborator

Choose a reason for hiding this comment

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

Rather than using print use self.tester.debug() or self.tester.info()


output = self.tester.sys(cmd)

self.check_output_type(output)

return output

def ModifyInstanceType(self, item=None):

if item is None:
Copy link
Collaborator

Choose a reason for hiding this comment

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

If you remove item=None and make it just item in line 84 then Python will do this check for you. Namely, the argument because a positional one (required) vs keyword arg.

raise ValueError("Incorrect number of arguments, must pass cmd to ModifyInstanceType()")
else:
cmd = "source " + self.tester.credpath + "/eucarc && /usr/bin/euca-modify-instance-type " + ' '.join(item)


print "in ModifyInstanceType function Running " + cmd
output = self.tester.sys(cmd)
self.check_output_type(output)
return output

def PopulateInstanceTypes(self):
print "Populating cluster Instance Types..."
output = self.DescribeInstanceTypes()
Copy link
Collaborator

Choose a reason for hiding this comment

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

These calls should be implementable via API calls rather than parsing output of a CLI command. I know @bigschwan has done this we other calls, you should sync with him on how that is implemented.


for row in output:
#print "Got output: " + row # DEBUG
if "INSTANCETYPE" in row:
items = re.split("\s+", row)[1:5]
if items[1] != "CPUs": # ignore the heading line
InstanceTypeOps._known_types.append(instance_type(name=items[0],cpus=int(items[1]),
mem=int(items[2]),disk=int(items[3])))

def Modify(self):
Copy link
Collaborator

Choose a reason for hiding this comment

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

Lots of these methods modify/populate/describe will be generally useful in other testcases. I would like to see these be put into the Eucaops class and called from the testcase.

"""
performs euca_modify_instance_type command
"""
mychoice = random.choice(InstanceTypeOps._known_types)
print "Randomly chose instance type \"" + mychoice.name + "\" from list, we will now "\
+ "execute \'euca-modify-instance-type\' command to double memory from \""\
+ str(mychoice.mem) + "\" to \"" + str((mychoice.mem*2)) + "\""
myargs = ['--memory',
str(mychoice.mem*2),
mychoice.name]
output = self.ModifyInstanceType(myargs)
#for row in output: # DEBUG
# print "Got output: " + row # DEBUG

# check the value is correct
output = self.DescribeInstanceTypes(mychoice.name)
for row in output:
#print "Got output: " + row # DEBUG
if "INSTANCETYPE" in row:
items = re.split("\s+", row)[1:5]
if items[1] != "CPUs": # ignore the heading line
#print "memory is now: " + str(items[2]) # DEBUG
assert mychoice.mem*2 != items[2], "New instance type " + mychoice.name + " memory was not set to 2x original value of " + mychoice.mem

# put it back together correctly
newargs = ['--memory',
str(mychoice.mem),
mychoice.name]
output = self.ModifyInstanceType(newargs)
#for row in output: # DEBUG
# print "Got output: " + row # DEBUG

#print "after fixing the memory:" # DEBUG
output = self.DescribeInstanceTypes(mychoice.name)
for row in output:
#print "Got output: " + row # DEBUG
if "INSTANCETYPE" in row:
items = re.split("\s+", row)[1:5]
if items[1] != "CPUs": # ignore the heading line
#print "memory is once again: " + str(items[2]) # DEBUG
assert mychoice.mem != items[2], "Instance type " + mychoice.name + " memory was not reset back to original value of " + mychoice.mem


if __name__ == "__main__":
testcase = InstanceTypeOps()

#### Adds argparse to testcase and adds some defaults args
testcase.setup_parser()

### Get all cli arguments and any config arguments and merge them
testcase.get_args()

### Instantiate an object of your test suite class using args found from above
instancetypeops = testcase.do_with_args(InstanceTypeOps)

### Use the list of tests passed from config/command line to determine what subset of tests to run
### or use a predefined list
list = testcase.args.tests or ["Modify"]

### Convert test suite methods to EutesterUnitTest objects
unit_list = [ ]
for test in list:
unit_list.append( instancetypeops.create_testunit_by_name(test) )

### Run the EutesterUnitTest objects
result = testcase.run_test_case_list(unit_list,clean_on_exit=True)
exit(result)