def setUp(self): self.cloud_argv = ['--min', '1', '--max', '1', '--group', 'blargscale', '--infrastructure', 'ec2', '--machine', 'ami-ABCDEFG'] self.cluster_argv = ['--ips', 'ips.yaml'] self.function = "appscale-run-instances" # mock out all logging, since it clutters our output flexmock(AppScaleLogger) AppScaleLogger.should_receive('log').and_return() # set up phony AWS credentials for each test # ones that test not having them present can # remove them for credential in EucalyptusAgent.REQUIRED_EC2_CREDENTIALS: os.environ[credential] = "baz" os.environ['EC2_URL'] = "http://boo" # similarly, pretend that our image does exist in EC2 # and Euca fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() fake_ec2.should_receive('get_image').with_args('emi-ABCDEFG') \ .and_return('anything') flexmock(boto) boto.should_receive('connect_ec2').with_args('baz', 'baz') \ .and_return(fake_ec2) boto.should_receive('connect_euca').and_return(fake_ec2)
def setUp(self): # mock out logging, since it clutters out test output flexmock(AppScaleLogger) AppScaleLogger.should_receive('log').and_return() # next, pretend our ec2 credentials are properly set for credential in EC2Agent.REQUIRED_CREDENTIALS: os.environ[credential] = "baz" # finally, pretend that our ec2 image to use exists fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() flexmock(boto) boto.should_receive('connect_ec2').with_args( 'baz', 'baz').and_return(fake_ec2) # add in some instance variables so that we don't have # a lot IP addresses everywhere self.blank_input_yaml = None self.default_options = {'table': 'cassandra'} self.ip_1 = '192.168.1.1' self.ip_2 = '192.168.1.2' self.ip_3 = '192.168.1.3' self.ip_4 = '192.168.1.4' self.ip_5 = '192.168.1.5' self.ip_6 = '192.168.1.6' self.ip_7 = '192.168.1.7' self.ip_8 = '192.168.1.8'
def testUpWithEC2EnvironmentVariables(self): # if the user wants us to use their EC2 credentials when running AppScale, # we should make sure they get set appscale = AppScale() # Mock out the actual file reading itself, and slip in a YAML-dumped # file contents = { 'infrastructure': 'ec2', 'machine': 'ami-ABCDEFG', 'keyname': 'bookey', 'group': 'boogroup', 'min': 1, 'max': 1, 'EC2_ACCESS_KEY': 'access key', 'EC2_SECRET_KEY': 'secret key' } yaml_dumped_contents = yaml.dump(contents) self.addMockForAppScalefile(appscale, yaml_dumped_contents) # finally, pretend that our ec2 image to use exists fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() flexmock(boto) boto.should_receive('connect_ec2').with_args('access key', 'secret key') \ .and_return(fake_ec2) # finally, mock out the actual appscale-run-instances call flexmock(AppScaleTools) AppScaleTools.should_receive('run_instances') appscale.up() self.assertEquals('access key', os.environ['EC2_ACCESS_KEY']) self.assertEquals('secret key', os.environ['EC2_SECRET_KEY'])
def testUpWithEC2EnvironmentVariables(self): # if the user wants us to use their EC2 credentials when running AppScale, # we should make sure they get set appscale = AppScale() # Mock out the actual file reading itself, and slip in a YAML-dumped # file contents = { 'infrastructure' : 'ec2', 'machine' : 'ami-ABCDEFG', 'keyname' : 'bookey', 'group' : 'boogroup', 'min' : 1, 'max' : 1, 'EC2_ACCESS_KEY' : 'access key', 'EC2_SECRET_KEY' : 'secret key' } yaml_dumped_contents = yaml.dump(contents) self.addMockForAppScalefile(appscale, yaml_dumped_contents) # finally, pretend that our ec2 image to use exists fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() flexmock(boto) boto.should_receive('connect_ec2').with_args('access key', 'secret key') \ .and_return(fake_ec2) # finally, mock out the actual appscale-run-instances call flexmock(AppScaleTools) AppScaleTools.should_receive('run_instances') appscale.up() self.assertEquals('access key', os.environ['EC2_ACCESS_KEY']) self.assertEquals('secret key', os.environ['EC2_SECRET_KEY'])
def setUp(self): self.cloud_argv = [ '--min', '1', '--max', '1', '--group', 'blargscale', '--infrastructure', 'ec2', '--machine', 'ami-ABCDEFG' ] self.cluster_argv = ['--ips', 'ips.yaml'] self.function = "appscale-run-instances" # mock out all logging, since it clutters our output flexmock(AppScaleLogger) AppScaleLogger.should_receive('log').and_return() # set up phony AWS credentials for each test # ones that test not having them present can # remove them for credential in EucalyptusAgent.REQUIRED_EC2_CREDENTIALS: os.environ[credential] = "baz" os.environ['EC2_URL'] = "http://boo" # similarly, pretend that our image does exist in EC2 # and Euca fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() fake_ec2.should_receive('get_image').with_args('emi-ABCDEFG') \ .and_return('anything') fake_price = flexmock(name='fake_price', price=1.00) fake_ec2.should_receive('get_spot_price_history').and_return( [fake_price]) flexmock(boto) boto.should_receive('connect_ec2').with_args('baz', 'baz') \ .and_return(fake_ec2) boto.should_receive('connect_euca').and_return(fake_ec2)
def setUp(self): # mock out logging, since it clutters out test output flexmock(AppScaleLogger) AppScaleLogger.should_receive('log').and_return() # next, pretend our ec2 credentials are properly set for credential in EC2Agent.REQUIRED_CREDENTIALS: os.environ[credential] = "baz" # finally, pretend that our ec2 image to use exists fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() flexmock(boto) boto.should_receive('connect_ec2').with_args('baz', 'baz').and_return(fake_ec2) # add in some instance variables so that we don't have # a lot IP addresses everywhere self.blank_input_yaml = None self.default_options = { 'table' : 'cassandra' } self.ip_1 = '192.168.1.1' self.ip_2 = '192.168.1.2' self.ip_3 = '192.168.1.3' self.ip_4 = '192.168.1.4' self.ip_5 = '192.168.1.5' self.ip_6 = '192.168.1.6' self.ip_7 = '192.168.1.7' self.ip_8 = '192.168.1.8'
def testUpWithCloudAppScalefile(self): # calling 'appscale up' if there is an AppScalefile present # should call appscale-run-instances with the given config # params. here, we assume that the file is intended for use # on EC2 appscale = AppScale() # Mock out the actual file reading itself, and slip in a YAML-dumped # file contents = { 'infrastructure' : 'ec2', 'machine' : 'ami-ABCDEFG', 'keyname' : 'bookey', 'group' : 'boogroup', 'min' : 1, 'max' : 1 } yaml_dumped_contents = yaml.dump(contents) self.addMockForAppScalefile(appscale, yaml_dumped_contents) # throw in some mocks for the argument parsing for credential in EC2Agent.REQUIRED_CREDENTIALS: os.environ[credential] = "baz" # finally, pretend that our ec2 image to use exists fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() flexmock(boto) boto.should_receive('connect_ec2').with_args('baz', 'baz').and_return(fake_ec2) # finally, mock out the actual appscale-run-instances call flexmock(AppScaleTools) AppScaleTools.should_receive('run_instances') appscale.up()
def setUp(self): self.cloud_argv = ['--min', '1', '--max', '1', '--group', 'blargscale', '--infrastructure', 'ec2', '--machine', 'ami-ABCDEFG', '--zone', 'my-zone-1b'] self.cluster_argv = ['--ips', 'ips.yaml'] self.function = "appscale-run-instances" # mock out all logging, since it clutters our output flexmock(AppScaleLogger) AppScaleLogger.should_receive('log').and_return() # set up phony AWS credentials for each test # ones that test not having them present can # remove them for credential in EucalyptusAgent.REQUIRED_EC2_CREDENTIALS: os.environ[credential] = "baz" os.environ['EC2_URL'] = "http://boo" # pretend that our credentials are valid. fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_all_instances') # similarly, pretend that our image does exist in EC2 # and Euca fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() fake_ec2.should_receive('get_image').with_args('emi-ABCDEFG') \ .and_return('anything') # Slip in mocks that assume our EBS volume exists in EC2. fake_ec2.should_receive('get_all_volumes').with_args(['vol-ABCDEFG']) \ .and_return('anything') # Also pretend that the availability zone we want to use exists. fake_ec2.should_receive('get_all_zones').with_args('my-zone-1b') \ .and_return('anything') # Pretend that a bad availability zone doesn't exist. fake_ec2.should_receive('get_all_zones').with_args('bad-zone-1b') \ .and_raise(boto.exception.EC2ResponseError, 'baz', 'baz') # Pretend that we have one elastic IP allocated for use. fake_ec2.should_receive('get_all_addresses').with_args('GOOD.IP.ADDRESS') \ .and_return('anything') # Pretend that asking for a bad elastic IP doesn't work. fake_ec2.should_receive('get_all_addresses').with_args('BAD.IP.ADDRESS') \ .and_raise(boto.exception.EC2ResponseError, 'baz', 'baz') fake_price = flexmock(name='fake_price', price=1.00) fake_ec2.should_receive('get_spot_price_history').and_return([fake_price]) flexmock(boto) flexmock(boto.ec2) boto.ec2.should_receive('connect_to_region').with_args('my-zone-1', aws_access_key_id='baz', aws_secret_access_key='baz').and_return(fake_ec2) boto.ec2.should_receive('connect_to_region').with_args('bad-zone-1', aws_access_key_id='baz', aws_secret_access_key='baz').and_return(fake_ec2) boto.should_receive('connect_euca').and_return(fake_ec2)
def setUp(self): # mock out printing to stdout builtins = flexmock(sys.modules['__builtin__']) builtins.should_receive('print').and_return() # next, pretend our ec2 credentials are properly set for credential in EC2Agent.REQUIRED_CREDENTIALS: os.environ[credential] = "baz" # finally, pretend that our ec2 image to use exists fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() flexmock(boto) boto.should_receive('connect_ec2').with_args('baz', 'baz').and_return(fake_ec2) # do argument parsing here, since the below tests do it the # same way every time argv = ["--min", "1", "--max", "1", "--infrastructure", "ec2", "--machine", "ami-ABCDEFG", "--group", "blargscale"] function = "appscale-run-instances" self.options = ParseArgs(argv, function).args self.my_id = "12345" self.expected = { "EC2_ACCESS_KEY" : None, "EC2_SECRET_KEY" : None, "EC2_URL" : None, "admin_pass" : None, "admin_user" : None, "appengine" : 1, "autoscale" : True, "min" : 1, "max" : 1, "infrastructure" : "ec2", "machine" : "ami-ABCDEFG", "force" : False, "group" : "blargscale", "instance_type" : "m1.large", "ips" : None, "ips_layout" : None, "keyname" : "appscale", "login_host" : None, "max_spot_price": None, "replication" : None, "scp" : None, "table" : "cassandra", "test" : False, "use_spot_instances" : False, "verbose" : False, "version" : False } # finally, construct a http payload for mocking that the below # tests can use self.payload = "?boo=baz&min=1&max=1&infrastructure=ec2" + \ "&machine=ami-ABCDEFG&force=False&group=appscale" + \ "&instance_type=m1.large&ips=None&keyname=appscale&n=None" + \ "table=cassandra&test=False&version=False"
def setUp(self): self.ec2_args = ['--EC2_ACCESS_KEY', 'baz', '--EC2_SECRET_KEY', 'baz', '--infrastructure', 'ec2'] # change infrastructure and add EC2_URL. self.euca_args = self.ec2_args[:-1] + ['euca', '--EC2_URL', 'http://boo'] self.cloud_argv = ['--min', '1', '--max', '1', '--group', 'blargscale', '--instance_type', 'm3.medium', '--machine', 'ami-ABCDEFG', '--zone', 'my-zone-1b'] + self.ec2_args self.cluster_argv = ['--ips', 'ips.yaml'] self.function = "appscale-run-instances" # mock out all logging, since it clutters our output flexmock(AppScaleLogger) AppScaleLogger.should_receive('log').and_return() # pretend that our credentials are valid. fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_all_instances') # similarly, pretend that our image does exist in EC2 # and Euca fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() fake_ec2.should_receive('get_image').with_args('emi-ABCDEFG') \ .and_return('anything') # Slip in mocks that assume our EBS volume exists in EC2. fake_ec2.should_receive('get_all_volumes').with_args(['vol-ABCDEFG']) \ .and_return('anything') # Also pretend that the availability zone we want to use exists. fake_ec2.should_receive('get_all_zones').with_args('my-zone-1b') \ .and_return('anything') # Pretend that a bad availability zone doesn't exist. fake_ec2.should_receive('get_all_zones').with_args('bad-zone-1b') \ .and_raise(boto.exception.EC2ResponseError, 'baz', 'baz') # Pretend that we have one elastic IP allocated for use. fake_ec2.should_receive('get_all_addresses').with_args('GOOD.IP.ADDRESS') \ .and_return('anything') # Pretend that asking for a bad elastic IP doesn't work. fake_ec2.should_receive('get_all_addresses').with_args('BAD.IP.ADDRESS') \ .and_raise(boto.exception.EC2ResponseError, 'baz', 'baz') fake_price = flexmock(name='fake_price', price=1.00) fake_ec2.should_receive('get_spot_price_history').and_return([fake_price]) flexmock(boto) flexmock(boto.ec2) boto.ec2.should_receive('connect_to_region').with_args('my-zone-1', aws_access_key_id='baz', aws_secret_access_key='baz').and_return(fake_ec2) boto.ec2.should_receive('connect_to_region').with_args('bad-zone-1', aws_access_key_id='baz', aws_secret_access_key='baz').and_return(fake_ec2) boto.should_receive('connect_euca').and_return(fake_ec2)
def test_failure_when_ami_doesnt_exist(self): # mock out boto calls to EC2 and put in that the image doesn't exist fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_raise(boto.exception.EC2ResponseError, '', '') flexmock(boto) boto.should_receive('connect_ec2').with_args('baz', 'baz').and_return(fake_ec2) argv = self.cloud_argv[:] + ["--infrastructure", "ec2", "--machine", "ami-ABCDEFG"] self.assertRaises(BadConfigurationException, ParseArgs, argv, self.function)
def test_failure_when_ami_doesnt_exist(self): # mock out boto calls to EC2 and put in that the image doesn't exist fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_raise(boto.exception.EC2ResponseError, '', '') flexmock(boto) boto.should_receive('connect_ec2').with_args('baz', 'baz') \ .and_return(fake_ec2) argv = self.cloud_argv[:] + ["--infrastructure", "ec2", "--machine",\ "ami-ABCDEFG"] self.assertRaises(BadConfigurationException, ParseArgs, argv, self.function)
def testUpWithCloudAppScalefile(self): # calling 'appscale up' if there is an AppScalefile present # should call appscale-run-instances with the given config # params. here, we assume that the file is intended for use # on EC2 appscale = AppScale() # Mock out the actual file reading itself, and slip in a YAML-dumped # file contents = { 'infrastructure': 'ec2', 'machine': 'ami-ABCDEFG', 'keyname': 'bookey', 'group': 'boogroup', 'min': 1, 'max': 1 } yaml_dumped_contents = yaml.dump(contents) self.addMockForAppScalefile(appscale, yaml_dumped_contents) # throw in some mocks for the argument parsing for credential in EC2Agent.REQUIRED_CREDENTIALS: os.environ[credential] = "baz" # finally, pretend that our ec2 image to use exists fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() flexmock(boto) boto.should_receive('connect_ec2').with_args( 'baz', 'baz').and_return(fake_ec2) # finally, mock out the actual appscale-run-instances call flexmock(AppScaleTools) AppScaleTools.should_receive('run_instances') appscale.up()
def test_terminate_in_cloud_and_succeeds(self): # let's say that there is a locations.yaml file, which means appscale is # running, so we should terminate the services on each box flexmock(os.path) os.path.should_call('exists') # set up the fall-through os.path.should_receive('exists').with_args( LocalState.get_locations_yaml_location( self.keyname)).and_return(True) # mock out reading the locations.yaml file, and pretend that we're on # a virtualized cluster builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') fake_yaml_file = flexmock(name='fake_file') fake_yaml_file.should_receive('read').and_return( yaml.dump({ 'infrastructure': 'ec2', 'group': 'bazboogroup' })) builtins.should_receive('open').with_args( LocalState.get_locations_yaml_location(self.keyname), 'r') \ .and_return(fake_yaml_file) # mock out reading the json file, and pretend that we're running in a # two node deployment fake_json_file = flexmock(name='fake_file') fake_json_file.should_receive('read').and_return( json.dumps([{ 'public_ip': 'public1', 'jobs': ['shadow'] }, { 'public_ip': 'public2', 'jobs': ['appengine'] }])) builtins.should_receive('open').with_args( LocalState.get_locations_json_location(self.keyname), 'r') \ .and_return(fake_json_file) # and slip in a fake secret file fake_secret_file = flexmock(name='fake_file') fake_secret_file.should_receive('read').and_return('the secret') builtins.should_receive('open').with_args( LocalState.get_secret_key_location(self.keyname), 'r') \ .and_return(fake_secret_file) # mock out talking to EC2 fake_ec2 = flexmock(name='fake_ec2') # let's say that three instances are running, and that two of them are in # our deployment fake_one_running = flexmock(name='fake_one', key_name=self.keyname, state='running', id='i-ONE', public_dns_name='public1', private_dns_name='private1') fake_two_running = flexmock(name='fake_two', key_name=self.keyname, state='running', id='i-TWO', public_dns_name='public2', private_dns_name='private2') fake_three_running = flexmock(name='fake_three', key_name='abcdefg', state='running', id='i-THREE', public_dns_name='public3', private_dns_name='private3') fake_reservation_running = flexmock( name='fake_reservation', instances=[fake_one_running, fake_two_running, fake_three_running]) fake_one_terminated = flexmock(name='fake_one', key_name=self.keyname, state='terminated', id='i-ONE', public_dns_name='public1', private_dns_name='private1') fake_two_terminated = flexmock(name='fake_two', key_name=self.keyname, state='terminated', id='i-TWO', public_dns_name='public2', private_dns_name='private2') fake_three_terminated = flexmock(name='fake_three', key_name='abcdefg', state='terminated', id='i-THREE', public_dns_name='public3', private_dns_name='private3') fake_reservation_terminated = flexmock(name='fake_reservation', instances=[ fake_one_terminated, fake_two_terminated, fake_three_terminated ]) fake_ec2.should_receive('get_all_instances').and_return(fake_reservation_running) \ .and_return(fake_reservation_terminated) flexmock(boto) boto.should_receive('connect_ec2').and_return(fake_ec2) # and mock out the call to kill the instances fake_ec2.should_receive('terminate_instances').with_args( ['i-ONE', 'i-TWO']).and_return([fake_one_terminated, fake_two_terminated]) # mock out the call to delete the keypair fake_ec2.should_receive('delete_key_pair').and_return() # and the call to delete the security group - let's say that we can't # delete the group the first time, and can the second fake_ec2.should_receive('delete_security_group').and_return(False) \ .and_return(True) # finally, mock out removing the yaml file, json file, and secret key from # this machine flexmock(os) os.should_receive('remove').with_args( LocalState.get_locations_yaml_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_locations_json_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_secret_key_location(self.keyname)).and_return() argv = ["--keyname", self.keyname] options = ParseArgs(argv, self.function).args AppScaleTools.terminate_instances(options)
def test_terminate_in_cloud_and_succeeds(self): # let's say that there is a locations.yaml file, which means appscale is # running, so we should terminate the services on each box flexmock(os.path) os.path.should_call('exists') # set up the fall-through os.path.should_receive('exists').with_args( LocalState.get_locations_yaml_location(self.keyname)).and_return(True) # mock out reading the locations.yaml file, and pretend that we're on # a virtualized cluster builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') fake_yaml_file = flexmock(name='fake_file') fake_yaml_file.should_receive('read').and_return(yaml.dump({ 'infrastructure' : 'ec2', 'group' : 'bazboogroup' })) builtins.should_receive('open').with_args( LocalState.get_locations_yaml_location(self.keyname), 'r') \ .and_return(fake_yaml_file) # mock out reading the json file, and pretend that we're running in a # two node deployment fake_json_file = flexmock(name='fake_file') fake_json_file.should_receive('read').and_return(json.dumps([ { 'public_ip' : 'public1', 'jobs' : ['shadow'] }, { 'public_ip' : 'public2', 'jobs' : ['appengine'] } ])) builtins.should_receive('open').with_args( LocalState.get_locations_json_location(self.keyname), 'r') \ .and_return(fake_json_file) # and slip in a fake secret file fake_secret_file = flexmock(name='fake_file') fake_secret_file.should_receive('read').and_return('the secret') builtins.should_receive('open').with_args( LocalState.get_secret_key_location(self.keyname), 'r') \ .and_return(fake_secret_file) # mock out talking to EC2 fake_ec2 = flexmock(name='fake_ec2') # let's say that three instances are running, and that two of them are in # our deployment fake_one = flexmock(name='fake_one', key_name=self.keyname, state='running', id='i-ONE', public_dns_name='public1', private_dns_name='private1') fake_two = flexmock(name='fake_two', key_name=self.keyname, state='running', id='i-TWO', public_dns_name='public2', private_dns_name='private2') fake_three = flexmock(name='fake_three', key_name='abcdefg', state='running', id='i-THREE', public_dns_name='public3', private_dns_name='private3') fake_reservation = flexmock(name='fake_reservation', instances=[fake_one, fake_two, fake_three]) fake_ec2.should_receive('get_all_instances').and_return(fake_reservation) flexmock(boto) boto.should_receive('connect_ec2').with_args('baz', 'baz') \ .and_return(fake_ec2) # and mock out the call to kill the instances fake_ec2.should_receive('terminate_instances').with_args(['i-ONE', 'i-TWO']).and_return([fake_one, fake_two]) # mock out the call to delete the keypair fake_ec2.should_receive('delete_key_pair').and_return() # and the call to delete the security group - let's say that we can't # delete the group the first time, and can the second fake_ec2.should_receive('delete_security_group').and_return(False) \ .and_return(True) # finally, mock out removing the yaml file, json file, and secret key from # this machine flexmock(os) os.should_receive('remove').with_args( LocalState.get_locations_yaml_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_locations_json_location(self.keyname)).and_return() os.should_receive('remove').with_args( LocalState.get_secret_key_location(self.keyname)).and_return() argv = [ "--keyname", self.keyname ] options = ParseArgs(argv, self.function).args AppScaleTools.terminate_instances(options)
def test_appscale_in_one_node_cloud_deployment_manual_spot_price(self): # let's say that appscale isn't already running local_state = flexmock(LocalState) local_state.should_receive('ensure_appscale_isnt_running').and_return() local_state.should_receive('make_appscale_directory').and_return() # mock out talking to logs.appscale.com fake_connection = flexmock(name='fake_connection') fake_connection.should_receive('request').with_args('POST', '/upload', str, AppScaleLogger.HEADERS).and_return() flexmock(httplib) httplib.should_receive('HTTPConnection').with_args('logs.appscale.com') \ .and_return(fake_connection) # mock out generating the secret key flexmock(uuid) uuid.should_receive('uuid4').and_return('the secret') # mock out writing the secret key to ~/.appscale, as well as reading it # later builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') # set the fall-through secret_key_location = LocalState.get_secret_key_location(self.keyname) fake_secret = flexmock(name="fake_secret") fake_secret.should_receive('read').and_return('the secret') fake_secret.should_receive('write').and_return() builtins.should_receive('open').with_args(secret_key_location, 'r') \ .and_return(fake_secret) builtins.should_receive('open').with_args(secret_key_location, 'w') \ .and_return(fake_secret) # mock out interactions with AWS fake_ec2 = flexmock(name='fake_ec2') # first, pretend that our image does exist in EC2 fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() # next, assume that our keypair doesn't exist yet fake_ec2.should_receive('get_key_pair').with_args(self.keyname) \ .and_return(None) # same for the security group fake_ec2.should_receive('get_all_security_groups').and_return([]) # mock out creating the keypair fake_key = flexmock(name='fake_key', material='baz') local_state.should_receive('write_key_file').with_args( re.compile(self.keyname), fake_key.material).and_return() fake_ec2.should_receive('create_key_pair').with_args(self.keyname) \ .and_return(fake_key) # and the same for the security group fake_ec2.should_receive('create_security_group').with_args('bazgroup', str).and_return() fake_ec2.should_receive('authorize_security_group').with_args('bazgroup', from_port=1, to_port=65535, ip_protocol='udp', cidr_ip='0.0.0.0/0') fake_ec2.should_receive('authorize_security_group').with_args('bazgroup', from_port=1, to_port=65535, ip_protocol='tcp', cidr_ip='0.0.0.0/0') fake_ec2.should_receive('authorize_security_group').with_args('bazgroup', ip_protocol='icmp', cidr_ip='0.0.0.0/0') # also mock out acquiring a spot instance fake_ec2.should_receive('request_spot_instances').with_args('1.23', 'ami-ABCDEFG', key_name=self.keyname, security_groups=['bazgroup'], instance_type='m1.large', count=1) # assume that there are no instances running initially, and that the # instance we spawn starts as pending, then becomes running no_instances = flexmock(name='no_instances', instances=[]) pending_instance = flexmock(name='pending_instance', state='pending', key_name=self.keyname, id='i-ABCDEFG') pending_reservation = flexmock(name='pending_reservation', instances=[pending_instance]) running_instance = flexmock(name='running_instance', state='running', key_name=self.keyname, id='i-ABCDEFG', public_dns_name='public1', private_dns_name='private1') running_reservation = flexmock(name='running_reservation', instances=[running_instance]) fake_ec2.should_receive('get_all_instances').and_return(no_instances) \ .and_return(pending_reservation).and_return(running_reservation) # finally, inject the mocked EC2 in flexmock(boto) boto.should_receive('connect_ec2').and_return(fake_ec2) # assume that root login is not enabled local_state.should_receive('shell').with_args(re.compile('ssh'), False, 1, stdin='ls').and_return(RemoteHelper.LOGIN_AS_UBUNTU_USER) # assume that we can enable root login local_state.should_receive('shell').with_args(re.compile('ssh'), False, 5, stdin=re.compile('sudo cp')).and_return() # and assume that we can copy over our ssh keys fine local_state.should_receive('shell').with_args(re.compile('scp .*[r|d]sa'), False, 5).and_return() local_state.should_receive('shell').with_args(re.compile('scp .*{0}' .format(self.keyname)), False, 5).and_return() # mock out seeing if the image is appscale-compatible, and assume it is # mock out our attempts to find /etc/appscale and presume it does exist local_state.should_receive('shell').with_args(re.compile('ssh'), False, 5, stdin=re.compile('/etc/appscale')).and_return() # mock out our attempts to find /etc/appscale/version and presume it does # exist local_state.should_receive('shell').with_args(re.compile('ssh'), False, 5, stdin=re.compile('/etc/appscale/{0}' .format(APPSCALE_VERSION))) # put in a mock indicating that the database the user wants is supported local_state.should_receive('shell').with_args(re.compile('ssh'), False, 5, stdin=re.compile('/etc/appscale/{0}/{1}' .format(APPSCALE_VERSION, 'cassandra'))) # mock out generating the private key local_state.should_receive('shell').with_args(re.compile('openssl'), False, stdin=None) # assume that we started god fine local_state.should_receive('shell').with_args(re.compile('ssh'), False, 5, stdin=re.compile('god &')) # and that we copied over the AppController's god file local_state.should_receive('shell').with_args(re.compile('scp'), False, 5, stdin=re.compile('appcontroller.god')) # also, that we started the AppController itself local_state.should_receive('shell').with_args(re.compile('ssh'), False, 5, stdin=re.compile('god load')) # assume that ssh comes up on the third attempt fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('public1', RemoteHelper.SSH_PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # assume that the AppController comes up on the third attempt fake_socket.should_receive('connect').with_args(('public1', AppControllerClient.PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # same for the UserAppServer fake_socket.should_receive('connect').with_args(('public1', UserAppClient.PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # as well as for the AppLoadBalancer fake_socket.should_receive('connect').with_args(('public1', RemoteHelper.APP_LOAD_BALANCER_PORT)).and_raise(Exception) \ .and_raise(Exception).and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) # mock out the SOAP call to the AppController and assume it succeeded fake_appcontroller = flexmock(name='fake_appcontroller') fake_appcontroller.should_receive('set_parameters').with_args(list, list, ['none'], 'the secret').and_return('OK') fake_appcontroller.should_receive('get_all_public_ips').with_args('the secret') \ .and_return(json.dumps(['public1'])) role_info = [{ 'public_ip' : 'public1', 'private_ip' : 'private1', 'jobs' : ['shadow', 'login'] }] fake_appcontroller.should_receive('get_role_info').with_args('the secret') \ .and_return(json.dumps(role_info)) fake_appcontroller.should_receive('status').with_args('the secret') \ .and_return('nothing interesting here') \ .and_return('Database is at not-up-yet') \ .and_return('Database is at public1') fake_appcontroller.should_receive('is_done_initializing') \ .and_return(False) \ .and_return(True) flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://*****:*****@a.com', str, 'xmpp_user', 'the secret') \ .and_return('true') fake_userappserver.should_receive('commit_new_user').with_args( 'a@public1', str, 'xmpp_user', 'the secret') \ .and_return('true') fake_userappserver.should_receive('set_cloud_admin_status').with_args( '*****@*****.**', 'true', 'the secret').and_return() fake_userappserver.should_receive('set_capabilities').with_args( '*****@*****.**', UserAppClient.ADMIN_CAPABILITIES, 'the secret').and_return() SOAPpy.should_receive('SOAPProxy').with_args('https://public1:4343') \ .and_return(fake_userappserver) argv = [ "--min", "1", "--max", "1", "--infrastructure", "ec2", "--machine", "ami-ABCDEFG", "--use_spot_instances", "--max_spot_price", "1.23", "--keyname", self.keyname, "--group", "bazgroup", "--test" ] options = ParseArgs(argv, self.function).args AppScaleTools.run_instances(options)
def setUp(self): # mock out all logging, since it clutters our output flexmock(AppScaleLogger) AppScaleLogger.should_receive("log").and_return() # mock out all sleeps, as they aren't necessary for unit testing flexmock(time) time.should_receive("sleep").and_return() # set up some fake options so that we don't have to generate them via # ParseArgs self.options = flexmock( infrastructure="ec2", group="boogroup", machine="ami-ABCDEFG", instance_type="m1.large", keyname="bookey", table="cassandra", verbose=False, test=False, use_spot_instances=False, zone="my-zone-1b", ) self.my_id = "12345" self.node_layout = NodeLayout(self.options) # set up phony AWS credentials for each test # ones that test not having them present can # remove them for credential in EucalyptusAgent.REQUIRED_EC2_CREDENTIALS: os.environ[credential] = "baz" os.environ["EC2_URL"] = "http://boo" # mock out calls to EC2 # begin by assuming that our ssh keypair doesn't exist, and thus that we # need to create it key_contents = "key contents here" fake_key = flexmock(name="fake_key", material=key_contents) fake_key.should_receive("save").with_args(os.environ["HOME"] + "/.appscale").and_return(None) fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive("get_key_pair").with_args("bookey").and_return(None) fake_ec2.should_receive("create_key_pair").with_args("bookey").and_return(fake_key) # mock out writing the secret key builtins = flexmock(sys.modules["__builtin__"]) builtins.should_call("open") # set the fall-through secret_key_location = LocalState.LOCAL_APPSCALE_PATH + "bookey.secret" fake_secret = flexmock(name="fake_secret") fake_secret.should_receive("write").and_return() builtins.should_receive("open").with_args(secret_key_location, "w").and_return(fake_secret) # also, mock out the keypair writing and chmod'ing ssh_key_location = LocalState.LOCAL_APPSCALE_PATH + "bookey.key" fake_file = flexmock(name="fake_file") fake_file.should_receive("write").with_args(key_contents).and_return() builtins.should_receive("open").with_args(ssh_key_location, "w").and_return(fake_file) flexmock(os) os.should_receive("chmod").with_args(ssh_key_location, 0600).and_return() # next, assume there are no security groups up at first, but then it gets # created. udp_rule = flexmock(from_port=1, to_port=65535, ip_protocol="udp") tcp_rule = flexmock(from_port=1, to_port=65535, ip_protocol="tcp") icmp_rule = flexmock(from_port=-1, to_port=-1, ip_protocol="icmp") group = flexmock(name="boogroup", rules=[tcp_rule, udp_rule, icmp_rule]) fake_ec2.should_receive("get_all_security_groups").with_args().and_return([]) fake_ec2.should_receive("get_all_security_groups").with_args("boogroup").and_return([group]) # and then assume we can create and open our security group fine fake_ec2.should_receive("create_security_group").with_args("boogroup", "AppScale security group").and_return() fake_ec2.should_receive("authorize_security_group").and_return() # next, add in mocks for run_instances # the first time around, let's say that no machines are running # the second time around, let's say that our machine is pending # and that it's up the third time around fake_pending_instance = flexmock(state="pending") fake_pending_reservation = flexmock(instances=fake_pending_instance) fake_running_instance = flexmock( state="running", key_name="bookey", id="i-12345678", public_dns_name="public1", private_dns_name="private1" ) fake_running_reservation = flexmock(instances=fake_running_instance) fake_ec2.should_receive("get_all_instances").and_return([]).and_return([fake_pending_reservation]).and_return( [fake_running_reservation] ) # next, assume that our run_instances command succeeds fake_ec2.should_receive("run_instances").and_return() # finally, inject our mocked EC2 flexmock(boto) boto.should_receive("connect_ec2").and_return(fake_ec2) # assume that ssh comes up on the third attempt fake_socket = flexmock(name="fake_socket") fake_socket.should_receive("connect").with_args(("public1", RemoteHelper.SSH_PORT)).and_raise( Exception ).and_raise(Exception).and_return(None) flexmock(socket) socket.should_receive("socket").and_return(fake_socket) # throw some default mocks together for when invoking via shell succeeds # and when it fails self.fake_temp_file = flexmock(name="fake_temp_file") self.fake_temp_file.should_receive("seek").with_args(0).and_return() self.fake_temp_file.should_receive("read").and_return("boo out") self.fake_temp_file.should_receive("close").and_return() flexmock(tempfile) tempfile.should_receive("NamedTemporaryFile").and_return(self.fake_temp_file) self.success = flexmock(name="success", returncode=0) self.success.should_receive("wait").and_return(0) self.failed = flexmock(name="success", returncode=1) self.failed.should_receive("wait").and_return(1) # assume that root login isn't already enabled local_state = flexmock(LocalState) local_state.should_receive("shell").with_args(re.compile("^ssh .*root"), False, 1, stdin="ls").and_return( "Please login as the ubuntu user rather than root user." ) # and assume that we can ssh in as ubuntu to enable root login local_state = flexmock(LocalState) local_state.should_receive("shell").with_args(re.compile("^ssh .*ubuntu"), False, 5).and_return() # also assume that we can scp over our ssh keys local_state.should_receive("shell").with_args(re.compile("scp .*/root/.ssh/id_"), False, 5).and_return() local_state.should_receive("shell").with_args( re.compile("scp .*/root/.appscale/bookey.key"), False, 5 ).and_return()
def test_appscale_in_one_node_cloud_deployment_manual_spot_price(self): # let's say that appscale isn't already running local_state = flexmock(LocalState) local_state.should_receive('ensure_appscale_isnt_running').and_return() local_state.should_receive('make_appscale_directory').and_return() # mock out talking to logs.appscale.com fake_connection = flexmock(name='fake_connection') fake_connection.should_receive('request').with_args('POST', '/upload', str, AppScaleLogger.HEADERS).and_return() flexmock(httplib) httplib.should_receive('HTTPConnection').with_args('logs.appscale.com') \ .and_return(fake_connection) # mock out generating the secret key flexmock(uuid) uuid.should_receive('uuid4').and_return('the secret') # mock out writing the secret key to ~/.appscale, as well as reading it # later builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') # set the fall-through secret_key_location = LocalState.get_secret_key_location(self.keyname) fake_secret = flexmock(name="fake_secret") fake_secret.should_receive('read').and_return('the secret') fake_secret.should_receive('write').and_return() builtins.should_receive('open').with_args(secret_key_location, 'r') \ .and_return(fake_secret) builtins.should_receive('open').with_args(secret_key_location, 'w') \ .and_return(fake_secret) # mock out interactions with AWS fake_ec2 = flexmock(name='fake_ec2') # first, pretend that our image does exist in EC2 fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() # next, assume that our keypair doesn't exist yet fake_ec2.should_receive('get_key_pair').with_args(self.keyname) \ .and_return(None) # same for the security group fake_ec2.should_receive('get_all_security_groups').and_return([]) # mock out creating the keypair fake_key = flexmock(name='fake_key', material='baz') local_state.should_receive('write_key_file').with_args( re.compile(self.keyname), fake_key.material).and_return() fake_ec2.should_receive('create_key_pair').with_args(self.keyname) \ .and_return(fake_key) # and the same for the security group fake_ec2.should_receive('create_security_group').with_args('bazgroup', str).and_return() fake_ec2.should_receive('authorize_security_group').with_args('bazgroup', from_port=1, to_port=65535, ip_protocol='udp', cidr_ip='0.0.0.0/0') fake_ec2.should_receive('authorize_security_group').with_args('bazgroup', from_port=1, to_port=65535, ip_protocol='tcp', cidr_ip='0.0.0.0/0') fake_ec2.should_receive('authorize_security_group').with_args('bazgroup', ip_protocol='icmp', cidr_ip='0.0.0.0/0') # also mock out acquiring a spot instance fake_ec2.should_receive('request_spot_instances').with_args('1.23', 'ami-ABCDEFG', key_name=self.keyname, security_groups=['bazgroup'], instance_type='m1.large', count=1) # assume that there are no instances running initially, and that the # instance we spawn starts as pending, then becomes running no_instances = flexmock(name='no_instances', instances=[]) pending_instance = flexmock(name='pending_instance', state='pending', key_name=self.keyname, id='i-ABCDEFG') pending_reservation = flexmock(name='pending_reservation', instances=[pending_instance]) running_instance = flexmock(name='running_instance', state='running', key_name=self.keyname, id='i-ABCDEFG', public_dns_name='public1', private_dns_name='private1') running_reservation = flexmock(name='running_reservation', instances=[running_instance]) fake_ec2.should_receive('get_all_instances').and_return(no_instances) \ .and_return(pending_reservation).and_return(running_reservation) # finally, inject the mocked EC2 in flexmock(boto) boto.should_receive('connect_ec2').and_return(fake_ec2) # assume that root login is not enabled local_state.should_receive('shell').with_args(re.compile('ssh'), False, 1, stdin='ls').and_return(RemoteHelper.LOGIN_AS_UBUNTU_USER) # assume that we can enable root login local_state.should_receive('shell').with_args(re.compile('ssh'), False, 5, stdin=re.compile('sudo cp')).and_return() # and assume that we can copy over our ssh keys fine local_state.should_receive('shell').with_args(re.compile('scp .*[r|d]sa'), False, 5).and_return() local_state.should_receive('shell').with_args(re.compile('scp .*{0}' .format(self.keyname)), False, 5).and_return() # mock out seeing if the image is appscale-compatible, and assume it is # mock out our attempts to find /etc/appscale and presume it does exist local_state.should_receive('shell').with_args(re.compile('ssh'), False, 5, stdin=re.compile('/etc/appscale')).and_return() # mock out our attempts to find /etc/appscale/version and presume it does # exist local_state.should_receive('shell').with_args(re.compile('ssh'), False, 5, stdin=re.compile('/etc/appscale/{0}' .format(APPSCALE_VERSION))) # put in a mock indicating that the database the user wants is supported local_state.should_receive('shell').with_args(re.compile('ssh'), False, 5, stdin=re.compile('/etc/appscale/{0}/{1}' .format(APPSCALE_VERSION, 'cassandra'))) # mock out generating the private key local_state.should_receive('shell').with_args(re.compile('openssl'), False, stdin=None) # assume that we started god fine local_state.should_receive('shell').with_args(re.compile('ssh'), False, 5, stdin=re.compile('god &')) # and that we copied over the AppController's god file local_state.should_receive('shell').with_args(re.compile('scp'), False, 5, stdin=re.compile('appcontroller.god')) # also, that we started the AppController itself local_state.should_receive('shell').with_args(re.compile('ssh'), False, 5, stdin=re.compile('god load')) # assume that ssh comes up on the third attempt fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('public1', RemoteHelper.SSH_PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # assume that the AppController comes up on the third attempt fake_socket.should_receive('connect').with_args(('public1', AppControllerClient.PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # same for the UserAppServer fake_socket.should_receive('connect').with_args(('public1', UserAppClient.PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # as well as for the AppDashboard fake_socket.should_receive('connect').with_args(('public1', RemoteHelper.APP_DASHBOARD_PORT)).and_raise(Exception) \ .and_raise(Exception).and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) # mock out the SOAP call to the AppController and assume it succeeded fake_appcontroller = flexmock(name='fake_appcontroller') fake_appcontroller.should_receive('set_parameters').with_args(list, list, ['none'], 'the secret').and_return('OK') fake_appcontroller.should_receive('get_all_public_ips').with_args('the secret') \ .and_return(json.dumps(['public1'])) role_info = [{ 'public_ip' : 'public1', 'private_ip' : 'private1', 'jobs' : ['shadow', 'login'] }] fake_appcontroller.should_receive('get_role_info').with_args('the secret') \ .and_return(json.dumps(role_info)) fake_appcontroller.should_receive('status').with_args('the secret') \ .and_return('nothing interesting here') \ .and_return('Database is at not-up-yet') \ .and_return('Database is at public1') fake_appcontroller.should_receive('is_done_initializing') \ .and_return(False) \ .and_return(True) flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://*****:*****@a.com', str, 'xmpp_user', 'the secret') \ .and_return('true') fake_userappserver.should_receive('commit_new_user').with_args( 'a@public1', str, 'xmpp_user', 'the secret') \ .and_return('true') fake_userappserver.should_receive('set_cloud_admin_status').with_args( '*****@*****.**', 'true', 'the secret').and_return() fake_userappserver.should_receive('set_capabilities').with_args( '*****@*****.**', UserAppClient.ADMIN_CAPABILITIES, 'the secret').and_return() SOAPpy.should_receive('SOAPProxy').with_args('https://public1:4343') \ .and_return(fake_userappserver) argv = [ "--min", "1", "--max", "1", "--infrastructure", "ec2", "--machine", "ami-ABCDEFG", "--use_spot_instances", "--max_spot_price", "1.23", "--keyname", self.keyname, "--group", "bazgroup", "--test" ] options = ParseArgs(argv, self.function).args AppScaleTools.run_instances(options)
def setUp(self): # mock out all logging, since it clutters our output flexmock(AppScaleLogger) AppScaleLogger.should_receive('log').and_return() # mock out all sleeps, as they aren't necessary for unit testing flexmock(time) time.should_receive('sleep').and_return() # set up some fake options so that we don't have to generate them via # ParseArgs self.options = flexmock(infrastructure='ec2', group='boogroup', machine='ami-ABCDEFG', instance_type='m1.large', keyname='bookey', table='cassandra', verbose=False, test=False, use_spot_instances=False) self.my_id = "12345" self.node_layout = NodeLayout(self.options) # mock out calls to EC2 # begin by assuming that our ssh keypair doesn't exist, and thus that we # need to create it key_contents = "key contents here" fake_key = flexmock(name="fake_key", material=key_contents) fake_key.should_receive('save').with_args(os.environ['HOME']+'/.appscale').and_return(None) fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_key_pair').with_args('bookey') \ .and_return(None) fake_ec2.should_receive('create_key_pair').with_args('bookey') \ .and_return(fake_key) # mock out writing the secret key builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') # set the fall-through secret_key_location = LocalState.LOCAL_APPSCALE_PATH + "bookey.secret" fake_secret = flexmock(name="fake_secret") fake_secret.should_receive('write').and_return() builtins.should_receive('open').with_args(secret_key_location, 'w') \ .and_return(fake_secret) # also, mock out the keypair writing and chmod'ing ssh_key_location = LocalState.LOCAL_APPSCALE_PATH + "bookey.key" fake_file = flexmock(name="fake_file") fake_file.should_receive('write').with_args(key_contents).and_return() builtins.should_receive('open').with_args(ssh_key_location, 'w') \ .and_return(fake_file) flexmock(os) os.should_receive('chmod').with_args(ssh_key_location, 0600).and_return() # next, assume there are no security groups up yet fake_ec2.should_receive('get_all_security_groups').and_return([]) # and then assume we can create and open our security group fine fake_ec2.should_receive('create_security_group').with_args('boogroup', 'AppScale security group').and_return() fake_ec2.should_receive('authorize_security_group').and_return() # next, add in mocks for run_instances # the first time around, let's say that no machines are running # the second time around, let's say that our machine is pending # and that it's up the third time around fake_pending_instance = flexmock(state='pending') fake_pending_reservation = flexmock(instances=fake_pending_instance) fake_running_instance = flexmock(state='running', key_name='bookey', id='i-12345678', public_dns_name='public1', private_dns_name='private1') fake_running_reservation = flexmock(instances=fake_running_instance) fake_ec2.should_receive('get_all_instances').and_return([]) \ .and_return([fake_pending_reservation]) \ .and_return([fake_running_reservation]) # next, assume that our run_instances command succeeds fake_ec2.should_receive('run_instances').and_return() # finally, inject our mocked EC2 flexmock(boto) boto.should_receive('connect_ec2').and_return(fake_ec2) # assume that ssh comes up on the third attempt fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('public1', RemoteHelper.SSH_PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) # throw some default mocks together for when invoking via shell succeeds # and when it fails self.fake_temp_file = flexmock(name='fake_temp_file') self.fake_temp_file.should_receive('seek').with_args(0).and_return() self.fake_temp_file.should_receive('read').and_return('boo out') self.fake_temp_file.should_receive('close').and_return() flexmock(tempfile) tempfile.should_receive('NamedTemporaryFile')\ .and_return(self.fake_temp_file) self.success = flexmock(name='success', returncode=0) self.success.should_receive('wait').and_return(0) self.failed = flexmock(name='success', returncode=1) self.failed.should_receive('wait').and_return(1) # assume that root login isn't already enabled local_state = flexmock(LocalState) local_state.should_receive('shell') \ .with_args(re.compile('^ssh .*root'), False, 1, stdin='ls') \ .and_return('Please login as the ubuntu user rather than root user.') # and assume that we can ssh in as ubuntu to enable root login local_state = flexmock(LocalState) local_state.should_receive('shell')\ .with_args(re.compile('^ssh .*ubuntu'),False,5)\ .and_return() # also assume that we can scp over our ssh keys local_state.should_receive('shell')\ .with_args(re.compile('scp .*/root/.ssh/id_'),False,5)\ .and_return() local_state.should_receive('shell')\ .with_args(re.compile('scp .*/root/.appscale/bookey.key'),False,5)\ .and_return()
def setUp(self): self.cloud_argv = [ '--min', '1', '--max', '1', '--group', 'blargscale', '--infrastructure', 'ec2', '--machine', 'ami-ABCDEFG', '--zone', 'my-zone-1b' ] self.cluster_argv = ['--ips', 'ips.yaml'] self.function = "appscale-run-instances" # mock out all logging, since it clutters our output flexmock(AppScaleLogger) AppScaleLogger.should_receive('log').and_return() # set up phony AWS credentials for each test # ones that test not having them present can # remove them for credential in EucalyptusAgent.REQUIRED_EC2_CREDENTIALS: os.environ[credential] = "baz" os.environ['EC2_URL'] = "http://boo" # pretend that our credentials are valid. fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_all_instances') # similarly, pretend that our image does exist in EC2 # and Euca fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() fake_ec2.should_receive('get_image').with_args('emi-ABCDEFG') \ .and_return('anything') # Slip in mocks that assume our EBS volume exists in EC2. fake_ec2.should_receive('get_all_volumes').with_args(['vol-ABCDEFG']) \ .and_return('anything') # Also pretend that the availability zone we want to use exists. fake_ec2.should_receive('get_all_zones').with_args('my-zone-1b') \ .and_return('anything') # Pretend that a bad availability zone doesn't exist. fake_ec2.should_receive('get_all_zones').with_args('bad-zone-1b') \ .and_raise(boto.exception.EC2ResponseError, 'baz', 'baz') # Pretend that we have one elastic IP allocated for use. fake_ec2.should_receive('get_all_addresses').with_args('GOOD.IP.ADDRESS') \ .and_return('anything') # Pretend that asking for a bad elastic IP doesn't work. fake_ec2.should_receive('get_all_addresses').with_args('BAD.IP.ADDRESS') \ .and_raise(boto.exception.EC2ResponseError, 'baz', 'baz') fake_price = flexmock(name='fake_price', price=1.00) fake_ec2.should_receive('get_spot_price_history').and_return( [fake_price]) flexmock(boto) flexmock(boto.ec2) boto.ec2.should_receive('connect_to_region').with_args( 'my-zone-1', aws_access_key_id='baz', aws_secret_access_key='baz').and_return(fake_ec2) boto.ec2.should_receive('connect_to_region').with_args( 'bad-zone-1', aws_access_key_id='baz', aws_secret_access_key='baz').and_return(fake_ec2) boto.should_receive('connect_euca').and_return(fake_ec2)
def test_terminate_in_cloud_and_succeeds(self): # let's say that there is a locations.yaml file, which means appscale is # running, so we should terminate the services on each box flexmock(os.path) os.path.should_call("exists") # set up the fall-through os.path.should_receive("exists").with_args(LocalState.get_locations_yaml_location(self.keyname)).and_return( True ) # mock out reading the locations.yaml file, and pretend that we're on # a virtualized cluster builtins = flexmock(sys.modules["__builtin__"]) builtins.should_call("open") fake_yaml_file = flexmock(name="fake_file") fake_yaml_file.should_receive("read").and_return(yaml.dump({"infrastructure": "ec2", "group": "bazboogroup"})) builtins.should_receive("open").with_args(LocalState.get_locations_yaml_location(self.keyname), "r").and_return( fake_yaml_file ) # mock out reading the json file, and pretend that we're running in a # two node deployment fake_json_file = flexmock(name="fake_file") fake_json_file.should_receive("read").and_return( json.dumps([{"public_ip": "public1", "jobs": ["shadow"]}, {"public_ip": "public2", "jobs": ["appengine"]}]) ) builtins.should_receive("open").with_args(LocalState.get_locations_json_location(self.keyname), "r").and_return( fake_json_file ) # and slip in a fake secret file fake_secret_file = flexmock(name="fake_file") fake_secret_file.should_receive("read").and_return("the secret") builtins.should_receive("open").with_args(LocalState.get_secret_key_location(self.keyname), "r").and_return( fake_secret_file ) # mock out talking to EC2 fake_ec2 = flexmock(name="fake_ec2") # let's say that three instances are running, and that two of them are in # our deployment fake_one_running = flexmock( name="fake_one", key_name=self.keyname, state="running", id="i-ONE", public_dns_name="public1", private_dns_name="private1", ) fake_two_running = flexmock( name="fake_two", key_name=self.keyname, state="running", id="i-TWO", public_dns_name="public2", private_dns_name="private2", ) fake_three_running = flexmock( name="fake_three", key_name="abcdefg", state="running", id="i-THREE", public_dns_name="public3", private_dns_name="private3", ) fake_reservation_running = flexmock( name="fake_reservation", instances=[fake_one_running, fake_two_running, fake_three_running] ) fake_one_terminated = flexmock( name="fake_one", key_name=self.keyname, state="terminated", id="i-ONE", public_dns_name="public1", private_dns_name="private1", ) fake_two_terminated = flexmock( name="fake_two", key_name=self.keyname, state="terminated", id="i-TWO", public_dns_name="public2", private_dns_name="private2", ) fake_three_terminated = flexmock( name="fake_three", key_name="abcdefg", state="terminated", id="i-THREE", public_dns_name="public3", private_dns_name="private3", ) fake_reservation_terminated = flexmock( name="fake_reservation", instances=[fake_one_terminated, fake_two_terminated, fake_three_terminated] ) fake_ec2.should_receive("get_all_instances").and_return(fake_reservation_running).and_return( fake_reservation_terminated ) flexmock(boto) boto.should_receive("connect_ec2").and_return(fake_ec2) # and mock out the call to kill the instances fake_ec2.should_receive("terminate_instances").with_args(["i-ONE", "i-TWO"]).and_return( [fake_one_terminated, fake_two_terminated] ) # mock out the call to delete the keypair fake_ec2.should_receive("delete_key_pair").and_return() # and the call to delete the security group - let's say that we can't # delete the group the first time, and can the second fake_ec2.should_receive("delete_security_group").and_return(False).and_return(True) # finally, mock out removing the yaml file, json file, and secret key from # this machine flexmock(os) os.should_receive("remove").with_args(LocalState.get_locations_yaml_location(self.keyname)).and_return() os.should_receive("remove").with_args(LocalState.get_locations_json_location(self.keyname)).and_return() os.should_receive("remove").with_args(LocalState.get_secret_key_location(self.keyname)).and_return() argv = ["--keyname", self.keyname] options = ParseArgs(argv, self.function).args AppScaleTools.terminate_instances(options)
def setUp(self): # mock out all logging, since it clutters our output flexmock(AppScaleLogger) AppScaleLogger.should_receive('log').and_return() # mock out all sleeps, as they aren't necessary for unit testing flexmock(time) time.should_receive('sleep').and_return() # set up some fake options so that we don't have to generate them via # ParseArgs self.options = flexmock(infrastructure='ec2', group='boogroup', machine='ami-ABCDEFG', instance_type='m1.large', keyname='bookey', table='cassandra', verbose=False, test=False, use_spot_instances=False) self.my_id = "12345" self.node_layout = NodeLayout(self.options) # set up phony AWS credentials for each test # ones that test not having them present can # remove them for credential in EucalyptusAgent.REQUIRED_EC2_CREDENTIALS: os.environ[credential] = "baz" os.environ['EC2_URL'] = "http://boo" # mock out calls to EC2 # begin by assuming that our ssh keypair doesn't exist, and thus that we # need to create it key_contents = "key contents here" fake_key = flexmock(name="fake_key", material=key_contents) fake_key.should_receive('save').with_args( os.environ['HOME'] + '/.appscale').and_return(None) fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_key_pair').with_args('bookey') \ .and_return(None) fake_ec2.should_receive('create_key_pair').with_args('bookey') \ .and_return(fake_key) # mock out writing the secret key builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') # set the fall-through secret_key_location = LocalState.LOCAL_APPSCALE_PATH + "bookey.secret" fake_secret = flexmock(name="fake_secret") fake_secret.should_receive('write').and_return() builtins.should_receive('open').with_args(secret_key_location, 'w') \ .and_return(fake_secret) # also, mock out the keypair writing and chmod'ing ssh_key_location = LocalState.LOCAL_APPSCALE_PATH + "bookey.key" fake_file = flexmock(name="fake_file") fake_file.should_receive('write').with_args(key_contents).and_return() builtins.should_receive('open').with_args(ssh_key_location, 'w') \ .and_return(fake_file) flexmock(os) os.should_receive('chmod').with_args(ssh_key_location, 0600).and_return() # next, assume there are no security groups up yet fake_ec2.should_receive('get_all_security_groups').and_return([]) # and then assume we can create and open our security group fine fake_ec2.should_receive('create_security_group').with_args( 'boogroup', 'AppScale security group').and_return() fake_ec2.should_receive('authorize_security_group').and_return() # next, add in mocks for run_instances # the first time around, let's say that no machines are running # the second time around, let's say that our machine is pending # and that it's up the third time around fake_pending_instance = flexmock(state='pending') fake_pending_reservation = flexmock(instances=fake_pending_instance) fake_running_instance = flexmock(state='running', key_name='bookey', id='i-12345678', public_dns_name='public1', private_dns_name='private1') fake_running_reservation = flexmock(instances=fake_running_instance) fake_ec2.should_receive('get_all_instances').and_return([]) \ .and_return([fake_pending_reservation]) \ .and_return([fake_running_reservation]) # next, assume that our run_instances command succeeds fake_ec2.should_receive('run_instances').and_return() # finally, inject our mocked EC2 flexmock(boto) boto.should_receive('connect_ec2').and_return(fake_ec2) # assume that ssh comes up on the third attempt fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('public1', RemoteHelper.SSH_PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) # throw some default mocks together for when invoking via shell succeeds # and when it fails self.fake_temp_file = flexmock(name='fake_temp_file') self.fake_temp_file.should_receive('seek').with_args(0).and_return() self.fake_temp_file.should_receive('read').and_return('boo out') self.fake_temp_file.should_receive('close').and_return() flexmock(tempfile) tempfile.should_receive('NamedTemporaryFile')\ .and_return(self.fake_temp_file) self.success = flexmock(name='success', returncode=0) self.success.should_receive('wait').and_return(0) self.failed = flexmock(name='success', returncode=1) self.failed.should_receive('wait').and_return(1) # assume that root login isn't already enabled local_state = flexmock(LocalState) local_state.should_receive('shell') \ .with_args(re.compile('^ssh .*root'), False, 1, stdin='ls') \ .and_return('Please login as the ubuntu user rather than root user.') # and assume that we can ssh in as ubuntu to enable root login local_state = flexmock(LocalState) local_state.should_receive('shell')\ .with_args(re.compile('^ssh .*ubuntu'),False,5)\ .and_return() # also assume that we can scp over our ssh keys local_state.should_receive('shell')\ .with_args(re.compile('scp .*/root/.ssh/id_'),False,5)\ .and_return() local_state.should_receive('shell')\ .with_args(re.compile('scp .*/root/.appscale/bookey.key'),False,5)\ .and_return()
def setup_ec2_mocks(self): # first, pretend that our image does exist in EC2 self.fake_ec2.should_receive("get_image").with_args("ami-ABCDEFG").and_return() # Also pretend that the availability zone we want to use exists. self.fake_ec2.should_receive("get_all_zones").with_args("my-zone-1b").and_return("anything") # next, assume that our keypair doesn't exist yet self.fake_ec2.should_receive("get_key_pair").with_args(self.keyname).and_return(None) # next, assume there are no security groups up at first, but then it gets # created. udp_rule = flexmock(from_port=1, to_port=65535, ip_protocol="udp") tcp_rule = flexmock(from_port=1, to_port=65535, ip_protocol="tcp") icmp_rule = flexmock(from_port=-1, to_port=-1, ip_protocol="icmp") group = flexmock(name=self.group, rules=[tcp_rule, udp_rule, icmp_rule]) self.fake_ec2.should_receive("get_all_security_groups").with_args().and_return([]) self.fake_ec2.should_receive("get_all_security_groups").with_args(self.group).and_return([group]) # mock out creating the keypair fake_key = flexmock(name="fake_key", material="baz") self.local_state.should_receive("write_key_file").with_args( re.compile(self.keyname), fake_key.material ).and_return() self.fake_ec2.should_receive("create_key_pair").with_args(self.keyname).and_return(fake_key) # and the same for the security group self.fake_ec2.should_receive("create_security_group").with_args(self.group, str).and_return() self.fake_ec2.should_receive("authorize_security_group").with_args( self.group, from_port=1, to_port=65535, ip_protocol="udp", cidr_ip="0.0.0.0/0" ) self.fake_ec2.should_receive("authorize_security_group").with_args( self.group, from_port=1, to_port=65535, ip_protocol="tcp", cidr_ip="0.0.0.0/0" ) self.fake_ec2.should_receive("authorize_security_group").with_args( self.group, from_port=-1, to_port=-1, ip_protocol="icmp", cidr_ip="0.0.0.0/0" ) # assume that there are no instances running initially, and that the # instance we spawn starts as pending, then becomes running no_instances = flexmock(name="no_instances", instances=[]) pending_instance = flexmock(name="pending_instance", state="pending", key_name=self.keyname, id="i-ABCDEFG") pending_reservation = flexmock(name="pending_reservation", instances=[pending_instance]) running_instance = flexmock( name="running_instance", state="running", key_name=self.keyname, id="i-ABCDEFG", public_dns_name="public1", private_dns_name="private1", ) running_reservation = flexmock(name="running_reservation", instances=[running_instance]) self.fake_ec2.should_receive("get_all_instances").and_return(no_instances).and_return( pending_reservation ).and_return(running_reservation) # finally, inject the mocked EC2 in flexmock(boto) boto.should_receive("connect_ec2").and_return(self.fake_ec2)
def setUp(self): # mock out printing to stdout builtins = flexmock(sys.modules['__builtin__']) builtins.should_receive('print').and_return() # next, pretend our ec2 credentials are properly set for credential in EC2Agent.REQUIRED_CREDENTIALS: os.environ[credential] = "baz" # finally, pretend that our ec2 image to use exists fake_ec2 = flexmock(name="fake_ec2") fake_ec2.should_receive('get_image').with_args('ami-ABCDEFG') \ .and_return() flexmock(boto) boto.should_receive('connect_ec2').with_args( 'baz', 'baz').and_return(fake_ec2) # do argument parsing here, since the below tests do it the # same way every time argv = [ "--min", "1", "--max", "1", "--infrastructure", "ec2", "--machine", "ami-ABCDEFG", "--group", "blargscale" ] function = "appscale-run-instances" self.options = ParseArgs(argv, function).args self.my_id = "12345" self.expected = { "EC2_ACCESS_KEY": None, "EC2_SECRET_KEY": None, "EC2_URL": None, "admin_pass": None, "admin_user": None, "appengine": 1, "autoscale": True, "min": 1, "max": 1, "infrastructure": "ec2", "machine": "ami-ABCDEFG", "force": False, "group": "blargscale", "instance_type": "m1.large", "ips": None, "ips_layout": None, "keyname": "appscale", "login_host": None, "max_spot_price": None, "replication": None, "scp": None, "table": "cassandra", "test": False, "use_spot_instances": False, "verbose": False, "version": False } # finally, construct a http payload for mocking that the below # tests can use self.payload = "?boo=baz&min=1&max=1&infrastructure=ec2" + \ "&machine=ami-ABCDEFG&force=False&group=appscale" + \ "&instance_type=m1.large&ips=None&keyname=appscale&n=None" + \ "table=cassandra&test=False&version=False"