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)
Пример #4
0
  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
    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)
Пример #8
0
  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)
Пример #9
0
    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)
Пример #17
0
    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)
Пример #19
0
  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)
Пример #20
0
    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()
Пример #21
0
  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)
Пример #23
0
  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)