test(tvix/nar-bridge): start testing handlers
We currently only had some integration tests (as part of tvix-boot) testing nar-bridge functionality as a smoketest, but with axum-test we can test individual handlers and peek at the store afterwards, which is much more granular. This adds tests for the nar-specific request handlers. Change-Id: I7f2345df89ac43b9b372ecc66f696e95e2fcad18 Reviewed-on: https://cl.tvl.fyi/c/depot/+/12916 Tested-by: BuildkiteCI Reviewed-by: raitobezarius <tvl@lahfa.xyz> Autosubmit: flokli <flokli@flokli.de>
This commit is contained in:
parent
4f9112f1cd
commit
30b631ea72
5 changed files with 870 additions and 49 deletions
177
tvix/Cargo.lock
generated
177
tvix/Cargo.lock
generated
|
@ -126,6 +126,16 @@ version = "0.7.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
||||
|
||||
[[package]]
|
||||
name = "assert-json-diff"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "2.3.1"
|
||||
|
@ -277,6 +287,12 @@ version = "1.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||
|
||||
[[package]]
|
||||
name = "auto-future"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c1e7e457ea78e524f48639f551fd79703ac3f2237f5ecccdf4708f8a75ad373"
|
||||
|
||||
[[package]]
|
||||
name = "auto_impl"
|
||||
version = "1.2.0"
|
||||
|
@ -305,7 +321,7 @@ dependencies = [
|
|||
"axum-macros",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
|
@ -338,7 +354,7 @@ dependencies = [
|
|||
"async-trait",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"mime",
|
||||
|
@ -361,7 +377,7 @@ dependencies = [
|
|||
"bytes",
|
||||
"futures-util",
|
||||
"headers",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"mime",
|
||||
|
@ -399,6 +415,36 @@ dependencies = [
|
|||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-test"
|
||||
version = "16.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "017cbca2776229a7100ebee44e065fcf5baccea6fc4cb9e5bea8328d83863a03"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"assert-json-diff",
|
||||
"auto-future",
|
||||
"axum",
|
||||
"bytes",
|
||||
"bytesize",
|
||||
"cookie",
|
||||
"http 1.1.0",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"mime",
|
||||
"pretty_assertions",
|
||||
"reserve-port",
|
||||
"rust-multipart-rfc7578_2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"smallvec",
|
||||
"tokio",
|
||||
"tower 0.5.1",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.74"
|
||||
|
@ -438,7 +484,7 @@ version = "0.2.10"
|
|||
source = "git+https://github.com/liufuyang/bigtable_rs?rev=1818355a5373a5bc2c84287e3a4e3807154ac8ef#1818355a5373a5bc2c84287e3a4e3807154ac8ef"
|
||||
dependencies = [
|
||||
"gcp_auth",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"hyper-util",
|
||||
"log",
|
||||
"prost",
|
||||
|
@ -533,6 +579,12 @@ version = "1.8.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da"
|
||||
|
||||
[[package]]
|
||||
name = "bytesize"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3e368af43e418a04d52505cf3dbc23dda4e3407ae2fa99fd0e4f308ce546acc"
|
||||
|
||||
[[package]]
|
||||
name = "bzip2"
|
||||
version = "0.4.4"
|
||||
|
@ -736,6 +788,16 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6"
|
||||
|
||||
[[package]]
|
||||
name = "cookie"
|
||||
version = "0.18.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
|
||||
dependencies = [
|
||||
"time",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
|
@ -1413,7 +1475,7 @@ dependencies = [
|
|||
"bytes",
|
||||
"chrono",
|
||||
"home",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
|
@ -1515,7 +1577,7 @@ dependencies = [
|
|||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"indexmap 2.6.0",
|
||||
"slab",
|
||||
"tokio",
|
||||
|
@ -1565,7 +1627,7 @@ dependencies = [
|
|||
"base64 0.21.7",
|
||||
"bytes",
|
||||
"headers-core",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"httpdate",
|
||||
"mime",
|
||||
"sha1",
|
||||
|
@ -1577,7 +1639,7 @@ version = "0.3.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4"
|
||||
dependencies = [
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1625,6 +1687,17 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "0.2.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.1.0"
|
||||
|
@ -1643,7 +1716,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1654,7 +1727,7 @@ checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
|
|||
dependencies = [
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"http-body",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
@ -1687,7 +1760,7 @@ dependencies = [
|
|||
"futures-channel",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
|
@ -1705,7 +1778,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"rustls",
|
||||
|
@ -1738,7 +1811,7 @@ dependencies = [
|
|||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"pin-project-lite",
|
||||
|
@ -2159,6 +2232,16 @@ version = "0.3.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
||||
|
||||
[[package]]
|
||||
name = "mime_guess"
|
||||
version = "2.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e"
|
||||
dependencies = [
|
||||
"mime",
|
||||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
|
@ -2237,6 +2320,7 @@ dependencies = [
|
|||
"axum",
|
||||
"axum-extra",
|
||||
"axum-range",
|
||||
"axum-test",
|
||||
"bytes",
|
||||
"clap",
|
||||
"data-encoding",
|
||||
|
@ -2252,6 +2336,7 @@ dependencies = [
|
|||
"prost-build",
|
||||
"rstest",
|
||||
"serde",
|
||||
"sha2",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-listener",
|
||||
|
@ -2263,6 +2348,7 @@ dependencies = [
|
|||
"tower-otel-http-metrics",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"tracing-test",
|
||||
"tvix-castore",
|
||||
"tvix-store",
|
||||
"tvix-tracing",
|
||||
|
@ -2591,7 +2677,7 @@ checksum = "10a8a7f5f6ba7c1b286c2fbca0454eaba116f63bbe69ed250b642d36fbb04d80"
|
|||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"opentelemetry",
|
||||
]
|
||||
|
||||
|
@ -2603,7 +2689,7 @@ checksum = "91cf61a1868dacc576bf2b2a1c3e9ab150af7272909e80085c3173384fe11f76"
|
|||
dependencies = [
|
||||
"async-trait",
|
||||
"futures-core",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"opentelemetry",
|
||||
"opentelemetry-proto",
|
||||
"opentelemetry_sdk",
|
||||
|
@ -3303,7 +3389,7 @@ dependencies = [
|
|||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
|
@ -3344,7 +3430,7 @@ source = "git+https://github.com/TrueLayer/reqwest-middleware?rev=8a494c165734e2
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"thiserror",
|
||||
|
@ -3359,7 +3445,7 @@ dependencies = [
|
|||
"anyhow",
|
||||
"async-trait",
|
||||
"getrandom",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"matchit 0.8.4",
|
||||
"opentelemetry",
|
||||
"reqwest",
|
||||
|
@ -3368,6 +3454,16 @@ dependencies = [
|
|||
"tracing-opentelemetry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reserve-port"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9838134a2bfaa8e1f40738fcc972ac799de6e0e06b5157acb95fc2b05a0ea283"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.8"
|
||||
|
@ -3445,6 +3541,22 @@ dependencies = [
|
|||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-multipart-rfc7578_2"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03b748410c0afdef2ebbe3685a6a862e2ee937127cdaae623336a459451c8d57"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"http 0.2.12",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
"rand",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
|
@ -4334,7 +4446,7 @@ dependencies = [
|
|||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"h2",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
|
@ -4441,7 +4553,7 @@ dependencies = [
|
|||
"bitflags 2.6.0",
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"pin-project-lite",
|
||||
|
@ -4466,7 +4578,7 @@ checksum = "ed0ba983713ec0f5d512dc28091fa3c1cb8fa5487de32a1b0bc0cb4159f9f89f"
|
|||
dependencies = [
|
||||
"axum",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"opentelemetry",
|
||||
"pin-project-lite",
|
||||
"tower 0.5.1",
|
||||
|
@ -4582,6 +4694,27 @@ dependencies = [
|
|||
"tracing-log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-test"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "557b891436fe0d5e0e363427fc7f217abf9ccd510d5136549847bdcbcd011d68"
|
||||
dependencies = [
|
||||
"tracing-core",
|
||||
"tracing-subscriber",
|
||||
"tracing-test-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-test-macro"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-tracy"
|
||||
version = "0.11.3"
|
||||
|
@ -4924,7 +5057,7 @@ name = "tvix-tracing"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"axum",
|
||||
"http",
|
||||
"http 1.1.0",
|
||||
"indicatif",
|
||||
"opentelemetry",
|
||||
"opentelemetry-http",
|
||||
|
|
464
tvix/Cargo.nix
464
tvix/Cargo.nix
|
@ -492,6 +492,34 @@ rec {
|
|||
"zeroize" = [ "dep:zeroize" ];
|
||||
};
|
||||
};
|
||||
"assert-json-diff" = rec {
|
||||
crateName = "assert-json-diff";
|
||||
version = "2.0.2";
|
||||
edition = "2018";
|
||||
sha256 = "04mg3w0rh3schpla51l18362hsirl23q93aisws2irrj32wg5r27";
|
||||
libName = "assert_json_diff";
|
||||
authors = [
|
||||
"David Pedersen <david.pdrsn@gmail.com>"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "serde";
|
||||
packageId = "serde";
|
||||
}
|
||||
{
|
||||
name = "serde_json";
|
||||
packageId = "serde_json";
|
||||
}
|
||||
];
|
||||
devDependencies = [
|
||||
{
|
||||
name = "serde";
|
||||
packageId = "serde";
|
||||
features = [ "derive" ];
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
"async-channel" = rec {
|
||||
crateName = "async-channel";
|
||||
version = "2.3.1";
|
||||
|
@ -1002,6 +1030,17 @@ rec {
|
|||
"portable-atomic" = [ "dep:portable-atomic" ];
|
||||
};
|
||||
};
|
||||
"auto-future" = rec {
|
||||
crateName = "auto-future";
|
||||
version = "1.0.0";
|
||||
edition = "2021";
|
||||
sha256 = "0wykbakzh227vz6frx9p48zsq0wpswgmb7v3917m53m7gr2pw7iw";
|
||||
libName = "auto_future";
|
||||
authors = [
|
||||
"Joseph Lenton <josephlenton@gmail.com>"
|
||||
];
|
||||
|
||||
};
|
||||
"auto_impl" = rec {
|
||||
crateName = "auto_impl";
|
||||
version = "1.2.0";
|
||||
|
@ -1070,7 +1109,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "http-body";
|
||||
|
@ -1243,7 +1282,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "http-body";
|
||||
|
@ -1331,7 +1370,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "http-body";
|
||||
|
@ -1500,6 +1539,135 @@ rec {
|
|||
];
|
||||
features = { };
|
||||
};
|
||||
"axum-test" = rec {
|
||||
crateName = "axum-test";
|
||||
version = "16.4.0";
|
||||
edition = "2021";
|
||||
sha256 = "00rshs1qscm8pvjvjk7wlv7aqnygbw34xr5y1q8afab2fyibqz01";
|
||||
libName = "axum_test";
|
||||
authors = [
|
||||
"Joseph Lenton <josephlenton@gmail.com>"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "anyhow";
|
||||
packageId = "anyhow";
|
||||
}
|
||||
{
|
||||
name = "assert-json-diff";
|
||||
packageId = "assert-json-diff";
|
||||
}
|
||||
{
|
||||
name = "auto-future";
|
||||
packageId = "auto-future";
|
||||
}
|
||||
{
|
||||
name = "axum";
|
||||
packageId = "axum";
|
||||
}
|
||||
{
|
||||
name = "bytes";
|
||||
packageId = "bytes";
|
||||
}
|
||||
{
|
||||
name = "bytesize";
|
||||
packageId = "bytesize";
|
||||
}
|
||||
{
|
||||
name = "cookie";
|
||||
packageId = "cookie";
|
||||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "http-body-util";
|
||||
packageId = "http-body-util";
|
||||
}
|
||||
{
|
||||
name = "hyper";
|
||||
packageId = "hyper";
|
||||
features = [ "http1" ];
|
||||
}
|
||||
{
|
||||
name = "hyper-util";
|
||||
packageId = "hyper-util";
|
||||
features = [ "client" "http1" "client-legacy" ];
|
||||
}
|
||||
{
|
||||
name = "mime";
|
||||
packageId = "mime";
|
||||
}
|
||||
{
|
||||
name = "pretty_assertions";
|
||||
packageId = "pretty_assertions";
|
||||
optional = true;
|
||||
}
|
||||
{
|
||||
name = "reserve-port";
|
||||
packageId = "reserve-port";
|
||||
}
|
||||
{
|
||||
name = "rust-multipart-rfc7578_2";
|
||||
packageId = "rust-multipart-rfc7578_2";
|
||||
}
|
||||
{
|
||||
name = "serde";
|
||||
packageId = "serde";
|
||||
}
|
||||
{
|
||||
name = "serde_json";
|
||||
packageId = "serde_json";
|
||||
}
|
||||
{
|
||||
name = "serde_urlencoded";
|
||||
packageId = "serde_urlencoded";
|
||||
}
|
||||
{
|
||||
name = "smallvec";
|
||||
packageId = "smallvec";
|
||||
}
|
||||
{
|
||||
name = "tokio";
|
||||
packageId = "tokio";
|
||||
features = [ "rt" ];
|
||||
}
|
||||
{
|
||||
name = "tower";
|
||||
packageId = "tower 0.5.1";
|
||||
features = [ "util" "make" ];
|
||||
}
|
||||
{
|
||||
name = "url";
|
||||
packageId = "url";
|
||||
}
|
||||
];
|
||||
devDependencies = [
|
||||
{
|
||||
name = "axum";
|
||||
packageId = "axum";
|
||||
features = [ "multipart" "tokio" "ws" ];
|
||||
}
|
||||
{
|
||||
name = "tokio";
|
||||
packageId = "tokio";
|
||||
features = [ "rt" "rt-multi-thread" "sync" "time" "macros" ];
|
||||
}
|
||||
];
|
||||
features = {
|
||||
"all" = [ "pretty-assertions" "yaml" "msgpack" "reqwest" "shuttle" "typed-routing" "ws" ];
|
||||
"default" = [ "pretty-assertions" ];
|
||||
"msgpack" = [ "dep:rmp-serde" ];
|
||||
"pretty-assertions" = [ "dep:pretty_assertions" ];
|
||||
"reqwest" = [ "dep:reqwest" ];
|
||||
"shuttle" = [ "dep:shuttle-axum" ];
|
||||
"typed-routing" = [ "dep:axum-extra" ];
|
||||
"ws" = [ "axum/ws" "tokio/time" "dep:uuid" "dep:base64" "dep:tokio-tungstenite" "dep:futures-util" ];
|
||||
"yaml" = [ "dep:serde_yaml" ];
|
||||
};
|
||||
resolvedDefaultFeatures = [ "default" "pretty-assertions" ];
|
||||
};
|
||||
"backtrace" = rec {
|
||||
crateName = "backtrace";
|
||||
version = "0.3.74";
|
||||
|
@ -1618,7 +1786,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "hyper-util";
|
||||
|
@ -1917,6 +2085,19 @@ rec {
|
|||
};
|
||||
resolvedDefaultFeatures = [ "default" "std" ];
|
||||
};
|
||||
"bytesize" = rec {
|
||||
crateName = "bytesize";
|
||||
version = "1.3.0";
|
||||
edition = "2015";
|
||||
sha256 = "1k3aak70iwz4s2gsjbxf0ws4xnixqbdz6p2ha96s06748fpniqx3";
|
||||
authors = [
|
||||
"Hyunsik Choi <hyunsik.choi@gmail.com>"
|
||||
];
|
||||
features = {
|
||||
"serde" = [ "dep:serde" ];
|
||||
};
|
||||
resolvedDefaultFeatures = [ "default" ];
|
||||
};
|
||||
"bzip2" = rec {
|
||||
crateName = "bzip2";
|
||||
version = "0.4.4";
|
||||
|
@ -2471,6 +2652,45 @@ rec {
|
|||
];
|
||||
features = { };
|
||||
};
|
||||
"cookie" = rec {
|
||||
crateName = "cookie";
|
||||
version = "0.18.1";
|
||||
edition = "2018";
|
||||
sha256 = "0iy749flficrlvgr3hjmf3igr738lk81n5akzf4ym4cs6cxg7pjd";
|
||||
authors = [
|
||||
"Sergio Benitez <sb@sergio.bz>"
|
||||
"Alex Crichton <alex@alexcrichton.com>"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "time";
|
||||
packageId = "time";
|
||||
usesDefaultFeatures = false;
|
||||
features = [ "std" "parsing" "formatting" "macros" ];
|
||||
}
|
||||
];
|
||||
buildDependencies = [
|
||||
{
|
||||
name = "version_check";
|
||||
packageId = "version_check";
|
||||
}
|
||||
];
|
||||
features = {
|
||||
"aes-gcm" = [ "dep:aes-gcm" ];
|
||||
"base64" = [ "dep:base64" ];
|
||||
"hkdf" = [ "dep:hkdf" ];
|
||||
"hmac" = [ "dep:hmac" ];
|
||||
"key-expansion" = [ "sha2" "hkdf" ];
|
||||
"percent-encode" = [ "percent-encoding" ];
|
||||
"percent-encoding" = [ "dep:percent-encoding" ];
|
||||
"private" = [ "aes-gcm" "base64" "rand" "subtle" ];
|
||||
"rand" = [ "dep:rand" ];
|
||||
"secure" = [ "private" "signed" "key-expansion" ];
|
||||
"sha2" = [ "dep:sha2" ];
|
||||
"signed" = [ "hmac" "sha2" "base64" "rand" "subtle" ];
|
||||
"subtle" = [ "dep:subtle" ];
|
||||
};
|
||||
};
|
||||
"core-foundation" = rec {
|
||||
crateName = "core-foundation";
|
||||
version = "0.9.4";
|
||||
|
@ -4481,7 +4701,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "http-body-util";
|
||||
|
@ -4796,7 +5016,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "indexmap";
|
||||
|
@ -4983,7 +5203,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "httpdate";
|
||||
|
@ -5012,7 +5232,7 @@ rec {
|
|||
dependencies = [
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -5116,7 +5336,33 @@ rec {
|
|||
];
|
||||
|
||||
};
|
||||
"http" = rec {
|
||||
"http 0.2.12" = rec {
|
||||
crateName = "http";
|
||||
version = "0.2.12";
|
||||
edition = "2018";
|
||||
sha256 = "1w81s4bcbmcj9bjp7mllm8jlz6b31wzvirz8bgpzbqkpwmbvn730";
|
||||
authors = [
|
||||
"Alex Crichton <alex@alexcrichton.com>"
|
||||
"Carl Lerche <me@carllerche.com>"
|
||||
"Sean McArthur <sean@seanmonstar.com>"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "bytes";
|
||||
packageId = "bytes";
|
||||
}
|
||||
{
|
||||
name = "fnv";
|
||||
packageId = "fnv";
|
||||
}
|
||||
{
|
||||
name = "itoa";
|
||||
packageId = "itoa";
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
"http 1.1.0" = rec {
|
||||
crateName = "http";
|
||||
version = "1.1.0";
|
||||
edition = "2018";
|
||||
|
@ -5163,7 +5409,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -5191,7 +5437,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "http-body";
|
||||
|
@ -5268,7 +5514,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "http-body";
|
||||
|
@ -5354,7 +5600,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "hyper";
|
||||
|
@ -5505,7 +5751,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "http-body";
|
||||
|
@ -6731,6 +6977,35 @@ rec {
|
|||
];
|
||||
|
||||
};
|
||||
"mime_guess" = rec {
|
||||
crateName = "mime_guess";
|
||||
version = "2.0.5";
|
||||
edition = "2015";
|
||||
sha256 = "03jmg3yx6j39mg0kayf7w4a886dl3j15y8zs119zw01ccy74zi7p";
|
||||
authors = [
|
||||
"Austin Bonander <austin.bonander@gmail.com>"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "mime";
|
||||
packageId = "mime";
|
||||
}
|
||||
{
|
||||
name = "unicase";
|
||||
packageId = "unicase";
|
||||
}
|
||||
];
|
||||
buildDependencies = [
|
||||
{
|
||||
name = "unicase";
|
||||
packageId = "unicase";
|
||||
}
|
||||
];
|
||||
features = {
|
||||
"default" = [ "rev-mappings" ];
|
||||
};
|
||||
resolvedDefaultFeatures = [ "default" "rev-mappings" ];
|
||||
};
|
||||
"minimal-lexical" = rec {
|
||||
crateName = "minimal-lexical";
|
||||
version = "0.2.1";
|
||||
|
@ -7072,6 +7347,10 @@ rec {
|
|||
name = "tracing-subscriber";
|
||||
packageId = "tracing-subscriber";
|
||||
}
|
||||
{
|
||||
name = "tracing-test";
|
||||
packageId = "tracing-test";
|
||||
}
|
||||
{
|
||||
name = "tvix-castore";
|
||||
packageId = "tvix-castore";
|
||||
|
@ -7101,6 +7380,10 @@ rec {
|
|||
}
|
||||
];
|
||||
devDependencies = [
|
||||
{
|
||||
name = "axum-test";
|
||||
packageId = "axum-test";
|
||||
}
|
||||
{
|
||||
name = "hex-literal";
|
||||
packageId = "hex-literal";
|
||||
|
@ -7109,6 +7392,10 @@ rec {
|
|||
name = "rstest";
|
||||
packageId = "rstest";
|
||||
}
|
||||
{
|
||||
name = "sha2";
|
||||
packageId = "sha2";
|
||||
}
|
||||
];
|
||||
features = {
|
||||
"default" = [ "otlp" ];
|
||||
|
@ -8243,7 +8530,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
usesDefaultFeatures = false;
|
||||
features = [ "std" ];
|
||||
}
|
||||
|
@ -8277,7 +8564,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
optional = true;
|
||||
usesDefaultFeatures = false;
|
||||
features = [ "std" ];
|
||||
|
@ -10480,7 +10767,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "http-body";
|
||||
|
@ -10771,7 +11058,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "reqwest";
|
||||
|
@ -10837,7 +11124,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "matchit";
|
||||
|
@ -10904,6 +11191,27 @@ rec {
|
|||
};
|
||||
resolvedDefaultFeatures = [ "opentelemetry_0_27" "opentelemetry_0_27_pkg" "tracing-opentelemetry_0_28_pkg" ];
|
||||
};
|
||||
"reserve-port" = rec {
|
||||
crateName = "reserve-port";
|
||||
version = "2.0.1";
|
||||
edition = "2021";
|
||||
sha256 = "10x21rdb1hjzp6n5flbbw3hfd7brmirckz1q0zsf3a7s5d516f4q";
|
||||
libName = "reserve_port";
|
||||
authors = [
|
||||
"Joseph Lenton <josephlenton@gmail.com>"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "lazy_static";
|
||||
packageId = "lazy_static";
|
||||
}
|
||||
{
|
||||
name = "thiserror";
|
||||
packageId = "thiserror";
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
"ring" = rec {
|
||||
crateName = "ring";
|
||||
version = "0.17.8";
|
||||
|
@ -11141,6 +11449,63 @@ rec {
|
|||
}
|
||||
];
|
||||
|
||||
};
|
||||
"rust-multipart-rfc7578_2" = rec {
|
||||
crateName = "rust-multipart-rfc7578_2";
|
||||
version = "0.6.1";
|
||||
edition = "2021";
|
||||
sha256 = "0mwd3i2mk91n6diaxnkw28vyjbifhrm5ls73pcpfzz8a1i0lidq3";
|
||||
libName = "rust_multipart_rfc7578_2";
|
||||
authors = [
|
||||
"Joseph Lenton <josephlenton@gmail.com>"
|
||||
"Ferris Tseng <ferristseng@fastmail.fm>"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "bytes";
|
||||
packageId = "bytes";
|
||||
}
|
||||
{
|
||||
name = "futures-core";
|
||||
packageId = "futures-core";
|
||||
}
|
||||
{
|
||||
name = "futures-util";
|
||||
packageId = "futures-util";
|
||||
usesDefaultFeatures = false;
|
||||
features = [ "io" ];
|
||||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http 0.2.12";
|
||||
}
|
||||
{
|
||||
name = "mime";
|
||||
packageId = "mime";
|
||||
}
|
||||
{
|
||||
name = "mime_guess";
|
||||
packageId = "mime_guess";
|
||||
}
|
||||
{
|
||||
name = "rand";
|
||||
packageId = "rand";
|
||||
features = [ "small_rng" ];
|
||||
}
|
||||
{
|
||||
name = "thiserror";
|
||||
packageId = "thiserror";
|
||||
}
|
||||
];
|
||||
devDependencies = [
|
||||
{
|
||||
name = "futures-util";
|
||||
packageId = "futures-util";
|
||||
usesDefaultFeatures = false;
|
||||
features = [ "std" ];
|
||||
}
|
||||
];
|
||||
|
||||
};
|
||||
"rustc-demangle" = rec {
|
||||
crateName = "rustc-demangle";
|
||||
|
@ -13068,7 +13433,7 @@ rec {
|
|||
"std" = [ "alloc" "deranged/std" ];
|
||||
"wasm-bindgen" = [ "dep:js-sys" ];
|
||||
};
|
||||
resolvedDefaultFeatures = [ "alloc" "formatting" "parsing" "serde" "serde-well-known" "std" ];
|
||||
resolvedDefaultFeatures = [ "alloc" "formatting" "macros" "parsing" "serde" "serde-well-known" "std" ];
|
||||
};
|
||||
"time-core" = rec {
|
||||
crateName = "time-core";
|
||||
|
@ -13956,7 +14321,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "http-body";
|
||||
|
@ -14484,7 +14849,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
}
|
||||
{
|
||||
name = "http-body";
|
||||
|
@ -14608,7 +14973,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
usesDefaultFeatures = false;
|
||||
features = [ "std" ];
|
||||
}
|
||||
|
@ -15072,6 +15437,57 @@ rec {
|
|||
};
|
||||
resolvedDefaultFeatures = [ "alloc" "ansi" "default" "env-filter" "fmt" "matchers" "nu-ansi-term" "once_cell" "regex" "registry" "sharded-slab" "smallvec" "std" "thread_local" "tracing" "tracing-log" ];
|
||||
};
|
||||
"tracing-test" = rec {
|
||||
crateName = "tracing-test";
|
||||
version = "0.2.5";
|
||||
edition = "2018";
|
||||
sha256 = "0s0x076wpga7k1a3cl8da76rrgvs45zzq9rl6q75w3gy6qa8jysm";
|
||||
libName = "tracing_test";
|
||||
authors = [
|
||||
"Danilo Bargen <mail@dbrgn.ch>"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "tracing-core";
|
||||
packageId = "tracing-core";
|
||||
}
|
||||
{
|
||||
name = "tracing-subscriber";
|
||||
packageId = "tracing-subscriber";
|
||||
features = [ "env-filter" ];
|
||||
}
|
||||
{
|
||||
name = "tracing-test-macro";
|
||||
packageId = "tracing-test-macro";
|
||||
}
|
||||
];
|
||||
features = {
|
||||
"no-env-filter" = [ "tracing-test-macro/no-env-filter" ];
|
||||
};
|
||||
};
|
||||
"tracing-test-macro" = rec {
|
||||
crateName = "tracing-test-macro";
|
||||
version = "0.2.5";
|
||||
edition = "2018";
|
||||
sha256 = "0s3m7a3pycn8r4xyql5gv5b85sdrqp4w24k1aqy26zf80vdrsr84";
|
||||
procMacro = true;
|
||||
libName = "tracing_test_macro";
|
||||
authors = [
|
||||
"Danilo Bargen <mail@dbrgn.ch>"
|
||||
];
|
||||
dependencies = [
|
||||
{
|
||||
name = "quote";
|
||||
packageId = "quote";
|
||||
}
|
||||
{
|
||||
name = "syn";
|
||||
packageId = "syn 2.0.79";
|
||||
features = [ "full" ];
|
||||
}
|
||||
];
|
||||
features = { };
|
||||
};
|
||||
"tracing-tracy" = rec {
|
||||
crateName = "tracing-tracy";
|
||||
version = "0.11.3";
|
||||
|
@ -16446,7 +16862,7 @@ rec {
|
|||
}
|
||||
{
|
||||
name = "http";
|
||||
packageId = "http";
|
||||
packageId = "http 1.1.0";
|
||||
optional = true;
|
||||
}
|
||||
{
|
||||
|
|
|
@ -149,6 +149,7 @@ tracing = "0.1.40"
|
|||
tracing-indicatif = "0.3.6"
|
||||
tracing-opentelemetry = "0.28.0"
|
||||
tracing-subscriber = "0.3.18"
|
||||
tracing-test = "0.2.5"
|
||||
tracing-tracy = "0.11.2"
|
||||
trybuild = "1.0.99"
|
||||
url = "2.5.2"
|
||||
|
|
|
@ -28,6 +28,7 @@ tvix-store = { path = "../store" }
|
|||
tvix-tracing = { path = "../tracing", features = ["tonic", "axum"] }
|
||||
tracing = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
tracing-test = { workspace = true }
|
||||
url = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
lru = { workspace = true }
|
||||
|
@ -44,8 +45,10 @@ otlp = ["tvix-tracing/otlp", "tower-otel-http-metrics"]
|
|||
xp-store-composition-cli = ["tvix-store/xp-composition-cli"]
|
||||
|
||||
[dev-dependencies]
|
||||
axum-test = "16.4.0"
|
||||
hex-literal = { workspace = true }
|
||||
rstest = { workspace = true }
|
||||
sha2.workspace = true
|
||||
|
||||
[lints]
|
||||
workspace = true
|
||||
|
|
|
@ -18,7 +18,7 @@ use crate::AppState;
|
|||
#[derive(Debug, Deserialize)]
|
||||
pub(crate) struct GetNARParams {
|
||||
#[serde(rename = "narsize")]
|
||||
nar_size: u64,
|
||||
nar_size: Option<u64>,
|
||||
}
|
||||
|
||||
#[instrument(skip_all)]
|
||||
|
@ -34,6 +34,13 @@ pub async fn get_head(
|
|||
}): axum::extract::State<AppState>,
|
||||
) -> Result<impl axum::response::IntoResponse, StatusCode> {
|
||||
use prost::Message;
|
||||
// We insist on the nar_size field being set.
|
||||
// If it's not present, the client is misbehaving somehow.
|
||||
let nar_size = nar_size.ok_or_else(|| {
|
||||
warn!("no nar_size parameter set");
|
||||
StatusCode::BAD_REQUEST
|
||||
})?;
|
||||
|
||||
// b64decode the root node passed *by the user*
|
||||
let root_node_proto = BASE64URL_NOPAD
|
||||
.decode(root_node_enc.as_bytes())
|
||||
|
@ -57,7 +64,7 @@ pub async fn get_head(
|
|||
|
||||
let root_node = root_node.try_into_anonymous_node().map_err(|e| {
|
||||
warn!(err=%e, "root node validation failed");
|
||||
StatusCode::BAD_REQUEST
|
||||
StatusCode::NOT_FOUND
|
||||
})?;
|
||||
|
||||
Ok((
|
||||
|
@ -116,7 +123,7 @@ pub async fn get_head(
|
|||
}
|
||||
|
||||
/// Handler to respond to GET/HEAD requests for recently uploaded NAR files.
|
||||
/// Nix probes at {narhash}.nar[.compression_suffix] to determine whether a NAR
|
||||
/// Nix probes at {filehash}.nar[.compression_suffix] to determine whether a NAR
|
||||
/// has already been uploaded, by responding to (some of) these requests we
|
||||
/// avoid it unnecessarily uploading.
|
||||
/// We don't keep a full K/V from NAR hash to root note around, only the
|
||||
|
@ -205,3 +212,264 @@ pub async fn put(
|
|||
|
||||
Ok("")
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::{
|
||||
num::NonZero,
|
||||
sync::{Arc, LazyLock},
|
||||
};
|
||||
|
||||
use axum::{http::Method, Router};
|
||||
use bytes::Bytes;
|
||||
use data_encoding::BASE64URL_NOPAD;
|
||||
use nix_compat::nixbase32;
|
||||
use sha2::Digest;
|
||||
use tracing_test::traced_test;
|
||||
use tvix_castore::{
|
||||
blobservice::{BlobService, MemoryBlobService},
|
||||
directoryservice::{DirectoryService, MemoryDirectoryService},
|
||||
fixtures::HELLOWORLD_BLOB_DIGEST,
|
||||
};
|
||||
use tvix_store::{
|
||||
fixtures::{
|
||||
CASTORE_NODE_COMPLICATED, CASTORE_NODE_SYMLINK, NAR_CONTENTS_COMPLICATED,
|
||||
NAR_CONTENTS_HELLOWORLD, NAR_CONTENTS_SYMLINK,
|
||||
},
|
||||
pathinfoservice::{MemoryPathInfoService, PathInfoService},
|
||||
};
|
||||
|
||||
use crate::AppState;
|
||||
|
||||
pub static NAR_STR_SYMLINK: LazyLock<String> = LazyLock::new(|| {
|
||||
use prost::Message;
|
||||
BASE64URL_NOPAD.encode(
|
||||
&tvix_castore::proto::Node::from_name_and_node("".into(), CASTORE_NODE_SYMLINK.clone())
|
||||
.encode_to_vec(),
|
||||
)
|
||||
});
|
||||
|
||||
/// Accepts a router without state, and returns a [axum_test::TestServer].
|
||||
fn gen_server(
|
||||
router: axum::Router<AppState>,
|
||||
) -> (
|
||||
axum_test::TestServer,
|
||||
impl BlobService,
|
||||
impl DirectoryService,
|
||||
impl PathInfoService,
|
||||
) {
|
||||
let blob_service = Arc::new(MemoryBlobService::default());
|
||||
let directory_service = Arc::new(MemoryDirectoryService::default());
|
||||
let path_info_service = Arc::new(MemoryPathInfoService::default());
|
||||
|
||||
let app = router.with_state(AppState::new(
|
||||
blob_service.clone(),
|
||||
directory_service.clone(),
|
||||
path_info_service.clone(),
|
||||
NonZero::new(100).unwrap(),
|
||||
));
|
||||
|
||||
(
|
||||
axum_test::TestServer::new(app).unwrap(),
|
||||
blob_service,
|
||||
directory_service,
|
||||
path_info_service,
|
||||
)
|
||||
}
|
||||
|
||||
#[traced_test]
|
||||
#[tokio::test]
|
||||
async fn test_get_head() {
|
||||
let (server, _blob_service, _directory_service, _path_info_service) =
|
||||
gen_server(Router::new().route(
|
||||
"/nar/tvix-castore/:root_node_enc",
|
||||
axum::routing::get(super::get_head),
|
||||
));
|
||||
|
||||
// Empty nar_str should be NotFound
|
||||
server
|
||||
.method(Method::HEAD, "/nar/tvix-castore/")
|
||||
.expect_failure()
|
||||
.await
|
||||
.assert_status_not_found();
|
||||
|
||||
let valid_url = &format!("/nar/tvix-castore/{}", &*NAR_STR_SYMLINK);
|
||||
let qps = &[("narsize", &NAR_CONTENTS_SYMLINK.len().to_string())];
|
||||
|
||||
// Missing narsize should be BadRequest
|
||||
server
|
||||
.method(Method::HEAD, valid_url)
|
||||
.expect_failure()
|
||||
.await
|
||||
.assert_status_bad_request();
|
||||
|
||||
let invalid_url = {
|
||||
use prost::Message;
|
||||
let n = tvix_castore::proto::Node {
|
||||
node: Some(tvix_castore::proto::node::Node::Directory(
|
||||
tvix_castore::proto::DirectoryNode {
|
||||
name: "".into(),
|
||||
digest: "invalid b64".into(),
|
||||
size: 1,
|
||||
},
|
||||
)),
|
||||
};
|
||||
&format!(
|
||||
"/nar/tvix-castore/{}",
|
||||
BASE64URL_NOPAD.encode(&n.encode_to_vec())
|
||||
)
|
||||
};
|
||||
|
||||
// Invalid node proto should return NotFound
|
||||
server
|
||||
.method(Method::HEAD, invalid_url)
|
||||
.add_query_params(qps)
|
||||
.expect_failure()
|
||||
.await
|
||||
.assert_status_not_found();
|
||||
|
||||
// success, HEAD
|
||||
server
|
||||
.method(Method::HEAD, valid_url)
|
||||
.add_query_params(qps)
|
||||
.expect_success()
|
||||
.await;
|
||||
|
||||
// success, GET
|
||||
assert_eq!(
|
||||
NAR_CONTENTS_SYMLINK.as_slice(),
|
||||
server
|
||||
.get(valid_url)
|
||||
.add_query_params(qps)
|
||||
.expect_success()
|
||||
.await
|
||||
.into_bytes(),
|
||||
"Expected to get back NAR_CONTENTS_SYMLINK"
|
||||
)
|
||||
}
|
||||
|
||||
/// Uploading a NAR with a different file hash than what's specified in the URL
|
||||
/// is considered an error.
|
||||
#[traced_test]
|
||||
#[tokio::test]
|
||||
async fn test_put_wrong_narhash() {
|
||||
let (server, _blob_service, _directory_service, _path_info_service) =
|
||||
gen_server(Router::new().route("/nar/:nar_str", axum::routing::put(super::put)));
|
||||
|
||||
server
|
||||
.put("/nar/0000000000000000000000000000000000000000000000000000.nar")
|
||||
.bytes(Bytes::from_static(&NAR_CONTENTS_SYMLINK))
|
||||
.expect_failure()
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Uploading a NAR with compression is not supported.
|
||||
#[traced_test]
|
||||
#[tokio::test]
|
||||
async fn test_put_with_compression_fail() {
|
||||
let (server, _blob_service, _directory_service, _path_info_service) =
|
||||
gen_server(Router::new().route("/nar/:nar_str", axum::routing::put(super::put)));
|
||||
|
||||
let nar_sha256: [u8; 32] = sha2::Sha256::new_with_prefix(NAR_CONTENTS_SYMLINK.as_slice())
|
||||
.finalize()
|
||||
.into();
|
||||
|
||||
let nar_url = format!("/nar/{}.nar.zst", nixbase32::encode(&nar_sha256));
|
||||
|
||||
server
|
||||
.put(&nar_url)
|
||||
.bytes(Bytes::from_static(&NAR_CONTENTS_SYMLINK))
|
||||
.expect_failure()
|
||||
.await
|
||||
.assert_status_unauthorized();
|
||||
}
|
||||
|
||||
/// Upload a NAR with a single file, ensure the blob exists later on.
|
||||
#[traced_test]
|
||||
#[tokio::test]
|
||||
async fn test_put_success() {
|
||||
let (server, blob_service, _directory_service, _path_info_service) =
|
||||
gen_server(Router::new().route("/nar/:nar_str", axum::routing::put(super::put)));
|
||||
|
||||
let nar_sha256: [u8; 32] =
|
||||
sha2::Sha256::new_with_prefix(NAR_CONTENTS_HELLOWORLD.as_slice())
|
||||
.finalize()
|
||||
.into();
|
||||
|
||||
let nar_url = format!("/nar/{}.nar", nixbase32::encode(&nar_sha256));
|
||||
|
||||
server
|
||||
.put(&nar_url)
|
||||
.bytes(Bytes::from_static(&NAR_CONTENTS_HELLOWORLD))
|
||||
.expect_success()
|
||||
.await;
|
||||
|
||||
assert!(blob_service
|
||||
.has(&HELLOWORLD_BLOB_DIGEST)
|
||||
.await
|
||||
.expect("blobservice"))
|
||||
}
|
||||
|
||||
// Upload a NAR with blobs and directories, ensure blobs and directories
|
||||
// were uploaded, by rendering the NAR stream from the root node we know
|
||||
// describes these contents.
|
||||
#[traced_test]
|
||||
#[tokio::test]
|
||||
async fn test_put_success2() {
|
||||
let (server, blob_service, directory_service, _path_info_service) =
|
||||
gen_server(Router::new().route("/nar/:nar_str", axum::routing::put(super::put)));
|
||||
|
||||
let nar_sha256: [u8; 32] =
|
||||
sha2::Sha256::new_with_prefix(NAR_CONTENTS_COMPLICATED.as_slice())
|
||||
.finalize()
|
||||
.into();
|
||||
|
||||
let nar_url = format!("/nar/{}.nar", nixbase32::encode(&nar_sha256));
|
||||
|
||||
server
|
||||
.put(&nar_url)
|
||||
.bytes(Bytes::from_static(&NAR_CONTENTS_COMPLICATED))
|
||||
.expect_success()
|
||||
.await;
|
||||
|
||||
let mut buf = Vec::new();
|
||||
tvix_store::nar::write_nar(
|
||||
&mut buf,
|
||||
&CASTORE_NODE_COMPLICATED,
|
||||
blob_service,
|
||||
directory_service,
|
||||
)
|
||||
.await
|
||||
.expect("write nar");
|
||||
|
||||
assert_eq!(NAR_CONTENTS_COMPLICATED, buf[..]);
|
||||
}
|
||||
|
||||
/// Upload a NAR, ensure a HEAD by NarHash returns a 2xx code.
|
||||
#[traced_test]
|
||||
#[tokio::test]
|
||||
async fn test_put_root_nodes() {
|
||||
let (server, _blob_service, _directory_servicee, _path_info_service) = gen_server(
|
||||
Router::new()
|
||||
.route("/nar/:nar_str", axum::routing::put(super::put))
|
||||
.route("/nar/:nar_str", axum::routing::get(super::head_root_nodes)),
|
||||
);
|
||||
|
||||
let nar_sha256: [u8; 32] =
|
||||
sha2::Sha256::new_with_prefix(NAR_CONTENTS_COMPLICATED.as_slice())
|
||||
.finalize()
|
||||
.into();
|
||||
|
||||
let nar_url = format!("/nar/{}.nar", nixbase32::encode(&nar_sha256));
|
||||
|
||||
// upload NAR
|
||||
server
|
||||
.put(&nar_url)
|
||||
.bytes(Bytes::from_static(&NAR_CONTENTS_COMPLICATED))
|
||||
.expect_success()
|
||||
.await;
|
||||
|
||||
// check HEAD by NarHash
|
||||
server.method(Method::HEAD, &nar_url).expect_success().await;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue