Compare commits

...

4 Commits

Author SHA1 Message Date
Valentin Brandl
bb5a3ecf4e
Test new caching mechanism
All checks were successful
continuous-integration/drone/push Build is passing
2019-09-16 22:42:41 +02:00
Valentin Brandl
a85ff2a54b
Add more tests
All checks were successful
continuous-integration/drone/push Build is passing
2019-09-10 23:13:50 +02:00
Valentin Brandl
97377a2442
Implement a few tests 2019-09-10 22:45:32 +02:00
Valentin Brandl
0ea5f38f83
Fix clippy lints 2019-09-10 22:45:10 +02:00
7 changed files with 387 additions and 11 deletions

View File

@ -26,17 +26,19 @@ COPY --chown=rust ./time-cache/Cargo.toml ./time-cache/Cargo.toml
WORKDIR /home/rust/src/yagcdn
# build to cache dependencies
RUN cargo build --release
# RUN cargo build --release
# delete build cache to prevent caching issues later on
RUN rm -r ./target/x86_64-unknown-linux-musl/release/.fingerprint/yagcdn*
RUN rm -r ./target/x86_64-unknown-linux-musl/release/.fingerprint/time-cache-*
# RUN rm -r ./target/x86_64-unknown-linux-musl/release/.fingerprint/yagcdn*
# RUN rm -r ./target/x86_64-unknown-linux-musl/release/.fingerprint/time-cache-*
COPY ./backend/static ./static
COPY ./backend/src ./src
COPY ./time-cache/src ../time-cache/src
# build source code
RUN cargo build --release
RUN --mount=type=cache,target=../../usr/local/cargo/registry \
--mount=type=cache,target=target \
cargo build --release
# create /etc/password for rootless scratch container
FROM alpine:latest as user_builder

View File

@ -16,6 +16,9 @@ mod error;
mod service;
mod statics;
#[cfg(test)]
mod test;
use crate::{
cdn::Cloudflare,
data::{FilePath, State},

View File

@ -9,28 +9,25 @@ lazy_static! {
pub(crate) static ref USER_AGENT: String = format!("yagcdn/{}", VERSION);
pub(crate) static ref OPT: Opt = Opt::from_args();
pub(crate) static ref GITHUB_AUTH_QUERY: Cow<'static, str> =
Github::auth_query().unwrap_or_default().into();
Github::auth_query().unwrap_or_default();
pub(crate) static ref CF_ZONE_IDENT: Cow<'static, str> = OPT
.cf_zone
.as_ref()
.map(Cow::from)
.or_else(|| load_env_var("CF_ZONE_IDENT"))
.expect("Cloudflare zone identifier not set")
.into();
.expect("Cloudflare zone identifier not set");
pub(crate) static ref CF_AUTH_KEY: Cow<'static, str> = OPT
.cf_auth_key
.as_ref()
.map(Cow::from)
.or_else(|| load_env_var("CF_AUTH_KEY"))
.expect("Cloudflare auth key not set")
.into();
.expect("Cloudflare auth key not set");
pub(crate) static ref CF_AUTH_USER: Cow<'static, str> = OPT
.cf_auth_user
.as_ref()
.map(Cow::from)
.or_else(|| load_env_var("CF_AUTH_USER"))
.expect("Cloudflare auth user not set")
.into();
.expect("Cloudflare auth user not set");
pub(crate) static ref HOSTNAME: Cow<'static, str> = OPT
.hostname
.as_ref()

View File

@ -0,0 +1,125 @@
use crate::{
data::{Key, Service, State},
proxy_file, purge_local_cache, redirect,
service::Bitbucket,
REDIRECT_AGE,
};
use actix_web::{dev::Service as _, http::StatusCode, middleware, test, web, App};
use awc::Client;
use std::sync::{Arc, RwLock};
use time_cache::{Cache, CacheResult};
#[test]
fn requesting_branch_redirects() {
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
let mut app = test::init_service(
App::new()
.data(Client::new())
.data(state)
.wrap(middleware::NormalizePath)
.route(
"/bitbucket/{user}/{repo}/{commit}/{file:.*}",
web::get().to_async(redirect::<Bitbucket>),
),
);
let req =
test::TestRequest::with_uri("/bitbucket/vbrandl/vbrandl.net/master/README.md").to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::SEE_OTHER, resp.status());
}
#[test]
fn invalid_file_404() {
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
let mut app = test::init_service(
App::new()
.data(Client::new())
.data(state)
.wrap(middleware::NormalizePath)
.route(
"/bitbucket/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
web::get().to_async(proxy_file::<Bitbucket>),
),
);
let req = test::TestRequest::with_uri(
"/bitbucket/vbrandl/vbrandl.net/369c392927a6d75f16c5dc38e2577276b94676bd/README.md.invalid",
)
.to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::NOT_FOUND, resp.status());
}
#[test]
fn valid_file_200() {
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
let mut app = test::init_service(
App::new()
.data(Client::new())
.data(state)
.wrap(middleware::NormalizePath)
.route(
"/bitbucket/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
web::get().to_async(proxy_file::<Bitbucket>),
),
);
let req = test::TestRequest::with_uri(
"/bitbucket/vbrandl/vbrandl.net/369c392927a6d75f16c5dc38e2577276b94676bd/README.md",
)
.to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::OK, resp.status());
}
#[test]
fn redirect_cache() {
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
let mut app = test::init_service(
App::new()
.data(Client::new())
.data(Arc::clone(&state))
.wrap(middleware::NormalizePath)
.route(
"/bitbucket/{user}/{repo}/{commit}/{file:.*}",
web::get().to_async(redirect::<Bitbucket>),
)
.route(
"/bitbucket/{user}/{repo}/{commit}/{file:.*}",
web::delete().to_async(purge_local_cache::<Bitbucket>),
),
);
let req =
test::TestRequest::with_uri("/bitbucket/vbrandl/vbrandl.net/master/README.md").to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::SEE_OTHER, resp.status());
let key = Key::new(
Service::Bitbucket,
Arc::new("vbrandl".to_string()),
Arc::new("vbrandl.net".to_string()),
Arc::new("master".to_string()),
);
{
let cache = state.read().unwrap();
let res = cache.get(&key);
assert_ne!(CacheResult::Empty, res);
assert_ne!(CacheResult::Invalid, res);
} // release the lock
let req = test::TestRequest::delete()
.uri("/bitbucket/vbrandl/vbrandl.net/master/README.md")
.to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::OK, resp.status());
{
let cache = state.read().unwrap();
assert_eq!(CacheResult::Empty, cache.get(&key));
} // release the lock
}

123
backend/src/test/github.rs Normal file
View File

@ -0,0 +1,123 @@
use crate::{
data::{Key, Service, State},
proxy_file, purge_local_cache, redirect,
service::Github,
REDIRECT_AGE,
};
use actix_web::{dev::Service as _, http::StatusCode, middleware, test, web, App};
use awc::Client;
use std::sync::{Arc, RwLock};
use time_cache::{Cache, CacheResult};
#[test]
fn requesting_branch_redirects() {
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
let mut app = test::init_service(
App::new()
.data(Client::new())
.data(state)
.wrap(middleware::NormalizePath)
.route(
"/github/{user}/{repo}/{commit}/{file:.*}",
web::get().to_async(redirect::<Github>),
),
);
let req = test::TestRequest::with_uri("/github/vbrandl/yagcdn/master/Cargo.toml").to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::SEE_OTHER, resp.status());
}
#[test]
fn invalid_file_404() {
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
let mut app = test::init_service(
App::new()
.data(Client::new())
.data(state)
.wrap(middleware::NormalizePath)
.route(
"/github/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
web::get().to_async(proxy_file::<Github>),
),
);
let req = test::TestRequest::with_uri(
"/github/vbrandl/yagcdn/f1b35e7c05b952be6de559051d7daad2ecf05369/Cargo.toml.invalid",
)
.to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::NOT_FOUND, resp.status());
}
#[test]
fn valid_file_200() {
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
let mut app = test::init_service(
App::new()
.data(Client::new())
.data(state)
.wrap(middleware::NormalizePath)
.route(
"/github/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
web::get().to_async(proxy_file::<Github>),
),
);
// github
let req = test::TestRequest::with_uri(
"/github/vbrandl/yagcdn/f1b35e7c05b952be6de559051d7daad2ecf05369/backend/Cargo.toml",
)
.to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::OK, resp.status());
}
#[test]
fn redirect_cache() {
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
let mut app = test::init_service(
App::new()
.data(Client::new())
.data(Arc::clone(&state))
.wrap(middleware::NormalizePath)
.route(
"/github/{user}/{repo}/{commit}/{file:.*}",
web::get().to_async(redirect::<Github>),
)
.route(
"/github/{user}/{repo}/{commit}/{file:.*}",
web::delete().to_async(purge_local_cache::<Github>),
),
);
let req = test::TestRequest::with_uri("/github/vbrandl/yagcdn/master/Cargo.toml").to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::SEE_OTHER, resp.status());
let key = Key::new(
Service::GitHub,
Arc::new("vbrandl".to_string()),
Arc::new("yagcdn".to_string()),
Arc::new("master".to_string()),
);
{
let cache = state.read().unwrap();
let res = cache.get(&key);
assert_ne!(CacheResult::Empty, res);
assert_ne!(CacheResult::Invalid, res);
} // release the lock
let req = test::TestRequest::delete()
.uri("/github/vbrandl/yagcdn/master/Cargo.toml")
.to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::OK, resp.status());
{
let cache = state.read().unwrap();
assert_eq!(CacheResult::Empty, cache.get(&key));
} // release the lock
}

123
backend/src/test/gitlab.rs Normal file
View File

@ -0,0 +1,123 @@
use crate::{
data::{Key, Service, State},
proxy_file, purge_local_cache, redirect,
service::GitLab,
REDIRECT_AGE,
};
use actix_web::{dev::Service as _, http::StatusCode, middleware, test, web, App};
use awc::Client;
use std::sync::{Arc, RwLock};
use time_cache::{Cache, CacheResult};
#[test]
fn requesting_branch_redirects() {
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
let mut app = test::init_service(
App::new()
.data(Client::new())
.data(state)
.wrap(middleware::NormalizePath)
.route(
"/gitlab/{user}/{repo}/{commit}/{file:.*}",
web::get().to_async(redirect::<GitLab>),
),
);
let req = test::TestRequest::with_uri("/gitlab/vbrandl/hoc/master/Cargo.toml").to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::SEE_OTHER, resp.status());
}
#[test]
fn invalid_file_404() {
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
let mut app = test::init_service(
App::new()
.data(Client::new())
.data(state)
.wrap(middleware::NormalizePath)
.route(
"/gitlab/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
web::get().to_async(proxy_file::<GitLab>),
),
);
let req = test::TestRequest::with_uri(
"/gitlab/vbrandl/hoc/1223d429db877e46653260b15aa2bbd326bcd495/Cargo.toml.invalid",
)
.to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::NOT_FOUND, resp.status());
}
#[test]
fn valid_file_200() {
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
let mut app = test::init_service(
App::new()
.data(Client::new())
.data(state)
.wrap(middleware::NormalizePath)
.route(
"/gitlab/{user}/{repo}/{commit:[0-9a-fA-F]{40}}/{file:.*}",
web::get().to_async(proxy_file::<GitLab>),
),
);
let req = test::TestRequest::with_uri(
"/gitlab/vbrandl/hoc/1223d429db877e46653260b15aa2bbd326bcd495/Cargo.toml",
)
.to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::OK, resp.status());
}
#[test]
fn redirect_cache() {
let state: State = Arc::new(RwLock::new(Cache::new(REDIRECT_AGE)));
let mut app = test::init_service(
App::new()
.data(Client::new())
.data(Arc::clone(&state))
.wrap(middleware::NormalizePath)
.route(
"/gitlab/{user}/{repo}/{commit}/{file:.*}",
web::get().to_async(redirect::<GitLab>),
)
.route(
"/gitlab/{user}/{repo}/{commit}/{file:.*}",
web::delete().to_async(purge_local_cache::<GitLab>),
),
);
let req = test::TestRequest::with_uri("/gitlab/vbrandl/hoc/master/Cargo.toml").to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::SEE_OTHER, resp.status());
let key = Key::new(
Service::GitLab,
Arc::new("vbrandl".to_string()),
Arc::new("hoc".to_string()),
Arc::new("master".to_string()),
);
{
let cache = state.read().unwrap();
let res = cache.get(&key);
assert_ne!(CacheResult::Empty, res);
assert_ne!(CacheResult::Invalid, res);
} // release the lock
let req = test::TestRequest::delete()
.uri("/gitlab/vbrandl/hoc/master/Cargo.toml")
.to_request();
let resp = test::block_fn(|| app.call(req)).unwrap();
assert_eq!(StatusCode::OK, resp.status());
{
let cache = state.read().unwrap();
assert_eq!(CacheResult::Empty, cache.get(&key));
} // release the lock
}

3
backend/src/test/mod.rs Normal file
View File

@ -0,0 +1,3 @@
mod bitbucket;
mod github;
mod gitlab;