def test_start_remote_appcontroller(self): # mock out removing the old json file local_state = flexmock(LocalState) local_state.should_receive('shell')\ .with_args(re.compile('^ssh'),False,5,stdin=re.compile('rm -rf'))\ .and_return() # assume we started monit on public1 fine local_state.should_receive('shell')\ .with_args(re.compile('^ssh'), False, 5, stdin=re.compile('monit'))\ .and_return() # and assume we started the AppController on public1 fine local_state.should_receive('shell').with_args( re.compile('^ssh'), False, 5, stdin='service appscale-controller start') # finally, assume the appcontroller comes up after a few tries # assume that ssh comes up on the third attempt fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('public1', AppControllerClient.PORT)).and_raise(Exception) \ .and_raise(Exception).and_return(None) socket.should_receive('socket').and_return(fake_socket) # Mock out additional remote calls. local_state.should_receive('shell').with_args('ssh -i /root/.appscale/bookey.key -o LogLevel=quiet -o NumberOfPasswordPrompts=0 -o StrictHostkeyChecking=no -o UserKnownHostsFile=/dev/null root@public1 ', False, 5, stdin='cp /root/appscale/AppController/scripts/appcontroller /etc/init.d/').and_return() local_state.should_receive('shell').with_args('ssh -i /root/.appscale/bookey.key -o LogLevel=quiet -o NumberOfPasswordPrompts=0 -o StrictHostkeyChecking=no -o UserKnownHostsFile=/dev/null root@public1 ', False, 5, stdin='chmod +x /etc/init.d/appcontroller').and_return() local_state.should_receive('shell').with_args('ssh -i /root/.appscale/boobazblargfoo.key -o LogLevel=quiet -o NumberOfPasswordPrompts=0 -o StrictHostkeyChecking=no -o UserKnownHostsFile=/dev/null root@elastic-ip ', False, 5, stdin='chmod +x /etc/init.d/appcontroller').and_return() RemoteHelper.start_remote_appcontroller('public1', 'bookey', False)
def test_start_remote_appcontroller(self): # mock out removing the old json file local_state = flexmock(LocalState) local_state.should_receive('shell')\ .with_args(re.compile('^ssh'),False,5,stdin=re.compile('rm -rf'))\ .and_return() # assume we started monit on public1 fine local_state.should_receive('shell')\ .with_args(re.compile('^ssh'), False, 5, stdin=re.compile('monit'))\ .and_return() # also assume that we scp'ed over the god config file fine local_state.should_receive('shell')\ .with_args(re.compile('scp .*controller-17443.cfg*'),False,5)\ .and_return() # and assume we started the AppController on public1 fine local_state.should_receive('shell')\ .with_args(re.compile('^ssh'), False, 5, stdin=re.compile('^monit start -g controller'))\ .and_return() # finally, assume the appcontroller comes up after a few tries # assume that ssh comes up on the third attempt fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('public1', AppControllerClient.PORT)).and_raise(Exception) \ .and_raise(Exception).and_return(None) socket.should_receive('socket').and_return(fake_socket) RemoteHelper.start_remote_appcontroller('public1', 'bookey', False)
def test_start_remote_appcontroller(self): # mock out removing the old json file local_state = flexmock(LocalState) local_state.should_receive("shell").with_args( re.compile("^ssh"), False, 5, stdin=re.compile("rm -rf") ).and_return().ordered() # assume we started god on public1 fine local_state.should_receive("shell").with_args( re.compile("^ssh"), False, 5, stdin=re.compile("nohup god") ).and_return().ordered() # also assume that we scp'ed over the god config file fine local_state.should_receive("shell").with_args( re.compile("scp .*appcontroller\.god.*"), False, 5 ).and_return().ordered() # and assume we started the AppController on public1 fine local_state.should_receive("shell").with_args( re.compile("^ssh"), False, 5, stdin=re.compile("^god load .*appcontroller\.god") ).and_return().ordered() # finally, assume the appcontroller comes up after a few tries # assume that ssh comes up on the third attempt fake_socket = flexmock(name="fake_socket") fake_socket.should_receive("connect").with_args(("public1", AppControllerClient.PORT)).and_raise( Exception ).and_raise(Exception).and_return(None) socket.should_receive("socket").and_return(fake_socket) RemoteHelper.start_remote_appcontroller("public1", "bookey", False)
def test_start_remote_appcontroller(self): # mock out removing the old json file subprocess.should_receive('Popen').with_args(re.compile('rm -rf'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # assume we started god on public1 fine subprocess.should_receive('Popen').with_args(re.compile('god &'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # also assume that we scp'ed over the god config file fine subprocess.should_receive('Popen').with_args(re.compile('appcontroller'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # and assume we started the AppController on public1 fine subprocess.should_receive('Popen').with_args(re.compile('god load'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # finally, assume the appcontroller comes up after a few tries # assume that ssh comes up on the third attempt fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('public1', AppControllerClient.PORT)).and_raise(Exception) \ .and_raise(Exception).and_return(None) socket.should_receive('socket').and_return(fake_socket) RemoteHelper.start_remote_appcontroller('public1', 'bookey', False)
def test_start_remote_appcontroller(self): local_state = flexmock(LocalState) # and assume we started the AppController on public1 fine local_state.should_receive('shell').with_args( re.compile('^ssh'), False, 5, stdin='systemctl start appscale-controller') # finally, assume the appcontroller comes up after a few tries # assume that ssh comes up on the third attempt fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('public1', AppControllerClient.PORT)).and_raise(Exception) \ .and_raise(Exception).and_return(None) socket.should_receive('socket').and_return(fake_socket) RemoteHelper.start_remote_appcontroller('public1', 'bookey', False)
def setup_socket_mocks(self, host): # assume that ssh comes up on the third attempt fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args((host, 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((host, AppControllerClient.PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # as well as for the AppDashboard fake_socket.should_receive('connect').with_args((host, RemoteHelper.APP_DASHBOARD_PORT)).and_raise(Exception) \ .and_raise(Exception).and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket)
def test_upload_php_app_successfully(self): app_dir = '/tmp/appscale-app-1234' # add in mocks so that the gzip'ed file gets extracted to /tmp # as well as for removing it later flexmock(os) os.should_receive('mkdir').with_args(app_dir) \ .and_return(True) flexmock(shutil) shutil.should_receive('rmtree').with_args(app_dir).and_return() local_state = flexmock(LocalState) local_state.should_receive('shell')\ .with_args(re.compile('tar zxvf'),False)\ .and_return() # add in mocks so that there is an app.yaml, but with no appid set flexmock(os.path) os.path.should_call('exists') app_yaml_location = AppEngineHelper.get_app_yaml_location(app_dir) os.path.should_receive('exists').with_args(app_yaml_location) \ .and_return(True) # mock out reading the app.yaml file builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') # set the fall-through fake_app_yaml = flexmock(name="fake_app_yaml") fake_app_yaml.should_receive('read').and_return( yaml.dump({ 'application': 'baz', 'runtime': 'php' })) builtins.should_receive('open').with_args(app_yaml_location, 'r') \ .and_return(fake_app_yaml) # Mock out service host and port app_data = { 'owner': '*****@*****.**', 'hosts': { '192.168.1.1': { 'http': 8080, 'https': 4380 } } } app_stats_data = { 'apps': { 'baz': { 'http': 8080, 'language': 'python27', 'total_reqs': 'no_change', 'appservers': 1, 'https': 4380, 'reqs_enqueued': None } } } remote_tarball = '/opt/appscale/apps/baz.tar.gz' # mock out the SOAP call to the AppController and assume it succeeded fake_appcontroller = flexmock(name='fake_appcontroller') fake_appcontroller.should_receive('status').with_args('the secret') \ .and_return('Database is at public1') fake_appcontroller.should_receive('done_uploading').with_args( 'baz', remote_tarball, 'the secret').and_return() fake_appcontroller.should_receive('update').with_args( ['baz'], 'the secret').and_return() fake_appcontroller.should_receive('does_user_exist').with_args( '*****@*****.**', 'the secret').and_return('true') fake_appcontroller.should_receive('does_user_exist').with_args( 'a@public1', 'the secret').and_return('true') fake_appcontroller.should_receive('does_app_exist').with_args( 'baz', 'the secret').and_return(json.dumps(app_data)) fake_appcontroller.should_receive('get_app_data').with_args( 'baz', 'the secret').and_return(json.dumps(app_data)) fake_appcontroller.should_receive('get_all_stats').with_args( 'the secret').and_return(json.dumps(app_stats_data)) flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://*****:*****@a.com") flexmock(getpass) getpass.should_receive('getpass').and_return('aaaaaa') # mock out making the remote app directory local_state.should_receive('shell') \ .with_args(re.compile('^ssh'), False, 5, stdin=re.compile('^mkdir -p')) \ .and_return() # and mock out tarring and copying the app local_state.should_receive('shell') \ .with_args(re.compile('tar -czf'), False) \ .and_return() local_state.should_receive('shell') \ .with_args(re.compile('/tmp/appscale-app-baz.tar.gz'), False, 5) \ .and_return() # as well as removing the tar'ed app once we're done copying it flexmock(os) os.should_receive('remove').with_args('/tmp/appscale-app-baz-1234.tar.gz') \ .and_return() os.should_receive('listdir').and_return(['app.yaml', 'index.py']) # and slap in a mock that says the app comes up after waiting for it # three times fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('public1', 8080)).and_raise(Exception).and_raise(Exception) \ .and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) flexmock(RemoteHelper).should_receive('copy_app_to_host').\ and_return(remote_tarball) argv = ["--keyname", self.keyname, "--file", self.app_dir + ".tar.gz"] options = ParseArgs(argv, self.function).args (host, port) = AppScaleTools.upload_app(options) self.assertEquals('public1', host) self.assertEquals(8080, port)
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', static_ip=None) 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([]) \ .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.ec2) boto.ec2.should_receive('connect_to_region').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(RemoteHelper.LOGIN_AS_UBUNTU_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): # 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_upload_app_successfully(self): # add in mocks so that there is an app.yaml, but with no appid set flexmock(os.path) os.path.should_call('exists') app_yaml_location = AppEngineHelper.get_app_yaml_location(self.app_dir) os.path.should_receive('exists').with_args(app_yaml_location) \ .and_return(True) # mock out reading the app.yaml file builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') # set the fall-through fake_app_yaml = flexmock(name="fake_app_yaml") fake_app_yaml.should_receive('read').and_return( yaml.dump({ 'application': 'baz', 'runtime': 'python27' })) builtins.should_receive('open').with_args(app_yaml_location, 'r') \ .and_return(fake_app_yaml) # mock out the SOAP call to the AppController and assume it succeeded fake_appcontroller = flexmock(name='fake_appcontroller') fake_appcontroller.should_receive('status').with_args('the secret') \ .and_return('Database is at public1') fake_appcontroller.should_receive('done_uploading').with_args( 'baz', '/opt/appscale/apps/baz.tar.gz', 'the secret').and_return() fake_appcontroller.should_receive('update').with_args( ['baz'], 'the secret').and_return() fake_appcontroller.should_receive('is_app_running').with_args( 'baz', 'the secret').and_return(False).and_return(True) flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://*****:*****@a.com', 'the secret').and_return('false') fake_userappserver.should_receive('does_user_exist').with_args( 'a@public1', 'the secret').and_return('false') fake_userappserver.should_receive('commit_new_user').with_args( '*****@*****.**', 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('get_app_data').with_args( 'baz', 'the secret').and_return('\n\nnum_ports:0\n') \ .and_return(app_data).and_return(app_data).and_return(app_data) fake_userappserver.should_receive('commit_new_app').with_args( 'baz', '*****@*****.**', 'python27', 'the secret').and_return('true') SOAPpy.should_receive('SOAPProxy').with_args('https://*****:*****@a.com") flexmock(getpass) getpass.should_receive('getpass').and_return('aaaaaa') # mock out making the remote app directory flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('mkdir -p'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # and mock out tarring and copying the app subprocess.should_receive('Popen').with_args(re.compile('tar -czhf'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) subprocess.should_receive('Popen').with_args(re.compile( '/tmp/appscale-app-baz.tar.gz'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # as well as removing the tar'ed app once we're done copying it flexmock(os) os.should_receive('remove').with_args('/tmp/appscale-app-baz-1234.tar.gz') \ .and_return() # and slap in a mock that says the app comes up after waiting for it # three times fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('public1', 8080)).and_raise(Exception).and_raise(Exception) \ .and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) argv = ["--keyname", self.keyname, "--file", self.app_dir] options = ParseArgs(argv, self.function).args (host, port) = AppScaleTools.upload_app(options) self.assertEquals('public1', host) self.assertEquals(8080, port)
def test_upload_tar_gz_app_successfully(self): # mock out generating a random app dir, for later mocks flexmock(uuid) uuid.should_receive('uuid4').and_return('12345678') app_dir = '/tmp/appscale-app-12345678' # add in mocks so that the gzip'ed file gets extracted to /tmp # as well as for removing it later flexmock(os) os.should_receive('mkdir').with_args(app_dir) \ .and_return(True) flexmock(shutil) shutil.should_receive('rmtree').with_args(app_dir).and_return() local_state = flexmock(LocalState) local_state.should_receive('shell')\ .with_args(re.compile('tar zxvf'),False)\ .and_return() # add in mocks so that there is an app.yaml, but with no appid set flexmock(os.path) os.path.should_call('exists') app_yaml_location = AppEngineHelper.get_app_yaml_location(app_dir) os.path.should_receive('exists').with_args(app_yaml_location) \ .and_return(True) # mock out reading the app.yaml file builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') # set the fall-through fake_app_yaml = flexmock(name="fake_app_yaml") fake_app_yaml.should_receive('read').and_return(yaml.dump({ 'application' : 'baz', 'runtime' : 'python' })) builtins.should_receive('open').with_args(app_yaml_location, 'r') \ .and_return(fake_app_yaml) # mock out the SOAP call to the AppController and assume it succeeded fake_appcontroller = flexmock(name='fake_appcontroller') fake_appcontroller.should_receive('status').with_args('the secret') \ .and_return('Database is at public1') fake_appcontroller.should_receive('done_uploading').with_args('baz', '/var/apps/baz/app/baz.tar.gz', 'the secret').and_return() fake_appcontroller.should_receive('update').with_args(['baz'], 'the secret').and_return() fake_appcontroller.should_receive('is_app_running').with_args('baz', 'the secret').and_return(False).and_return(True) flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://*****:*****@a.com', 'the secret').and_return('false') fake_userappserver.should_receive('commit_new_user').with_args( '*****@*****.**', 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('get_app_data').with_args( 'baz', 'the secret').and_return('\n\nnum_ports:0\n') \ .and_return(app_data).and_return(app_data).and_return(app_data) fake_userappserver.should_receive('commit_new_app').with_args( 'baz', '*****@*****.**', 'python', 'the secret').and_return('true') SOAPpy.should_receive('SOAPProxy').with_args('https://*****:*****@a.com") flexmock(getpass) getpass.should_receive('getpass').and_return('aaaaaa') # mock out making the remote app directory local_state.should_receive('shell')\ .with_args(re.compile('^ssh'),False,5,stdin=re.compile('^mkdir -p'))\ .and_return() # and mock out tarring and copying the app local_state.should_receive('shell')\ .with_args(re.compile('tar -czf'),False)\ .and_return() local_state.should_receive('shell')\ .with_args(re.compile('/tmp/appscale-app-baz.tar.gz'),False,5)\ .and_return() # as well as removing the tar'ed app once we're done copying it flexmock(os) os.should_receive('remove').with_args('/tmp/appscale-app-baz.tar.gz') \ .and_return() # and slap in a mock that says the app comes up after waiting for it # three times fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('public1', 8080)).and_raise(Exception).and_raise(Exception) \ .and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) argv = [ "--keyname", self.keyname, "--file", self.app_dir + ".tar.gz" ] options = ParseArgs(argv, self.function).args AppScaleTools.upload_app(options)
def test_upload_php_app_successfully(self): app_dir = '/tmp/appscale-app-1234' # add in mocks so that the gzip'ed file gets extracted to /tmp # as well as for removing it later flexmock(os) os.should_receive('mkdir').with_args(app_dir) \ .and_return(True) flexmock(shutil) shutil.should_receive('rmtree').with_args(app_dir).and_return() local_state = flexmock(LocalState) local_state.should_receive('shell')\ .with_args(re.compile('tar zxvf'),False)\ .and_return() # add in mocks so that there is an app.yaml, but with no appid set flexmock(os.path) os.path.should_call('exists') app_yaml_location = AppEngineHelper.get_app_yaml_location(app_dir) os.path.should_receive('exists').with_args(app_yaml_location) \ .and_return(True) # mock out reading the app.yaml file builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') # set the fall-through fake_app_yaml = flexmock(name="fake_app_yaml") fake_app_yaml.should_receive('read').and_return(yaml.dump({ 'application' : 'baz', 'runtime' : 'php' })) builtins.should_receive('open').with_args(app_yaml_location, 'r') \ .and_return(fake_app_yaml) # Mock out service host and port app_data = {'owner' : '*****@*****.**', 'hosts' : {'192.168.1.1' : { 'http' : 8080, 'https' : 4380 }}} app_stats_data = {'apps': {'baz': {'http': 8080, 'language': 'python27', 'total_reqs': 'no_change', 'appservers': 1, 'https': 4380, 'reqs_enqueued': None}}} # mock out the SOAP call to the AppController and assume it succeeded fake_appcontroller = flexmock(name='fake_appcontroller') fake_appcontroller.should_receive('status').with_args('the secret') \ .and_return('Database is at public1') fake_appcontroller.should_receive('done_uploading').with_args('baz', '/opt/appscale/apps/baz.tar.gz', 'the secret').and_return() fake_appcontroller.should_receive('update').with_args(['baz'], 'the secret').and_return() fake_appcontroller.should_receive('is_app_running').with_args('baz', 'the secret').and_return(False).and_return(True) fake_appcontroller.should_receive('does_user_exist').with_args( '*****@*****.**', 'the secret').and_return('true') fake_appcontroller.should_receive('does_user_exist').with_args( 'a@public1', 'the secret').and_return('true') fake_appcontroller.should_receive('does_app_exist').with_args( 'baz', 'the secret').and_return(json.dumps(app_data)) fake_appcontroller.should_receive('get_app_data').with_args( 'baz', 'the secret').and_return(json.dumps(app_data)) fake_appcontroller.should_receive('get_all_stats').with_args( 'the secret').and_return(json.dumps(app_stats_data)) flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://*****:*****@a.com") flexmock(getpass) getpass.should_receive('getpass').and_return('aaaaaa') # mock out making the remote app directory local_state.should_receive('shell') \ .with_args(re.compile('^ssh'), False, 5, stdin=re.compile('^mkdir -p')) \ .and_return() # and mock out tarring and copying the app local_state.should_receive('shell') \ .with_args(re.compile('tar -czf'), False) \ .and_return() local_state.should_receive('shell') \ .with_args(re.compile('/tmp/appscale-app-baz.tar.gz'), False, 5) \ .and_return() # as well as removing the tar'ed app once we're done copying it flexmock(os) os.should_receive('remove').with_args('/tmp/appscale-app-baz-1234.tar.gz') \ .and_return() os.should_receive('listdir').and_return(['app.yaml','index.py']) # and slap in a mock that says the app comes up after waiting for it # three times fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('public1', 8080)).and_raise(Exception).and_raise(Exception) \ .and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) argv = [ "--keyname", self.keyname, "--file", self.app_dir + ".tar.gz" ] options = ParseArgs(argv, self.function).args (host, port) = AppScaleTools.upload_app(options) self.assertEquals('public1', host) self.assertEquals(8080, port)
def test_appscale_with_ips_layout_flag_and_success(self): # assume that ssh is running on each machine fake_socket = flexmock(name='socket') fake_socket.should_receive('connect').with_args(('1.2.3.4', 22)) \ .and_return(None) fake_socket.should_receive('connect').with_args(('1.2.3.5', 22)) \ .and_return(None) fake_socket.should_receive('connect').with_args(('1.2.3.6', 22)) \ .and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) # assume that we have ssh-keygen and ssh-copy-id flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('which ssh-keygen'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('which ssh-copy-id'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # assume that we have a ~/.appscale flexmock(os.path) os.path.should_call('exists') os.path.should_receive('exists').with_args(LocalState.LOCAL_APPSCALE_PATH) \ .and_return(True) # and assume that we don't have public and private keys already made path = LocalState.LOCAL_APPSCALE_PATH + self.keyname public_key = LocalState.LOCAL_APPSCALE_PATH + self.keyname + '.pub' private_key = LocalState.LOCAL_APPSCALE_PATH + self.keyname + '.key' os.path.should_receive('exists').with_args(public_key).and_return( False) os.path.should_receive('exists').with_args(private_key).and_return( False) # next, assume that ssh-keygen ran fine flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('ssh-keygen'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # assume that we can rename the private key flexmock(shutil) shutil.should_receive('copy').with_args(path, private_key).and_return() # finally, assume that we can chmod 0600 those files fine flexmock(os) os.should_receive('chmod').with_args(public_key, 0600).and_return() os.should_receive('chmod').with_args(path, 0600).and_return() # and assume that we can ssh-copy-id to each of the three IPs below flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('ssh-copy-id'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # also, we should be able to copy over our new public and private keys fine flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('id_rsa[.pub]?'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # don't use a 192.168.X.Y IP here, since sometimes we set our virtual # machines to boot with those addresses (and that can mess up our tests). ips_layout = yaml.safe_load(""" master : 1.2.3.4 database: 1.2.3.4 zookeeper: 1.2.3.5 appengine: 1.2.3.6 """) argv = [ "--ips_layout", base64.b64encode(yaml.dump(ips_layout)), "--keyname", self.keyname ] options = ParseArgs(argv, self.function).args AppScaleTools.add_keypair(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 test_upload_app_when_app_exists_on_virt_cluster(self): # we do let you upload an app if it's already running # add in mocks so that there is an app.yaml with an appid set flexmock(os.path) os.path.should_call('exists') app_yaml_location = AppEngineHelper.get_app_yaml_location(self.app_dir) os.path.should_receive('exists').with_args(app_yaml_location) \ .and_return(True) # mock out reading the app.yaml file builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') # set the fall-through fake_app_yaml = flexmock(name="fake_app_yaml") fake_app_yaml.should_receive('read').and_return( yaml.dump({ 'application': 'baz', 'runtime': 'python27' })) builtins.should_receive('open').with_args(app_yaml_location, 'r') \ .and_return(fake_app_yaml) # Mock out service host and port app_data = { 'owner': '*****@*****.**', 'hosts': { '192.168.1.1': { 'http': 8080, 'https': 4380 } } } app_stats_data = { 'apps': { 'baz': { 'http': 8080, 'language': 'python27', 'total_reqs': 'no_change', 'appservers': 1, 'https': 4380, 'reqs_enqueued': None } } } # mock out the SOAP call to the AppController and assume it succeeded fake_appcontroller = flexmock(name='fake_appcontroller') fake_appcontroller.should_receive('status').with_args('the secret') \ .and_return('Database is at public1') fake_appcontroller.should_receive('done_uploading').with_args( 'baz', '/opt/appscale/apps/baz.tar.gz', 'the secret').and_return('OK') fake_appcontroller.should_receive('update').with_args( ['baz'], 'the secret').and_return('OK') fake_appcontroller.should_receive('does_user_exist').with_args( '*****@*****.**', 'the secret').and_return('true') fake_appcontroller.should_receive('does_user_exist').with_args( 'a@public1', 'the secret').and_return('true') fake_appcontroller.should_receive('does_app_exist').with_args( 'baz', 'the secret').and_return(json.dumps(app_data)) fake_appcontroller.should_receive('get_app_data').with_args( 'baz', 'the secret').and_return(json.dumps(app_data)) fake_appcontroller.should_receive('get_all_stats').with_args( 'the secret').and_return(json.dumps(app_stats_data)) flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://*****:*****@a.com") flexmock(getpass) getpass.should_receive('getpass').and_return('aaaaaa') # mock out making the remote app directory flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('mkdir -p'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # and mock out tarring and copying the app subprocess.should_receive('Popen').with_args(re.compile('tar -czhf'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) subprocess.should_receive('Popen').with_args(re.compile( '/tmp/appscale-app-baz.tar.gz'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # as well as removing the tar'ed app once we're done copying it flexmock(os) os.should_receive('remove').with_args('/tmp/appscale-app-baz-1234.tar.gz') \ .and_return() # and slap in a mock that says the app comes up after waiting for it # three times fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('public1', 8080)).and_raise(Exception).and_raise(Exception) \ .and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) argv = ["--keyname", self.keyname, "--file", self.app_dir] options = ParseArgs(argv, self.function).args (host, port) = AppScaleTools.upload_app(options) self.assertEquals('public1', host) self.assertEquals(8080, port)
def test_appscale_in_one_node_virt_deployment(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() rh = flexmock(RemoteHelper) rh.should_receive('copy_deployment_credentials').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 copying over the keys local_state.should_receive('shell')\ .with_args(re.compile('^scp .*.key'),False,5) # 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('ls /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('ls /etc/appscale/{0}'.format(APPSCALE_VERSION)))\ .and_return() # finally, 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('ls /etc/appscale/{0}/{1}'\ .format(APPSCALE_VERSION, 'cassandra')))\ .and_return() # mock out generating the private key local_state.should_receive('shell')\ .with_args(re.compile('^openssl'),False,stdin=None)\ .and_return() # mock out removing the old json file local_state = flexmock(LocalState) local_state.should_receive('shell')\ .with_args(re.compile('^ssh'),False,5,stdin=re.compile('rm -rf'))\ .and_return() # assume that we started god fine local_state.should_receive('shell')\ .with_args(re.compile('^ssh'),False,5,stdin=re.compile('god &'))\ .and_return() # and that we copied over the AppController's god file local_state.should_receive('shell')\ .with_args(re.compile('scp .*appcontroller\.god.*'),False,5)\ .and_return() # also, that we started the AppController itself local_state.should_receive('shell')\ .with_args(re.compile('^ssh'),False,5,\ stdin=re.compile('^god load .*appcontroller\.god'))\ .and_return() # assume that the AppController comes up on the third attempt fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('1.2.3.4', AppControllerClient.PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # same for the UserAppServer fake_socket.should_receive('connect').with_args(('1.2.3.4', UserAppClient.PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # as well as for the AppLoadBalancer fake_socket.should_receive('connect').with_args(('1.2.3.4', 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(['1.2.3.4'])) role_info = [{ 'public_ip' : '1.2.3.4', 'private_ip' : '1.2.3.4', '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 1.2.3.4') fake_appcontroller.should_receive('is_done_initializing') \ .and_return(False) \ .and_return(True) flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://1.2.3.4:17443') \ .and_return(fake_appcontroller) # mock out reading the locations.json file, and slip in our own json local_state.should_receive('get_local_nodes_info').and_return(json.loads( json.dumps([{ "public_ip" : "1.2.3.4", "private_ip" : "1.2.3.4", "jobs" : ["shadow", "login"] }]))) # copying over the locations yaml and json files should be fine local_state.should_receive('shell')\ .with_args(re.compile('^scp .*/etc/appscale/locations-bookey.yaml'),\ False,5)\ .and_return() local_state.should_receive('shell')\ .with_args(re.compile('^scp .*/etc/appscale/locations-bookey.json'),\ False,5)\ .and_return() local_state.should_receive('shell')\ .with_args(re.compile('^scp .*/root/.appscale/locations-bookey.json'),\ False,5)\ .and_return() # same for the secret key local_state.should_receive('shell')\ .with_args(re.compile('^scp .*.secret'),False,5)\ .and_return() # mock out calls to the UserAppServer and presume that calls to create new # users succeed fake_userappserver = flexmock(name='fake_appcontroller') fake_userappserver.should_receive('commit_new_user').with_args( '*****@*****.**', str, 'xmpp_user', 'the secret') \ .and_return('true') fake_userappserver.should_receive('commit_new_user').with_args( '[email protected]', 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://1.2.3.4:4343') \ .and_return(fake_userappserver) # don't use a 192.168.X.Y IP here, since sometimes we set our virtual # machines to boot with those addresses (and that can mess up our tests). ips_layout = yaml.safe_load(""" master : 1.2.3.4 database: 1.2.3.4 zookeeper: 1.2.3.4 appengine: 1.2.3.4 """) argv = [ "--ips_layout", base64.b64encode(yaml.dump(ips_layout)), "--keyname", self.keyname, "--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) 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_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').with_args('baz', 'baz').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('read').and_return('boo out') self.fake_temp_file.should_receive('close').and_return() flexmock(tempfile) tempfile.should_receive('TemporaryFile').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) # and assume that we can ssh in as ubuntu to enable root login, but that # it fails the first time flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('ubuntu'), \ shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.failed).and_return(self.success) # also assume that we can scp over our ssh keys, but that it fails the first # time subprocess.should_receive('Popen').with_args(re.compile('/root/.ssh/id_'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.failed).and_return(self.success) subprocess.should_receive('Popen').with_args(re.compile( '/root/.appscale/bookey.key'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.failed).and_return(self.success)
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', static_ip=None, replication=None, appengine=None, autoscale=None, user_commands=[], flower_password='', max_memory='400', ips=FOUR_NODE_CLOUD) 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', ip_address=IP_1, private_ip_address=IP_1) fake_running_reservation = flexmock(instances=fake_running_instance) fake_ec2.should_receive('get_all_instances').and_return([]) \ .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.ec2) boto.ec2.should_receive('connect_to_region').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 user "ubuntu" rather than the user "root"') # 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 test_upload_app_when_app_exists_on_virt_cluster(self): # we do let you upload an app if it's already running # add in mocks so that there is an app.yaml with an appid set flexmock(os.path) os.path.should_call('exists') app_yaml_location = AppEngineHelper.get_app_yaml_location(self.app_dir) os.path.should_receive('exists').with_args(app_yaml_location) \ .and_return(True) # mock out reading the app.yaml file builtins = flexmock(sys.modules['__builtin__']) builtins.should_call('open') # set the fall-through fake_app_yaml = flexmock(name="fake_app_yaml") fake_app_yaml.should_receive('read').and_return(yaml.dump({ 'application' : 'baz', 'runtime' : 'python27' })) builtins.should_receive('open').with_args(app_yaml_location, 'r') \ .and_return(fake_app_yaml) # mock out the SOAP call to the AppController and assume it succeeded fake_appcontroller = flexmock(name='fake_appcontroller') fake_appcontroller.should_receive('status').with_args('the secret') \ .and_return('Database is at public1') fake_appcontroller.should_receive('done_uploading').with_args( 'baz', '/opt/appscale/apps/baz.tar.gz', 'the secret').and_return('OK') fake_appcontroller.should_receive('update').with_args( ['baz'], 'the secret').and_return('OK') flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://*****:*****@a.com', 'the secret').and_return('false') fake_userappserver.should_receive('does_user_exist').with_args( 'a@public1', 'the secret').and_return('false') fake_userappserver.should_receive('commit_new_user').with_args( '*****@*****.**', 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('get_app_data').with_args( 'baz', 'the secret').and_return(app_data) SOAPpy.should_receive('SOAPProxy').with_args('https://*****:*****@a.com") flexmock(getpass) getpass.should_receive('getpass').and_return('aaaaaa') # mock out making the remote app directory flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('mkdir -p'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # and mock out tarring and copying the app subprocess.should_receive('Popen').with_args(re.compile('tar -czhf'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) subprocess.should_receive('Popen').with_args(re.compile( '/tmp/appscale-app-baz.tar.gz'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # as well as removing the tar'ed app once we're done copying it flexmock(os) os.should_receive('remove').with_args('/tmp/appscale-app-baz-1234.tar.gz') \ .and_return() # and slap in a mock that says the app comes up after waiting for it # three times fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('public1', 8080)).and_raise(Exception).and_raise(Exception) \ .and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) argv = [ "--keyname", self.keyname, "--file", self.app_dir ] options = ParseArgs(argv, self.function).args (host, port) = AppScaleTools.upload_app(options) self.assertEquals('public1', host) self.assertEquals(8080, port)
def test_appscale_in_one_node_virt_deployment(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() rh = flexmock(RemoteHelper) rh.should_receive('copy_deployment_credentials').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 copying over the keys local_state.should_receive('shell')\ .with_args(re.compile('^scp .*.key'),False,5) # 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('ls /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('ls /etc/appscale/{0}'.format(APPSCALE_VERSION)))\ .and_return() # finally, 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('ls /etc/appscale/{0}/{1}'\ .format(APPSCALE_VERSION, 'cassandra')))\ .and_return() # mock out generating the private key local_state.should_receive('shell')\ .with_args(re.compile('^openssl'),False,stdin=None)\ .and_return() # mock out removing the old json file local_state = flexmock(LocalState) local_state.should_receive('shell')\ .with_args(re.compile('^ssh'),False,5,stdin=re.compile('rm -rf'))\ .and_return() # assume that we started god fine local_state.should_receive('shell')\ .with_args(re.compile('^ssh'),False,5,stdin=re.compile('god &'))\ .and_return() # and that we copied over the AppController's god file local_state.should_receive('shell')\ .with_args(re.compile('scp .*appcontroller\.god.*'),False,5)\ .and_return() # also, that we started the AppController itself local_state.should_receive('shell')\ .with_args(re.compile('^ssh'),False,5,\ stdin=re.compile('^god load .*appcontroller\.god'))\ .and_return() # assume that the AppController comes up on the third attempt fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('1.2.3.4', AppControllerClient.PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # same for the UserAppServer fake_socket.should_receive('connect').with_args(('1.2.3.4', UserAppClient.PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # as well as for the AppDashboard fake_socket.should_receive('connect').with_args(('1.2.3.4', 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(['1.2.3.4'])) role_info = [{ 'public_ip' : '1.2.3.4', 'private_ip' : '1.2.3.4', '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 1.2.3.4') fake_appcontroller.should_receive('is_done_initializing') \ .and_return(False) \ .and_return(True) flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://1.2.3.4:17443') \ .and_return(fake_appcontroller) # mock out reading the locations.json file, and slip in our own json local_state.should_receive('get_local_nodes_info').and_return(json.loads( json.dumps([{ "public_ip" : "1.2.3.4", "private_ip" : "1.2.3.4", "jobs" : ["shadow", "login"] }]))) # copying over the locations yaml and json files should be fine local_state.should_receive('shell')\ .with_args(re.compile('^scp .*/etc/appscale/locations-bookey.yaml'),\ False,5)\ .and_return() local_state.should_receive('shell')\ .with_args(re.compile('^scp .*/etc/appscale/locations-bookey.json'),\ False,5)\ .and_return() local_state.should_receive('shell')\ .with_args(re.compile('^scp .*/root/.appscale/locations-bookey.json'),\ False,5)\ .and_return() # same for the secret key local_state.should_receive('shell')\ .with_args(re.compile('^scp .*.secret'),False,5)\ .and_return() # mock out calls to the UserAppServer and presume that calls to create new # users succeed fake_userappserver = flexmock(name='fake_appcontroller') fake_userappserver.should_receive('commit_new_user').with_args( '*****@*****.**', str, 'xmpp_user', 'the secret') \ .and_return('true') fake_userappserver.should_receive('commit_new_user').with_args( '[email protected]', 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://1.2.3.4:4343') \ .and_return(fake_userappserver) # don't use a 192.168.X.Y IP here, since sometimes we set our virtual # machines to boot with those addresses (and that can mess up our tests). ips_layout = yaml.safe_load(""" master : 1.2.3.4 database: 1.2.3.4 zookeeper: 1.2.3.4 appengine: 1.2.3.4 """) argv = [ "--ips_layout", base64.b64encode(yaml.dump(ips_layout)), "--keyname", self.keyname, "--test" ] options = ParseArgs(argv, self.function).args AppScaleTools.run_instances(options)
def test_appscale_with_ips_layout_flag_and_success(self): # assume that ssh is running on each machine fake_socket = flexmock(name='socket') fake_socket.should_receive('connect').with_args(('1.2.3.4', 22)) \ .and_return(None) fake_socket.should_receive('connect').with_args(('1.2.3.5', 22)) \ .and_return(None) fake_socket.should_receive('connect').with_args(('1.2.3.6', 22)) \ .and_return(None) flexmock(socket) socket.should_receive('socket').and_return(fake_socket) # assume that we have ssh-keygen and ssh-copy-id flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('which ssh-keygen'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('which ssh-copy-id'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # assume that we have a ~/.appscale flexmock(os.path) os.path.should_call('exists') os.path.should_receive('exists').with_args(LocalState.LOCAL_APPSCALE_PATH) \ .and_return(True) # and assume that we don't have public and private keys already made path = LocalState.LOCAL_APPSCALE_PATH + self.keyname public_key = LocalState.LOCAL_APPSCALE_PATH + self.keyname + '.pub' private_key = LocalState.LOCAL_APPSCALE_PATH + self.keyname + '.key' os.path.should_receive('exists').with_args(public_key).and_return(False) os.path.should_receive('exists').with_args(private_key).and_return(False) # next, assume that ssh-keygen ran fine flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('ssh-keygen'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # assume that we can rename the private key flexmock(shutil) shutil.should_receive('copy').with_args(path, private_key).and_return() # finally, assume that we can chmod 0600 those files fine flexmock(os) os.should_receive('chmod').with_args(public_key, 0600).and_return() os.should_receive('chmod').with_args(path, 0600).and_return() # and assume that we can ssh-copy-id to each of the three IPs below flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('ssh-copy-id'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # also, we should be able to copy over our new public and private keys fine flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('id_rsa[.pub]?'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # don't use a 192.168.X.Y IP here, since sometimes we set our virtual # machines to boot with those addresses (and that can mess up our tests). ips_layout = yaml.safe_load(""" master : 1.2.3.4 database: 1.2.3.4 zookeeper: 1.2.3.5 appengine: 1.2.3.6 """) argv = [ "--ips_layout", base64.b64encode(yaml.dump(ips_layout)), "--keyname", self.keyname ] options = ParseArgs(argv, self.function).args AppScaleTools.add_keypair(options)
def test_appscale_in_one_node_virt_deployment(self): # let's say that appscale isn't already running flexmock(os.path) os.path.should_call('exists') os.path.should_receive('exists').with_args( LocalState.get_locations_yaml_location(self.keyname)).and_return(False) # 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('HTTPSConnection').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 seeing if the image is appscale-compatible, and assume it is # mock out our attempts to find /etc/appscale and presume it does exist flexmock(subprocess) subprocess.should_receive('Popen').with_args(re.compile('/etc/appscale'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # mock out our attempts to find /etc/appscale/version and presume it does # exist subprocess.should_receive('Popen').with_args(re.compile( '/etc/appscale/{0}'.format(APPSCALE_VERSION)), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # put in a mock indicating that the database the user wants is supported subprocess.should_receive('Popen').with_args(re.compile( '/etc/appscale/{0}/{1}'.format(APPSCALE_VERSION, 'cassandra')), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # mock out generating the private key flexmock(M2Crypto.RSA) fake_rsa_key = flexmock(name='fake_rsa_key') fake_rsa_key.should_receive('save_key').with_args( LocalState.get_private_key_location(self.keyname), None) M2Crypto.RSA.should_receive('gen_key').and_return(fake_rsa_key) flexmock(M2Crypto.EVP) fake_pkey = flexmock(name='fake_pkey') fake_pkey.should_receive('assign_rsa').with_args(fake_rsa_key).and_return() M2Crypto.EVP.should_receive('PKey').and_return(fake_pkey) # and mock out generating the certificate flexmock(M2Crypto.X509) fake_cert = flexmock(name='fake_x509') fake_cert.should_receive('set_pubkey').with_args(fake_pkey).and_return() fake_cert.should_receive('set_subject') fake_cert.should_receive('set_issuer_name') fake_cert.should_receive('set_not_before') fake_cert.should_receive('set_not_after') fake_cert.should_receive('sign').with_args(fake_pkey, md="sha256") fake_cert.should_receive('save_pem').with_args( LocalState.get_certificate_location(self.keyname)) M2Crypto.X509.should_receive('X509').and_return(fake_cert) # assume that we started god fine subprocess.should_receive('Popen').with_args(re.compile('god &'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # and that we copied over the AppController's god file subprocess.should_receive('Popen').with_args(re.compile( 'appcontroller.god'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # also, that we started the AppController itself subprocess.should_receive('Popen').with_args(re.compile('god load'), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # assume that the AppController comes up on the third attempt fake_socket = flexmock(name='fake_socket') fake_socket.should_receive('connect').with_args(('1.2.3.4', AppControllerClient.PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # same for the UserAppServer fake_socket.should_receive('connect').with_args(('1.2.3.4', UserAppClient.PORT)).and_raise(Exception).and_raise(Exception) \ .and_return(None) # as well as for the AppLoadBalancer fake_socket.should_receive('connect').with_args(('1.2.3.4', 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(['1.2.3.4'])) role_info = [{ 'public_ip' : '1.2.3.4', 'private_ip' : '1.2.3.4', '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 1.2.3.4') fake_appcontroller.should_receive('is_done_initializing') \ .and_raise(Exception) \ .and_return(False) \ .and_return(True) flexmock(SOAPpy) SOAPpy.should_receive('SOAPProxy').with_args('https://1.2.3.4:17443') \ .and_return(fake_appcontroller) # mock out reading the locations.json file, and slip in our own json os.path.should_receive('exists').with_args( LocalState.get_locations_json_location(self.keyname)).and_return(True) fake_nodes_json = flexmock(name="fake_nodes_json") fake_nodes_json.should_receive('read').and_return(json.dumps([{ "public_ip" : "1.2.3.4", "private_ip" : "1.2.3.4", "jobs" : ["shadow", "login"] }])) fake_nodes_json.should_receive('write').and_return() builtins.should_receive('open').with_args( LocalState.get_locations_json_location(self.keyname), 'r') \ .and_return(fake_nodes_json) builtins.should_receive('open').with_args( LocalState.get_locations_json_location(self.keyname), 'w') \ .and_return(fake_nodes_json) # copying over the locations yaml and json files should be fine subprocess.should_receive('Popen').with_args(re.compile( 'locations-{0}.[yaml|json]'.format(self.keyname)), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # same for the secret key subprocess.should_receive('Popen').with_args(re.compile( '{0}.secret'.format(self.keyname)), shell=True, stdout=self.fake_temp_file, stderr=subprocess.STDOUT) \ .and_return(self.success) # mock out calls to the UserAppServer and presume that calls to create new # users succeed fake_userappserver = flexmock(name='fake_appcontroller') fake_userappserver.should_receive('commit_new_user').with_args( '*****@*****.**', str, 'xmpp_user', 'the secret') \ .and_return('true') fake_userappserver.should_receive('commit_new_user').with_args( '[email protected]', 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://1.2.3.4:4343') \ .and_return(fake_userappserver) # don't use a 192.168.X.Y IP here, since sometimes we set our virtual # machines to boot with those addresses (and that can mess up our tests). ips_layout = yaml.safe_load(""" master : 1.2.3.4 database: 1.2.3.4 zookeeper: 1.2.3.4 appengine: 1.2.3.4 """) argv = [ "--ips_layout", base64.b64encode(yaml.dump(ips_layout)), "--keyname", self.keyname, "--test" ] options = ParseArgs(argv, self.function).args AppScaleTools.run_instances(options)