Skip to content

Commit

Permalink
the first simple test to validate we can connect.
Browse files Browse the repository at this point in the history
We decided to just write separate, simplified tests for the basics,
making async support somewhat of a second class citizen, but it's a
valid first step. With the right code layout, one should be able
to reuse all the blocking code where it matters.

This may also make us push code down into `git-protocol`, where
it probably should be anyway. Let's see if this is feasible.
  • Loading branch information
Byron committed Nov 13, 2022
1 parent 52f4095 commit 2bf860a
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 47 deletions.
1 change: 0 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion git-repository/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ is_ci = "1.1.1"
anyhow = "1"
walkdir = "2.3.2"
serial_test = "0.9.0"
maybe-async = "0.2.6"
async-std = { version = "1.12.0", features = ["attributes"] }

[package.metadata.docs.rs]
Expand Down
43 changes: 29 additions & 14 deletions git-repository/tests/remote/connect.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#[cfg(any(feature = "blocking-network-client", feature = "async-network-client-async-std"))]
mod blocking_or_async_io {
#[cfg(feature = "blocking-network-client")]
mod blocking_io {
mod protocol_allow {
use git_features::progress;
use git_repository as git;
Expand All @@ -8,16 +8,13 @@ mod blocking_or_async_io {

use crate::remote;

#[maybe_async::test(
feature = "blocking-network-client",
async(feature = "async-network-client-async-std", async_std::test)
)]
async fn deny() {
#[test]
fn deny() {
for name in ["protocol_denied", "protocol_file_denied"] {
let repo = remote::repo(name);
let remote = repo.find_remote("origin").unwrap();
assert!(matches!(
remote.connect(Fetch, progress::Discard).await.err(),
remote.connect(Fetch, progress::Discard).err(),
Some(git::remote::connect::Error::ProtocolDenied {
url: _,
scheme: git::url::Scheme::File
Expand All @@ -26,12 +23,9 @@ mod blocking_or_async_io {
}
}

#[maybe_async::test(
feature = "blocking-network-client",
async(feature = "async-network-client-async-std", async_std::test)
)]
#[test]
#[serial]
async fn user() -> crate::Result {
fn user() -> crate::Result {
for (env_value, should_allow) in [(None, true), (Some("0"), false), (Some("1"), true)] {
let _env = env_value.map(|value| git_testtools::Env::new().set("GIT_PROTOCOL_FROM_USER", value));
let repo = git::open_opts(
Expand All @@ -46,7 +40,7 @@ mod blocking_or_async_io {
)?;
let remote = repo.find_remote("origin")?;
assert_eq!(
remote.connect(Fetch, progress::Discard).await.is_ok(),
remote.connect(Fetch, progress::Discard).is_ok(),
should_allow,
"Value = {:?}",
env_value
Expand All @@ -56,3 +50,24 @@ mod blocking_or_async_io {
}
}
}

#[cfg(feature = "async-network-client-async-std")]
mod async_io_via_async_std {
use git_features::progress;
use git_repository::remote::Direction::Fetch;

use crate::remote;
use crate::remote::into_daemon_remote;

#[async_std::test]
async fn connect_only() -> crate::Result {
let repo = remote::repo("protocol_file_user");
let daemon = git_testtools::spawn_git_daemon(repo.git_dir())?;
let remote = into_daemon_remote(repo.find_remote("origin")?, &daemon.url, None);
remote
.connect(Fetch, progress::Discard)
.await
.expect("connection succeeds");
Ok(())
}
}
45 changes: 14 additions & 31 deletions git-repository/tests/remote/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,44 +12,27 @@ pub(crate) fn repo(name: &str) -> git::Repository {
git::open_opts(repo_path(name), git::open::Options::isolated()).unwrap()
}

#[cfg(any(feature = "blocking-network-client", feature = "async-network-client-async-std"))]
#[cfg_attr(not(feature = "async-network-client-async-std"), allow(unused_variables))]
pub(crate) fn spawn_daemon_if_async(name: &str) -> std::io::Result<Option<git_testtools::GitDaemon>> {
#[cfg(not(feature = "async-network-client-async-std"))]
{
Ok(None)
}
#[cfg(feature = "async-network-client-async-std")]
{
git_testtools::spawn_git_daemon(repo_path(name)).map(Some)
}
}

/// Turn `remote` into a remote that interacts with the git daemon at `daemon_url`, and `repo_path`
/// can be a specific repo, or it can be empty if the repo is hosted at the root.
#[cfg(any(feature = "blocking-network-client", feature = "async-network-client-async-std"))]
#[cfg_attr(not(feature = "async-network-client-async-std"), allow(unused_variables))]
#[allow(dead_code)] // TODO: remove this when it's used
pub(crate) fn into_daemon_remote_if_async<'repo>(
#[cfg(feature = "async-network-client-async-std")]
pub(crate) fn into_daemon_remote<'repo, 'a>(
remote: git::Remote<'repo>,
daemon_url: &str,
repo_path: &str,
) -> crate::Result<git::Remote<'repo>> {
#[cfg(not(feature = "async-network-client-async-std"))]
{
Ok(remote)
}
#[cfg(feature = "async-network-client-async-std")]
{
let mut new_remote = remote.repo().remote_at(format!("{}/{}", daemon_url, repo_path))?;
for direction in [git::remote::Direction::Fetch, git::remote::Direction::Push] {
new_remote.replace_refspecs(
repo_path: impl Into<Option<&'a str>>,
) -> git::Remote<'repo> {
let mut new_remote = remote
.repo()
.remote_at(format!("{}/{}", daemon_url, repo_path.into().unwrap_or_default()))
.expect("valid url to create remote at");
for direction in [git::remote::Direction::Fetch, git::remote::Direction::Push] {
new_remote
.replace_refspecs(
remote.refspecs(direction).iter().map(|s| s.to_ref().to_bstring()),
direction,
)?;
}
Ok(new_remote)
)
.expect("input refspecs valid");
}
new_remote
}

pub(crate) fn cow_str(s: &str) -> Cow<str> {
Expand Down

0 comments on commit 2bf860a

Please sign in to comment.