mirror of
https://github.com/facebook/sapling.git
synced 2024-10-11 01:07:15 +03:00
e988a88be9
Summary: Context: https://fb.workplace.com/groups/rust.language/permalink/3338940432821215/ This codemod replaces *all* dependencies on `//common/rust/renamed:futures-preview` with `fbsource//third-party/rust:futures-preview` and their uses in Rust code from `futures_preview::` to `futures::`. This does not introduce any collisions with `futures::` meaning 0.1 futures because D20168958 previously renamed all of those to `futures_old::` in crates that depend on *both* 0.1 and 0.3 futures. Codemod performed by: ``` rg \ --files-with-matches \ --type-add buck:TARGETS \ --type buck \ --glob '!/experimental' \ --regexp '(_|\b)rust(_|\b)' \ | sed 's,TARGETS$,:,' \ | xargs \ -x \ buck query "labels(srcs, rdeps(%Ss, //common/rust/renamed:futures-preview, 1))" \ | xargs sed -i 's,\bfutures_preview::,futures::,' rg \ --files-with-matches \ --type-add buck:TARGETS \ --type buck \ --glob '!/experimental' \ --regexp '(_|\b)rust(_|\b)' \ | xargs sed -i 's,//common/rust/renamed:futures-preview,fbsource//third-party/rust:futures-preview,' ``` Reviewed By: k21 Differential Revision: D20213432 fbshipit-source-id: 07ee643d350c5817cda1f43684d55084f8ac68a6
254 lines
7.2 KiB
Rust
254 lines
7.2 KiB
Rust
/*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This software may be used and distributed according to the terms of the
|
|
* GNU General Public License version 2.
|
|
*/
|
|
|
|
use anyhow::Error;
|
|
use async_trait::async_trait;
|
|
use blobstore::Loadable;
|
|
use bookmarks::BookmarkTransactionError;
|
|
use context::CoreContext;
|
|
use fbinit::FacebookInit;
|
|
use futures::{compat::Future01CompatExt, future::try_join_all};
|
|
use maplit::hashset;
|
|
use mercurial_types::globalrev::{Globalrev, START_COMMIT_GLOBALREV};
|
|
use mononoke_types::{BonsaiChangesetMut, ChangesetId, RepositoryId};
|
|
use pushrebase::{
|
|
do_pushrebase_bonsai, OntoBookmarkParams, PushrebaseCommitHook, PushrebaseHook,
|
|
PushrebaseTransactionHook, RebasedChangesets,
|
|
};
|
|
use rand::Rng;
|
|
use sql::rusqlite::Connection as SqliteConnection;
|
|
use sql::Transaction;
|
|
use std::time::Duration;
|
|
use tests_utils::{bookmark, resolve_cs_id, CreateCommitContext};
|
|
|
|
use crate::GlobalrevPushrebaseHook;
|
|
|
|
#[fbinit::test]
|
|
fn pushrebase_assigns_globalrevs(fb: FacebookInit) -> Result<(), Error> {
|
|
let mut runtime = tokio_compat::runtime::Runtime::new()?;
|
|
runtime.block_on_std(pushrebase_assigns_globalrevs_impl(fb))
|
|
}
|
|
|
|
async fn pushrebase_assigns_globalrevs_impl(fb: FacebookInit) -> Result<(), Error> {
|
|
let ctx = CoreContext::test_mock(fb);
|
|
let (repo, _con) = blobrepo_factory::new_memblob_with_sqlite_connection_with_id(
|
|
SqliteConnection::open_in_memory()?,
|
|
RepositoryId::new(1),
|
|
)?;
|
|
let mapping = repo.bonsai_globalrev_mapping().clone();
|
|
|
|
let root = CreateCommitContext::new_root(&ctx, &repo).commit().await?;
|
|
|
|
let cs1 = CreateCommitContext::new(&ctx, &repo, vec![root])
|
|
.commit()
|
|
.await?;
|
|
|
|
let cs2 = CreateCommitContext::new(&ctx, &repo, vec![root])
|
|
.commit()
|
|
.await?
|
|
.load(ctx.clone(), repo.blobstore())
|
|
.compat()
|
|
.await?;
|
|
|
|
let book = bookmark(&ctx, &repo, "master").set_to(cs1).await?;
|
|
|
|
let hooks = [GlobalrevPushrebaseHook::new(mapping, repo.get_repoid())];
|
|
let onto = OntoBookmarkParams::new(book);
|
|
|
|
let rebased = do_pushrebase_bonsai(
|
|
&ctx,
|
|
&repo,
|
|
&Default::default(),
|
|
&onto,
|
|
&hashset![cs2.clone()],
|
|
&None,
|
|
&hooks,
|
|
)
|
|
.await?
|
|
.rebased_changesets;
|
|
|
|
let cs2_rebased = rebased
|
|
.iter()
|
|
.find(|e| e.id_old == cs2.get_changeset_id())
|
|
.ok_or(Error::msg("missing cs2"))?
|
|
.id_new
|
|
.load(ctx.clone(), repo.blobstore())
|
|
.compat()
|
|
.await?;
|
|
|
|
let cs3 = CreateCommitContext::new(&ctx, &repo, vec![root])
|
|
.commit()
|
|
.await?
|
|
.load(ctx.clone(), repo.blobstore())
|
|
.compat()
|
|
.await?;
|
|
|
|
let cs4 = CreateCommitContext::new(&ctx, &repo, vec![cs3.get_changeset_id()])
|
|
.commit()
|
|
.await?
|
|
.load(ctx.clone(), repo.blobstore())
|
|
.compat()
|
|
.await?;
|
|
|
|
let rebased = do_pushrebase_bonsai(
|
|
&ctx,
|
|
&repo,
|
|
&Default::default(),
|
|
&onto,
|
|
&hashset![cs3.clone(), cs4.clone()],
|
|
&None,
|
|
&hooks,
|
|
)
|
|
.await?
|
|
.rebased_changesets;
|
|
|
|
let cs3_rebased = rebased
|
|
.iter()
|
|
.find(|e| e.id_old == cs3.get_changeset_id())
|
|
.ok_or(Error::msg("missing cs3"))?
|
|
.id_new
|
|
.load(ctx.clone(), repo.blobstore())
|
|
.compat()
|
|
.await?;
|
|
|
|
let cs4_rebased = rebased
|
|
.iter()
|
|
.find(|e| e.id_old == cs4.get_changeset_id())
|
|
.ok_or(Error::msg("missing cs4"))?
|
|
.id_new
|
|
.load(ctx.clone(), repo.blobstore())
|
|
.compat()
|
|
.await?;
|
|
|
|
assert_eq!(
|
|
Globalrev::new(START_COMMIT_GLOBALREV),
|
|
Globalrev::from_bcs(&cs2_rebased)?
|
|
);
|
|
assert_eq!(
|
|
Globalrev::new(START_COMMIT_GLOBALREV + 1),
|
|
Globalrev::from_bcs(&cs3_rebased)?
|
|
);
|
|
assert_eq!(
|
|
Globalrev::new(START_COMMIT_GLOBALREV + 2),
|
|
Globalrev::from_bcs(&cs4_rebased)?
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
#[fbinit::test]
|
|
fn test_pushrebase_race_assigns_monotonic_globalrevs(fb: FacebookInit) -> Result<(), Error> {
|
|
let mut runtime = tokio_compat::runtime::Runtime::new()?;
|
|
runtime.block_on_std(pushrebase_race_assigns_monotonic_globalrevs(fb))
|
|
}
|
|
|
|
async fn pushrebase_race_assigns_monotonic_globalrevs(fb: FacebookInit) -> Result<(), Error> {
|
|
#[derive(Copy, Clone)]
|
|
struct SleepHook;
|
|
|
|
#[async_trait]
|
|
impl PushrebaseHook for SleepHook {
|
|
async fn prepushrebase(&self) -> Result<Box<dyn PushrebaseCommitHook>, Error> {
|
|
let us = rand::thread_rng().gen_range(0, 100);
|
|
tokio::time::delay_for(Duration::from_micros(us)).await;
|
|
Ok(Box::new(*self) as Box<dyn PushrebaseCommitHook>)
|
|
}
|
|
}
|
|
|
|
impl PushrebaseCommitHook for SleepHook {
|
|
fn post_rebase_changeset(
|
|
&mut self,
|
|
_bcs_old: ChangesetId,
|
|
_bcs_new: &mut BonsaiChangesetMut,
|
|
) -> Result<(), Error> {
|
|
Ok(())
|
|
}
|
|
|
|
fn into_transaction_hook(
|
|
self: Box<Self>,
|
|
_changesets: &RebasedChangesets,
|
|
) -> Result<Box<dyn PushrebaseTransactionHook>, Error> {
|
|
Ok(Box::new(*self) as Box<dyn PushrebaseTransactionHook>)
|
|
}
|
|
}
|
|
|
|
#[async_trait]
|
|
impl PushrebaseTransactionHook for SleepHook {
|
|
async fn populate_transaction(
|
|
&self,
|
|
_ctx: &CoreContext,
|
|
txn: Transaction,
|
|
) -> Result<Transaction, BookmarkTransactionError> {
|
|
Ok(txn)
|
|
}
|
|
}
|
|
|
|
let ctx = CoreContext::test_mock(fb);
|
|
let (repo, _con) = blobrepo_factory::new_memblob_with_sqlite_connection_with_id(
|
|
SqliteConnection::open_in_memory()?,
|
|
RepositoryId::new(1),
|
|
)?;
|
|
let mapping = repo.bonsai_globalrev_mapping().clone();
|
|
|
|
let root = CreateCommitContext::new_root(&ctx, &repo).commit().await?;
|
|
let book = bookmark(&ctx, &repo, "master").set_to(root).await?;
|
|
|
|
let onto = OntoBookmarkParams::new(book);
|
|
|
|
let hooks = [
|
|
GlobalrevPushrebaseHook::new(mapping, repo.get_repoid()),
|
|
Box::new(SleepHook) as Box<dyn PushrebaseHook>,
|
|
];
|
|
|
|
let n: u64 = 10;
|
|
let mut futs = vec![];
|
|
for _ in 0..n {
|
|
let bcs = CreateCommitContext::new(&ctx, &repo, vec![root])
|
|
.commit()
|
|
.await?
|
|
.load(ctx.clone(), repo.blobstore())
|
|
.compat()
|
|
.await?;
|
|
|
|
let fut = async {
|
|
let params = Default::default();
|
|
let bcss = hashset![bcs];
|
|
do_pushrebase_bonsai(&ctx, &repo, ¶ms, &onto, &bcss, &None, &hooks).await
|
|
};
|
|
|
|
futs.push(fut);
|
|
}
|
|
|
|
let results = try_join_all(futs).await?;
|
|
|
|
// Check that we had some retries
|
|
assert!(results.iter().fold(0, |sum, e| sum + e.retry_num) > 0);
|
|
|
|
let mut next_cs_id = resolve_cs_id(&ctx, &repo, "master").await?;
|
|
let mut next_globalrev = START_COMMIT_GLOBALREV + n - 1;
|
|
|
|
// Check history backwards and assert that globalrevs are going down
|
|
|
|
loop {
|
|
if next_cs_id == root {
|
|
break;
|
|
}
|
|
|
|
let cs = next_cs_id
|
|
.load(ctx.clone(), repo.blobstore())
|
|
.compat()
|
|
.await?;
|
|
|
|
assert_eq!(Globalrev::new(next_globalrev), Globalrev::from_bcs(&cs)?);
|
|
|
|
next_cs_id = cs.parents().next().ok_or(Error::msg("no parent found"))?;
|
|
next_globalrev -= 1;
|
|
}
|
|
|
|
Ok(())
|
|
}
|