Exemplo n.º 1
0
def _upload_delta(
    store_client,
    *,
    snap_name: str,
    snap_filename: str,
    source_snap: str,
    built_at: str,
    channels: Optional[List[str]] = None,
) -> Dict[str, Any]:
    delta_format = "xdelta3"
    logger.debug("Found cached source snap {}.".format(source_snap))
    target_snap = os.path.join(os.getcwd(), snap_filename)

    try:
        xdelta_generator = deltas.XDelta3Generator(source_path=source_snap,
                                                   target_path=target_snap)
        delta_filename = xdelta_generator.make_delta()
    except (DeltaGenerationError, DeltaGenerationTooBigError,
            ToolMissingError) as e:
        raise storeapi.errors.StoreDeltaApplicationError(str(e))

    snap_hashes = {
        "source_hash": calculate_sha3_384(source_snap),
        "target_hash": calculate_sha3_384(target_snap),
        "delta_hash": calculate_sha3_384(delta_filename),
    }

    try:
        logger.debug("Uploading delta {!r}.".format(delta_filename))
        delta_tracker = store_client.upload(
            snap_name=snap_name,
            snap_filename=delta_filename,
            built_at=built_at,
            channels=channels,
            delta_format=delta_format,
            source_hash=snap_hashes["source_hash"],
            target_hash=snap_hashes["target_hash"],
            delta_hash=snap_hashes["delta_hash"],
        )
        result = delta_tracker.track()
        delta_tracker.raise_for_code()
    except storeapi.errors.StoreReviewError as e:
        if e.code == "processing_upload_delta_error":
            raise storeapi.errors.StoreDeltaApplicationError(str(e))
        else:
            raise
    except storeapi.errors.StoreServerError as e:
        raise storeapi.errors.StoreUploadError(snap_name, e.response)
    finally:
        if os.path.isfile(delta_filename):
            try:
                os.remove(delta_filename)
            except OSError:
                logger.warning(
                    "Unable to remove delta {}.".format(delta_filename))
    return result
Exemplo n.º 2
0
    def test_xdelta3(self):
        self.generate_snap_pair()
        base_delta = deltas.XDelta3Generator(source_path=self.source_file,
                                             target_path=self.target_file)
        path = base_delta.make_delta(is_for_test=True)

        self.assertThat(path, m.FileExists())
        expect_path = "{}.{}".format(base_delta.target_path,
                                     base_delta.delta_file_extname)
        self.assertThat(path, m.Equals(expect_path))
Exemplo n.º 3
0
    def test_xdelta3_logs(self):
        self.generate_snap_pair()
        base_delta = deltas.XDelta3Generator(source_path=self.source_file,
                                             target_path=self.target_file)
        base_delta.make_delta(is_for_test=True)

        self.assertThat(
            self.fake_logger.output,
            m.Contains('Generating xdelta3 delta for {}'.format(
                os.path.basename(base_delta.target_path))))
        self.assertThat(self.fake_logger.output,
                        m.Contains('xdelta3 delta diff generation'))
Exemplo n.º 4
0
    def test_raises_DeltaToolError_when_xdelta3_not_installed(self):
        self.patch(file_utils, 'executable_exists', lambda a: False)
        self.patch(shutil, 'which', lambda a: None)

        self.assertThat(
            lambda: deltas.XDelta3Generator(
                source_path=self.source_file, target_path=self.target_file),
            m.raises(deltas.errors.DeltaToolError)
        )
        self.assertRaises(deltas.errors.DeltaToolError,
                          deltas.XDelta3Generator,
                          source_path=self.source_file,
                          target_path=self.target_file)
Exemplo n.º 5
0
    def test_raises_DeltaToolError_when_xdelta3_not_installed(self):
        self.patch(file_utils, 'executable_exists', lambda a: False)
        self.patch(shutil, 'which', lambda a: None)

        self.assertThat(
            lambda: deltas.XDelta3Generator(source_path=self.source_file,
                                            target_path=self.target_file),
            m.raises(deltas.errors.DeltaToolError))
        exception = self.assertRaises(deltas.errors.DeltaToolError,
                                      deltas.XDelta3Generator,
                                      source_path=self.source_file,
                                      target_path=self.target_file)
        expected = 'delta_tool_path must be set in subclass!'
        self.assertEqual(str(exception), expected)
Exemplo n.º 6
0
def _push_delta(snap_name, snap_filename, source_snap, built_at):
    store = storeapi.StoreClient()
    delta_format = "xdelta3"
    logger.debug("Found cached source snap {}.".format(source_snap))
    target_snap = os.path.join(os.getcwd(), snap_filename)

    try:
        xdelta_generator = deltas.XDelta3Generator(source_path=source_snap,
                                                   target_path=target_snap)
        delta_filename = xdelta_generator.make_delta()
    except (DeltaGenerationError, DeltaGenerationTooBigError,
            DeltaToolError) as e:
        raise storeapi.errors.StoreDeltaApplicationError(str(e))

    snap_hashes = {
        "source_hash": calculate_sha3_384(source_snap),
        "target_hash": calculate_sha3_384(target_snap),
        "delta_hash": calculate_sha3_384(delta_filename),
    }

    try:
        logger.debug("Pushing delta {!r}.".format(delta_filename))
        with _requires_login():
            delta_tracker = store.upload(
                snap_name,
                delta_filename,
                delta_format=delta_format,
                source_hash=snap_hashes["source_hash"],
                target_hash=snap_hashes["target_hash"],
                delta_hash=snap_hashes["delta_hash"],
                built_at=built_at,
            )
        result = delta_tracker.track()
        delta_tracker.raise_for_code()
    except storeapi.errors.StoreReviewError as e:
        if e.code == "processing_upload_delta_error":
            raise storeapi.errors.StoreDeltaApplicationError(str(e))
        else:
            raise
    except storeapi.errors.StoreServerError as e:
        raise storeapi.errors.StorePushError(snap_name, e.response)
    finally:
        if os.path.isfile(delta_filename):
            try:
                os.remove(delta_filename)
            except OSError:
                logger.warning(
                    "Unable to remove delta {}.".format(delta_filename))
    return result
Exemplo n.º 7
0
    def test_xdelta3_return_invalid_code(self, mock_subproc_popen):
        # mock the subprocess.Popen with a unexpected returncode
        process_mock = mock.Mock()
        attrs = {"returncode": -1}
        process_mock.configure_mock(**attrs)
        mock_subproc_popen.return_value = process_mock

        self.generate_snap_pair()
        base_delta = deltas.XDelta3Generator(source_path=self.source_file,
                                             target_path=self.target_file)

        self.assertThat(
            lambda: base_delta.make_delta(is_for_test=True),
            m.raises(deltas.errors.DeltaGenerationError),
        )
Exemplo n.º 8
0
def _push_delta(snap_name, snap_filename, source_snap):
    store = storeapi.StoreClient()
    delta_format = 'xdelta3'
    logger.info('Found cached source snap {}.'.format(source_snap))
    target_snap = os.path.join(os.getcwd(), snap_filename)

    try:
        xdelta_generator = deltas.XDelta3Generator(source_path=source_snap,
                                                   target_path=target_snap)
        delta_filename = xdelta_generator.make_delta()
    except (DeltaGenerationError, DeltaGenerationTooBigError,
            DeltaToolError) as e:
        raise StoreDeltaApplicationError(str(e))

    snap_hashes = {
        'source_hash': calculate_sha3_384(source_snap),
        'target_hash': calculate_sha3_384(target_snap),
        'delta_hash': calculate_sha3_384(delta_filename)
    }

    try:
        logger.info('Pushing delta {}.'.format(delta_filename))
        with _requires_login():
            delta_tracker = store.upload(
                snap_name,
                delta_filename,
                delta_format=delta_format,
                source_hash=snap_hashes['source_hash'],
                target_hash=snap_hashes['target_hash'],
                delta_hash=snap_hashes['delta_hash'])
        result = delta_tracker.track()
        delta_tracker.raise_for_code()
    except storeapi.errors.StoreReviewError as e:
        if e.code == 'processing_upload_delta_error':
            raise StoreDeltaApplicationError
        else:
            raise
    finally:
        if os.path.isfile(delta_filename):
            try:
                os.remove(delta_filename)
            except OSError:
                logger.warning(
                    'Unable to remove delta {}.'.format(delta_filename))
    return result
Exemplo n.º 9
0
    def test_xdelta3_with_progress_indicator(self):
        self.generate_snap_pair()
        base_delta = deltas.XDelta3Generator(source_path=self.source_file,
                                             target_path=self.target_file)

        message = "creating delta file from {!r}...".format(self.source_file)
        maxval = 10
        progress_indicator = ProgressBar(widgets=[message,
                                                  AnimatedMarker()],
                                         maxval=maxval)
        progress_indicator.start()

        path = base_delta.make_delta(progress_indicator=progress_indicator,
                                     is_for_test=True)
        progress_indicator.finish()

        self.assertThat(path, m.FileExists())
        expect_path = "{}.{}".format(base_delta.target_path,
                                     base_delta.delta_file_extname)
        self.assertThat(path, m.Equals(expect_path))
Exemplo n.º 10
0
    def test_xdelta3_with_custom_output_dir(self):
        self.generate_snap_pair()
        base_delta = deltas.XDelta3Generator(source_path=self.source_file,
                                             target_path=self.target_file)
        delta_filename = "{}.{}".format(
            os.path.split(base_delta.target_path)[1],
            base_delta.delta_file_extname)

        existed_output_dir = self.useFixture(fixtures.TempDir()).path
        path = base_delta.make_delta(existed_output_dir, is_for_test=True)

        expect_path = os.path.join(existed_output_dir, delta_filename)
        self.assertThat(path, m.FileExists())
        self.assertThat(path, m.Equals(expect_path))

        none_existed_output_dir = (self.useFixture(fixtures.TempDir()).path +
                                   "/whatever/")
        path = base_delta.make_delta(none_existed_output_dir, is_for_test=True)

        expect_path = os.path.join(none_existed_output_dir, delta_filename)
        self.assertThat(path, m.FileExists())
        self.assertThat(path, m.Equals(expect_path))