def testLocalTarPath(self):
     # A local tar file doesn't need to be downloaded
     self.StartObjectPatch(os.path, 'isfile', return_value=True)
     location = os.path.join('foo', 'bar.tar')
     download_path = _sdk_tar.DownloadTar(location, self.temp_dir)
     self.assertEqual(location, download_path)
     self.url_patch.assert_not_called()
 def testDownload(self):
     location = 'http://foo/bar.tar'
     download_path = _sdk_tar.DownloadTar(location, self.temp_dir)
     self.assertEqual(
         os.path.join(self.temp_dir, constants.DOWNLOAD_FOLDER, 'bar.tar'),
         download_path)
     self.url_patch.assert_called_once_with(location)
 def testDownloadTwice(self):
     location = 'http://foo/bar.tar'
     self.StartObjectPatch(os.path, 'isfile', return_value=True)
     download_path = _sdk_tar.DownloadTar(location, self.temp_dir)
     self.assertEqual(
         os.path.join(self.temp_dir, constants.DOWNLOAD_FOLDER, 'bar.tar'),
         download_path)
     self.url_patch.assert_not_called()
 def testBadLocalTarPath(self):
     self.StartObjectPatch(os.path, 'isfile', return_value=False)
     location = os.path.join('foo', 'bar.tar')
     with self.assertRaisesRegexp(ValueError, re.escape(location)):
         _sdk_tar.DownloadTar(location, self.temp_dir)
Esempio n. 5
0
def Init(tar_location=None, additional_components=None, root_directory=None):
  """Downloads and installs the SDK.

  Initialize the driver by downloading and installing the SDK. This
  initialization must be done before SDK.Run will work.

  Multiple SDK objects will share this installation; however, only the version,
  installed components and installation properties (config set --installation)
  are tied to the installation.

  Args:
    tar_location: string, where to download the SDK from. If left as None, the
      latest release tar will be used.
    additional_components: [string], a list of additional components to be
      installed with the SDK.
    root_directory: string, where to download and install the SDK to. If left as
      None, a temporary folder will be created for this purpose.

  Raises:
    error.InitError: If the SDK cannot be downloaded or installed.
  """
  if _IsOnWindows():
    raise error.InitError('This driver is not currently Windows compatible.')

  # TODO(magimaster): Make sure this is usable with multiple processes.
  if constants.DRIVER_LOCATION_ENV in os.environ:
    raise error.InitError('Driver is already initialized.')

  if tar_location is None:
    tar_location = constants.RELEASE_TAR
  if root_directory is None:
    root_directory = tempfile.mkdtemp()
  elif not os.path.isdir(root_directory):
    os.makedirs(root_directory)
  else:
    os.environ[constants.DRIVER_KEEP_LOCATION_ENV] = 'True'

  # TODO(magimaster): Once some better safeguards are in place, run Destroy if
  # anything in Init fails.
  download_path = _sdk_tar.DownloadTar(tar_location, root_directory)

  snapshot_url = _sdk_tar.UnpackTar(download_path, tar_location, root_directory)
  env = {}
  if snapshot_url:
    env[constants.SNAPSHOT_ENV] = snapshot_url

  if sys.executable:
    env[constants.PYTHON_ENV] = sys.executable
  # TODO(magimaster): Document that environment will override these.
  env.update(copy.deepcopy(os.environ))

  if constants.PYTHON_ENV not in env:
    raise error.InitError('Neither sys.executable nor the {var} '
                          'environment variable are set.'.format(
                              var=constants.PYTHON_ENV))

  sdk_dir = os.path.join(root_directory, constants.SDK_FOLDER)
  command = [
      './install.sh',
      '--disable-installation-options',
      '--bash-completion=false',
      '--path-update=false',
      '--usage-reporting=false',
      '--rc-path={path}/.bashrc'.format(path=root_directory)]
  if additional_components:
    if isinstance(additional_components, types.StringTypes):
      raise error.InitError(
          'additional_components must be an iterable of strings.')
    command.append('--additional-components')
    command.extend(additional_components)

  p = subprocess.Popen(
      command, stdout=subprocess.PIPE,
      stderr=subprocess.PIPE, cwd=sdk_dir, env=env)
  out, err = p.communicate()
  error.HandlePossibleError((out, err, p.returncode),
                            error.InitError, 'SDK installation failed')

  if not os.path.isdir(sdk_dir):
    raise error.InitError(
        'SDK installation failed. SDK directory was not created.')

  # Store this as an environment variable so subprocesses will have access. Set
  # this last so that a failed installation won't permit the creation of SDK
  # objects.
  os.environ[constants.DRIVER_LOCATION_ENV] = root_directory