Skip to content

tests: Extract UpstreamIndex struct #4384

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Dec 31, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 63 additions & 2 deletions src/tests/git.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,69 @@
use anyhow::anyhow;
use git2::Repository;
use std::env;
use std::fs;
use std::path::PathBuf;
use std::sync::Once;
use std::thread;
use url::Url;

pub struct UpstreamIndex {
pub repository: Repository,
}

impl UpstreamIndex {
pub fn new() -> anyhow::Result<Self> {
init();

let thread_local_path = bare();
let repository = Repository::open_bare(thread_local_path)?;
Ok(Self { repository })
}

pub fn url() -> Url {
Url::from_file_path(&bare()).unwrap()
}

/// Obtain a list of crates from the index HEAD
pub fn crates_from_index_head(
&self,
crate_name: &str,
) -> anyhow::Result<Vec<cargo_registry::git::Crate>> {
let repo = &self.repository;

let path = cargo_registry::git::Repository::relative_index_file(crate_name);

let head = repo.head()?;
let tree = head.peel_to_tree()?;
let blob = tree.get_path(&path)?.to_object(repo)?.peel_to_blob()?;

let content = blob.content();

// The index format consists of one JSON object per line
// It is not a JSON array
let lines = std::str::from_utf8(content)?.lines();
let versions = lines.map(serde_json::from_str).collect::<Result<_, _>>()?;

Ok(versions)
}

pub fn create_empty_commit(&self) -> anyhow::Result<()> {
let repo = &self.repository;

let head = repo.head()?;
let target = head
.target()
.ok_or_else(|| anyhow!("Missing target for HEAD"))?;

let sig = repo.signature()?;
let parent = repo.find_commit(target)?;
let tree = repo.find_tree(parent.tree_id())?;

repo.commit(Some("HEAD"), &sig, &sig, "empty commit", &tree, &[&parent])?;

Ok(())
}
}

fn root() -> PathBuf {
env::current_dir()
Expand All @@ -12,11 +73,11 @@ fn root() -> PathBuf {
.join(thread::current().name().unwrap())
}

pub fn bare() -> PathBuf {
fn bare() -> PathBuf {
root().join("bare")
}

pub fn init() {
fn init() {
static INIT: Once = Once::new();
let _ = fs::remove_dir_all(&bare());

Expand Down
9 changes: 1 addition & 8 deletions src/tests/krate/publish.rs
Original file line number Diff line number Diff line change
Expand Up @@ -563,14 +563,7 @@ fn new_krate_git_upload_appends() {
fn new_krate_git_upload_with_conflicts() {
let (app, _, _, token) = TestApp::full().with_token();

let index = app.upstream_repository();
let target = index.head().unwrap().target().unwrap();
let sig = index.signature().unwrap();
let parent = index.find_commit(target).unwrap();
let tree = index.find_tree(parent.tree_id()).unwrap();
index
.commit(Some("HEAD"), &sig, &sig, "empty commit", &tree, &[&parent])
.unwrap();
app.upstream_index().create_empty_commit().unwrap();

let crate_to_publish = PublishBuilder::new("foo_conflicts");
token.enqueue_publish(crate_to_publish).good();
Expand Down
43 changes: 10 additions & 33 deletions src/tests/util/test_app.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use super::{MockAnonymousUser, MockCookieUser, MockTokenUser};
use crate::git::UpstreamIndex;
use crate::record;
use crate::util::{chaosproxy::ChaosProxy, fresh_schema::FreshSchema};
use cargo_registry::config;
Expand All @@ -10,20 +11,18 @@ use cargo_registry::{
};
use std::{rc::Rc, sync::Arc, time::Duration};

use cargo_registry::git::{Repository as WorkerRepository, Repository};
use cargo_registry::git::Repository as WorkerRepository;
use diesel::PgConnection;
use git2::Repository as UpstreamRepository;
use reqwest::{blocking::Client, Proxy};
use std::collections::HashSet;
use swirl::Runner;
use url::Url;

struct TestAppInner {
app: Arc<App>,
// The bomb (if created) needs to be held in scope until the end of the test.
_bomb: Option<record::Bomb>,
middle: conduit_middleware::MiddlewareBuilder,
index: Option<UpstreamRepository>,
index: Option<UpstreamIndex>,
runner: Option<Runner<Environment, DieselPool>>,
db_chaosproxy: Option<Arc<ChaosProxy>>,

Expand Down Expand Up @@ -129,30 +128,15 @@ impl TestApp {
}

/// Obtain a reference to the upstream repository ("the index")
pub fn upstream_repository(&self) -> &UpstreamRepository {
self.0.index.as_ref().unwrap()
pub fn upstream_index(&self) -> &UpstreamIndex {
assert_some!(self.0.index.as_ref())
}

/// Obtain a list of crates from the index HEAD
pub fn crates_from_index_head(&self, crate_name: &str) -> Vec<cargo_registry::git::Crate> {
let path = Repository::relative_index_file(crate_name);
let index = self.upstream_repository();
let tree = index.head().unwrap().peel_to_tree().unwrap();
let blob = tree
.get_path(&path)
self.upstream_index()
.crates_from_index_head(crate_name)
.unwrap()
.to_object(index)
.unwrap()
.peel_to_blob()
.unwrap();
let content = blob.content();

// The index format consists of one JSON object per line
// It is not a JSON array
let lines = std::str::from_utf8(content).unwrap().lines();
lines
.map(|line| serde_json::from_str(line).unwrap())
.collect()
}

pub fn run_pending_background_jobs(&self) {
Expand Down Expand Up @@ -186,15 +170,13 @@ pub struct TestAppBuilder {
config: config::Server,
proxy: Option<String>,
bomb: Option<record::Bomb>,
index: Option<UpstreamRepository>,
index: Option<UpstreamIndex>,
build_job_runner: bool,
}

impl TestAppBuilder {
/// Create a `TestApp` with an empty database
pub fn empty(mut self) -> (TestApp, MockAnonymousUser) {
use crate::git;

// Run each test inside a fresh database schema, deleted at the end of the test,
// The schema will be cleared up once the app is dropped.
let (db_chaosproxy, fresh_schema) = if !self.config.use_test_database_pool {
Expand All @@ -211,7 +193,7 @@ impl TestAppBuilder {

let runner = if self.build_job_runner {
let repository_config = RepositoryConfig {
index_location: Url::from_file_path(&git::bare()).unwrap(),
index_location: UpstreamIndex::url(),
credentials: Credentials::Missing,
};
let index = WorkerRepository::open(&repository_config).expect("Could not clone index");
Expand Down Expand Up @@ -286,12 +268,7 @@ impl TestAppBuilder {
}

pub fn with_git_index(mut self) -> Self {
use crate::git;

git::init();

let thread_local_path = git::bare();
self.index = Some(UpstreamRepository::open_bare(thread_local_path).unwrap());
self.index = Some(UpstreamIndex::new().unwrap());
self
}

Expand Down