def test_upload_app(self):
        app_id = 'guestbook'
        source_path = '{}.tar.gz'.format(app_id)
        extracted_dir = '/tmp/{}'.format(app_id)
        head_node = '192.168.33.10'
        secret = 'secret-key'
        operation_id = 'operation-1'
        port = 8080
        version_url = 'http://{}:{}'.format(head_node, port)

        argv = ['--keyname', self.keyname, '--file', source_path, '--test']
        options = ParseArgs(argv, self.function).args

        version = Version('python27', 'app.yaml')
        version.project_id = app_id

        flexmock(LocalState).should_receive('extract_tgz_app_to_dir').\
          and_return('/tmp/{}'.format(app_id))
        flexmock(Version).should_receive('from_tar_gz').and_return(version)
        flexmock(AppEngineHelper).should_receive('validate_app_id')
        flexmock(LocalState).should_receive('get_host_with_role').\
          and_return(head_node)
        flexmock(LocalState).should_receive('get_secret_key').and_return(
            secret)
        flexmock(RemoteHelper).should_receive('copy_app_to_host').\
          with_args(extracted_dir, app_id, self.keyname, {}, None).\
          and_return(source_path)
        flexmock(AdminClient).should_receive('create_version').\
          and_return(operation_id)
        flexmock(AdminClient).should_receive('get_operation').\
          and_return({'done': True, 'response': {'versionUrl': version_url}})
        flexmock(shutil).should_receive('rmtree').with_args(extracted_dir)
        flexmock(AppEngineHelper).should_receive('warn_if_version_defined')

        given_host, given_port = AppScaleTools.upload_app(options)
        self.assertEquals(given_host, head_node)
        self.assertEquals(given_port, port)

        # If provided user is not app admin, deployment should fail.
        flexmock(AdminClient).should_receive('create_version').\
          and_raise(AdminError)
        self.assertRaises(AdminError, AppScaleTools.upload_app, options)

        # An application with the PHP runtime should be deployed successfully.
        version = Version('php', 'app.yaml')
        version.project_id = app_id
        flexmock(Version).should_receive('from_tar_gz').and_return(version)
        flexmock(AdminClient).should_receive('create_version').\
          and_return(operation_id)
        given_host, given_port = AppScaleTools.upload_app(options)
        self.assertEquals(given_host, head_node)
        self.assertEquals(given_port, port)
  def test_upload_app(self):
    app_id = 'guestbook'
    source_path = '{}.tar.gz'.format(app_id)
    extracted_dir = '/tmp/{}'.format(app_id)
    head_node = '192.168.33.10'
    secret = 'secret-key'
    operation_id = 'operation-1'
    port = 8080
    version_url = 'http://{}:{}'.format(head_node, port)

    argv = ['--keyname', self.keyname, '--file', source_path, '--test']
    options = ParseArgs(argv, self.function).args

    version = Version('python27', 'app.yaml')
    version.project_id = app_id

    flexmock(LocalState).should_receive('extract_tgz_app_to_dir').\
      and_return('/tmp/{}'.format(app_id))
    flexmock(Version).should_receive('from_tar_gz').and_return(version)
    flexmock(AppEngineHelper).should_receive('validate_app_id')
    flexmock(LocalState).should_receive('get_host_with_role').\
      and_return(head_node)
    flexmock(LocalState).should_receive('get_secret_key').and_return(secret)
    flexmock(RemoteHelper).should_receive('copy_app_to_host').\
      with_args(extracted_dir, app_id, self.keyname, False, {}, None).\
      and_return(source_path)
    flexmock(AdminClient).should_receive('create_version').\
      and_return(operation_id)
    flexmock(AdminClient).should_receive('get_operation').\
      and_return({'done': True, 'response': {'versionUrl': version_url}})
    flexmock(shutil).should_receive('rmtree').with_args(extracted_dir)
    flexmock(AppEngineHelper).should_receive('warn_if_version_defined')

    given_host, given_port = AppScaleTools.upload_app(options)
    self.assertEquals(given_host, head_node)
    self.assertEquals(given_port, port)

    # If provided user is not app admin, deployment should fail.
    flexmock(AdminClient).should_receive('create_version').\
      and_raise(AdminError)
    self.assertRaises(AdminError, AppScaleTools.upload_app, options)

    # An application with the PHP runtime should be deployed successfully.
    version = Version('php', 'app.yaml')
    version.project_id = app_id
    flexmock(Version).should_receive('from_tar_gz').and_return(version)
    flexmock(AdminClient).should_receive('create_version').\
      and_return(operation_id)
    given_host, given_port = AppScaleTools.upload_app(options)
    self.assertEquals(given_host, head_node)
    self.assertEquals(given_port, port)
  def stop_service(cls, options):
    """Instructs AppScale to stop the named service.

    This is applicable for services using manual scaling.

    Args:
      options: A Namespace that has fields for each parameter that can be
        passed in via the command-line interface.
    Raises:
      AppScaleException: If the named service isn't running in this
        AppScale cloud, or if stop is not valid for the service.
    """
    if not options.confirm:
      response = raw_input(
        'Are you sure you want to stop this service? (y/N) ')
      if response.lower() not in ['y', 'yes']:
        raise AppScaleException("Cancelled service stop.")

    load_balancer_ip = LocalState.get_host_with_role(
      options.keyname, 'load_balancer')
    secret = LocalState.get_secret_key(options.keyname)
    admin_client = AdminClient(load_balancer_ip, secret)

    version = Version(None, None)
    version.project_id = options.project_id
    version.service_id = options.service_id or DEFAULT_SERVICE
    version.id = DEFAULT_VERSION
    version.serving_status = 'STOPPED'

    admin_client.patch_version(version, ['servingStatus'])

    AppScaleLogger.success('Stop requested for {}.'.format(options.project_id))
  def start_service(cls, options):
    """Instructs AppScale to start the named service.

    This is applicable for services using manual scaling.

    Args:
      options: A Namespace that has fields for each parameter that can be
        passed in via the command-line interface.
    Raises:
      AppScaleException: If the named service isn't running in this
        AppScale cloud, or if start is not valid for the service.
    """
    load_balancer_ip = LocalState.get_host_with_role(
      options.keyname, 'load_balancer')
    secret = LocalState.get_secret_key(options.keyname)
    admin_client = AdminClient(load_balancer_ip, secret)

    version = Version(None, None)
    version.project_id = options.project_id
    version.service_id = options.service_id or DEFAULT_SERVICE
    version.id = DEFAULT_VERSION
    version.serving_status = 'SERVING'

    admin_client.patch_version(version, ['servingStatus'])

    AppScaleLogger.success('Start requested for {}.'.format(options.project_id))