diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ed2fca269c..366deafce0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -96,6 +96,11 @@ task, but not currently run per-platform, which means there is no way to find out the status of clippy per platform without running it on that platform as a developer. +### import rustup-macros::{integration,unit}_test into test modules + +These test helpers add pre-and-post logic to tests to enable the use of tracing +inside tests, which can be helpful for tracking down behaviours in larger tests. + ## Version numbers If you ever see a released version of rustup which has `::` in its version string @@ -217,8 +222,8 @@ break our testing (like `RUSTUP_TOOLCHAIN`, `SHELL`, `ZDOTDIR`, `RUST_BACKTRACE` But if you want to debug locally, you may need backtrace. `RUSTUP_BACKTRACE` is used like `RUST_BACKTRACE` to enable backtraces of failed tests. -**NOTE**: This is a backtrace for the test, not for any rustup process running -in the test +**NOTE**: This is a backtrace for the test, not for any subprocess invocation of +rustup process running in the test ```bash $ RUSTUP_BACKTRACE=1 cargo test --release --test cli-v1 -- remove_toolchain_then_add_again @@ -273,3 +278,74 @@ test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 26 filtered out error: test failed, to rerun pass '--test cli-v1' ``` + +## Tracing + +The feature "otel" can be used when building rustup to turn on Opentelemetry +tracing with an OLTP GRPC exporter. This requires protoc installed, which can be +downloaded from GitHub or installed via package manager. + +The normal [OTLP environment +variables](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md) +can be used to customise its behaviour, but often the simplest thing is to just +run a Jaeger docker container on the same host: + +```sh +docker run -d --name jaeger -e COLLECTOR_ZIPKIN_HOST_PORT=:9411 -e COLLECTOR_OTLP_ENABLED=true -p 6831:6831/udp -p 6832:6832/udp -p 5778:5778 -p 16686:16686 -p 4317:4317 -p 4318:4318 -p 14250:14250 -p 14268:14268 -p 14269:14269 -p 9411:9411 jaegertracing/all-in-one:latest +``` + +Then build rustup-init with tracing: + +```sh +cargo build --features=otel +``` + +Run the operation you want to analyze: + +```sh +RUSTUP_FORCE_ARG0="rustup" ./target/debug/rustup-init show +``` + +And [look in Jaeger for a trace](http://localhost:16686/search?service=rustup). + +### Tracing and tests + +The custom macro `rustup_macros::test` adds a prelude and suffix to each test to +ensure that there is a tracing context setup, that the test function is a span, +and that the spans from the test are flushed. Build with features=otel to +use this feature. + +### Adding instrumentation + +The `otel` feature uses conditional compilation to only add function instrument +when enabled. Instrumenting a currently uninstrumented function is mostly simply +done like so: + +```rust +#[cfg_attr(feature = "otel", tracing::instrument(err, skip_all))] +``` + +`skip_all` is not required, but some core structs don't implement Debug yet, and +others have a lot of output in Debug : tracing adds some overheads, so keeping +spans lightweight can help avoid frequency bias in the results - where +parameters with large debug in frequently called functions show up as much +slower than they are. + +Some good general heuristics: + +- Do instrument slow blocking functions +- Do instrument functions with many callers or that call many different things, + as these tend to help figure the puzzle of what-is-happening +- Default to not instrumenting thin shim functions (or at least, only instrument + them temporarily while figuring out the shape of a problem) +- Be way of debug build timing - release optimisations make a huge difference, + though debug is a lot faster to iterate on. If something isn't a problem in + release don't pay it too much heed in debug. + +### Caveats + +Cross-thread propogation isn't connected yet. This will cause instrumentation in +a thread to make a new root span until it is fixed. If any Tokio runtime-related +code gets added in those threads this will also cause a panic. We have a couple +of threadpools in use today; if you need to instrument within that context, use +a thunk to propogate the tokio runtime into those threads. \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 77c1253de7..8b3aaf7751 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,9 +10,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" dependencies = [ "memchr", ] @@ -37,49 +37,58 @@ dependencies = [ [[package]] name = "anstream" -version = "0.2.6" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "342258dd14006105c2b75ab1bd7543a03bdf0cfc94383303ac212a04939dff6f" +checksum = "6342bd4f5a1205d7f41e94a41a901f5647c938cdfa96036338e8533c9d6c2450" dependencies = [ "anstyle", "anstyle-parse", + "anstyle-query", "anstyle-wincon", - "concolor-override", - "concolor-query", + "colorchoice", "is-terminal", "utf8parse", ] [[package]] name = "anstyle" -version = "0.3.5" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2" +checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d" [[package]] name = "anstyle-parse" -version = "0.1.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7d1bb534e9efed14f3e5f44e7dd1a4f709384023a4165199a4241e18dff0116" +checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee" dependencies = [ "utf8parse", ] +[[package]] +name = "anstyle-query" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys 0.48.0", +] + [[package]] name = "anstyle-wincon" -version = "0.2.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3127af6145b149f3287bb9a0d10ad9c5692dba8c53ad48285e5bec4063834fa" +checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188" dependencies = [ "anstyle", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] name = "anyhow" -version = "1.0.70" +version = "1.0.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7de8ce5e0f9f8d88245311066a578d72b7af3e7088f32783804676302df237e4" +checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "as-slice" @@ -103,6 +112,39 @@ dependencies = [ "tokio", ] +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + [[package]] name = "atty" version = "0.2.14" @@ -120,6 +162,57 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "axum" +version = "0.6.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b70caf9f1b0c045f7da350636435b775a9733adf2df56e8aa2a29210fbc335d4" +dependencies = [ + "async-trait", + "axum-core", + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + [[package]] name = "base64" version = "0.21.0" @@ -155,9 +248,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.12.0" +version = "3.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" +checksum = "9b1ce199063694f33ffb7dd4e0ee620741495c32833cde5aa08f02a0bf96f0c8" [[package]] name = "byteorder" @@ -209,9 +302,9 @@ dependencies = [ [[package]] name = "clap" -version = "3.2.23" +version = "3.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71655c45cb9845d3270c9d6df84ebe72b4dad3c2ba3f7023ad47c144e4e473a5" +checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" dependencies = [ "atty", "bitflags", @@ -252,19 +345,10 @@ dependencies = [ ] [[package]] -name = "concolor-override" +name = "colorchoice" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a855d4a1978dc52fb0536a04d384c2c0c1aa273597f08b77c8c4d3b2eec6037f" - -[[package]] -name = "concolor-query" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d11d52c3d7ca2e6d0040212be9e4dbbcd78b6447f535b6b561f449427944cf" -dependencies = [ - "windows-sys 0.45.0", -] +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "content_inspector" @@ -287,15 +371,15 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" +checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" [[package]] name = "cpufeatures" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "280a9f2d8b3a38871a3c8a46fb80db65e5e5ed97da80c4d08bf27fb63e35e181" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" dependencies = [ "libc", ] @@ -311,9 +395,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf2b3e8478797446514c91ef04bafcb59faba183e621ad488df88983cc14128c" +checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" dependencies = [ "cfg-if 1.0.0", "crossbeam-utils", @@ -425,7 +509,7 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.13", + "syn 2.0.15", ] [[package]] @@ -442,7 +526,20 @@ checksum = "2345488264226bf682893e25de0769f3360aac9957980ec49361b083ddaa5bc5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.13", + "syn 2.0.15", +] + +[[package]] +name = "dashmap" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "907076dfda823b0b36d2a1bb5f90c96660a5bbcd7729e10727f07858f22c4edc" +dependencies = [ + "cfg-if 1.0.0", + "hashbrown", + "lock_api", + "once_cell", + "parking_lot_core", ] [[package]] @@ -473,9 +570,9 @@ dependencies = [ [[package]] name = "dunce" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bd4b30a6560bbd9b4620f4de34c3f14f60848e58a9b7216801afcb4c7b31c3c" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" [[package]] name = "effective-limits" @@ -537,24 +634,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.2.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" -dependencies = [ - "errno-dragonfly", - "libc", - "winapi", -] - -[[package]] -name = "errno" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d6a0976c999d473fe89ad888d5a284e55366d9dc9038b1ba2aa15128c4afa0" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -578,21 +664,27 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a3de6e8d11b22ff9edc6d916f890800597d60f8b2da1caf2955c274638d6412" +checksum = "5cbc844cecaee9d4443931972e1289c8ff485cb4cc2767cb03ca139ed6885153" dependencies = [ "cfg-if 1.0.0", "libc", "redox_syscall 0.2.16", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + [[package]] name = "flate2" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", "miniz_oxide", @@ -630,9 +722,9 @@ dependencies = [ [[package]] name = "fs_at" -version = "0.1.4" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37047c0d530b3aefc64e4c4d7c6b1e23030c65973661b70e12c826f426f3f675" +checksum = "0504bab20f4487fdf1c20ed48e3e32c7951827a778cd3dfded1768f90b6abb0a" dependencies = [ "aligned", "cfg-if 1.0.0", @@ -640,7 +732,21 @@ dependencies = [ "libc", "nix", "smart-default", - "windows-sys 0.45.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "futures" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", ] [[package]] @@ -650,6 +756,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955518d47e09b25bbebc7a18df10b81f0c766eaf4c4f1cccef2fca5f2a4fb5f2" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -658,12 +765,34 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" +[[package]] +name = "futures-executor" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4fff74096e71ed47f8e023204cfd0aa1289cd54ae5430a9523be060cdb849964" +[[package]] +name = "futures-macro" +version = "0.3.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + [[package]] name = "futures-sink" version = "0.3.28" @@ -682,8 +811,11 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b01e40b772d54cf6c6d721c1d1abd0647a0106a12ecaa1c186273392a69533" dependencies = [ + "futures-channel", "futures-core", "futures-io", + "futures-macro", + "futures-sink", "futures-task", "memchr", "pin-project-lite", @@ -703,9 +835,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +checksum = "c85e1d9ab2eadba7e5040d4e09cbd6d072b76a557ad64e797c2cb9d4da21d7e4" dependencies = [ "cfg-if 1.0.0", "libc", @@ -743,9 +875,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "h2" -version = "0.3.16" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d" +checksum = "17f8a914c2987b688368b5138aa05321db91f4090cf26118185672ad588bce21" dependencies = [ "bytes", "fnv", @@ -766,6 +898,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -792,11 +930,11 @@ checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" [[package]] name = "home" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "747309b4b440c06d57b0b25f2aee03ee9b5e5397d288c60e21fc709bb98a7408" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "winapi", + "windows-sys 0.48.0", ] [[package]] @@ -851,9 +989,9 @@ dependencies = [ [[package]] name = "hyper" -version = "0.14.25" +version = "0.14.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc5e554ff619822309ffd57d8734d77cd5ce6238bc956f037ea06c58238c9899" +checksum = "ab302d72a6f11a3b910431ff93aae7e773078c769f0a3ef15fb9ec692ed147d4" dependencies = [ "bytes", "futures-channel", @@ -886,6 +1024,18 @@ dependencies = [ "tokio-rustls", ] +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -901,9 +1051,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.54" +version = "0.1.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c17cc76786e99f8d2f055c11159e7f0091c42474dcc3189fbab96072e873e6d" +checksum = "0722cd7114b7de04316e7ea5456a0bbb20e4adb46fd27a3697adb812cff0f37c" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -954,13 +1104,13 @@ dependencies = [ [[package]] name = "io-lifetimes" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb" +checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" dependencies = [ "hermit-abi 0.3.1", "libc", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -971,14 +1121,23 @@ checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f" [[package]] name = "is-terminal" -version = "0.4.6" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "256017f749ab3117e93acb91063009e1f1bb56d03965b14c2c8df4eb02c524d8" +checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f" dependencies = [ "hermit-abi 0.3.1", "io-lifetimes", - "rustix 0.37.6", - "windows-sys 0.45.0", + "rustix", + "windows-sys 0.48.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", ] [[package]] @@ -1013,15 +1172,15 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.140" +version = "0.2.142" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99227334921fae1a979cf0bfdfcc6b3e5ce376ef57e16fb6fb3ea2ed6095f80c" +checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" [[package]] name = "libz-sys" -version = "1.1.8" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9702761c3935f8cc2f101793272e202c72b99da8f4224a19ddcf1279a6450bbf" +checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db" dependencies = [ "cc", "libc", @@ -1040,15 +1199,19 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "b64f40e5e03e0d54f03845c8197d0291253cdbedfb1cb46b13c2c117554a9f4c" [[package]] -name = "linux-raw-sys" -version = "0.3.1" +name = "lock_api" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d59d8c75012853d2e872fb56bc8a2e53718e2cafe1a4c823143141c6d90c322f" +checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" +dependencies = [ + "autocfg", + "scopeguard", +] [[package]] name = "log" @@ -1070,6 +1233,21 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matchit" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b87248edafb776e59e6ee64a79086f65890d3510f2c656c000bf2a7e8a0aea40" + [[package]] name = "memchr" version = "2.5.0" @@ -1093,9 +1271,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.6.2" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" dependencies = [ "adler", ] @@ -1112,6 +1290,12 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "multimap" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" + [[package]] name = "native-tls" version = "0.2.11" @@ -1163,6 +1347,16 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -1200,9 +1394,9 @@ checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "opener" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d57fbd03b7f4ab9605d497df6f1cb7ea0ac60b18a2038b1e66e5ab34fe01fa99" +checksum = "6c62dcb6174f9cb326eac248f07e955d5d559c272730b6c03e396b443b562788" dependencies = [ "bstr", "normpath", @@ -1211,9 +1405,9 @@ dependencies = [ [[package]] name = "openssl" -version = "0.10.49" +version = "0.10.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d2f106ab837a24e03672c59b1239669a0596406ff657c3c0835b6b7f0f35a33" +checksum = "01b8574602df80f7b85fdfc5392fa884a4e3b3f4f35402c070ab34c3d3f78d56" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -1232,7 +1426,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.13", + "syn 2.0.15", ] [[package]] @@ -1243,18 +1437,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "111.25.2+1.1.1t" +version = "111.25.3+1.1.1t" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320708a054ad9b3bf314688b5db87cf4d6683d64cfc835e2337924ae62bf4431" +checksum = "924757a6a226bf60da5f7dd0311a34d2b52283dd82ddeb103208ddc66362f80c" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.84" +version = "0.9.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a20eace9dc2d82904039cb76dcf50fb1a0bba071cfd1629720b5d6f1ddba0fa" +checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e" dependencies = [ "cc", "libc", @@ -1263,14 +1457,94 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "opentelemetry" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69d6c3d7288a106c0a363e4b0e8d308058d56902adefb16f4936f417ffef086e" +dependencies = [ + "opentelemetry_api", + "opentelemetry_sdk", +] + +[[package]] +name = "opentelemetry-otlp" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c928609d087790fc936a1067bdc310ae702bdf3b090c3f281b713622c8bbde" +dependencies = [ + "async-trait", + "futures", + "futures-util", + "http", + "opentelemetry", + "opentelemetry-proto", + "prost", + "thiserror", + "tokio", + "tonic", +] + +[[package]] +name = "opentelemetry-proto" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d61a2f56df5574508dd86aaca016c917489e589ece4141df1b5e349af8d66c28" +dependencies = [ + "futures", + "futures-util", + "opentelemetry", + "prost", + "tonic", + "tonic-build", +] + +[[package]] +name = "opentelemetry_api" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c24f96e21e7acc813c7a8394ee94978929db2bcc46cf6b5014fc612bf7760c22" +dependencies = [ + "fnv", + "futures-channel", + "futures-util", + "indexmap", + "js-sys", + "once_cell", + "pin-project-lite", + "thiserror", +] + +[[package]] +name = "opentelemetry_sdk" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ca41c4933371b61c2a2f214bf16931499af4ec90543604ec828f7a625c09113" +dependencies = [ + "async-trait", + "crossbeam-channel", + "dashmap", + "fnv", + "futures-channel", + "futures-executor", + "futures-util", + "once_cell", + "opentelemetry_api", + "percent-encoding", + "rand", + "thiserror", + "tokio", + "tokio-stream", +] + [[package]] name = "os_pipe" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a53dbb20faf34b16087a931834cba2d7a73cc74af2b7ef345a4c8324e2409a12" +checksum = "0ae859aa07428ca9a929b936690f8b12dc5f11dd8c6992a18ca93919f28bc177" dependencies = [ "libc", - "windows-sys 0.45.0", + "windows-sys 0.48.0", ] [[package]] @@ -1279,12 +1553,61 @@ version = "6.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ceedf44fb00f2d1984b0bc98102627ce622e083e49a5bacdb3e514fa4238e267" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking_lot_core" +version = "0.9.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "windows-sys 0.45.0", +] + [[package]] name = "percent-encoding" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "petgraph" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4" +dependencies = [ + "fixedbitset", + "indexmap", +] + +[[package]] +name = "pin-project" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -1309,15 +1632,79 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "prettyplease" +version = "0.1.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8646e95016a7a6c4adea95bafa8a16baab64b583356217f2c85db4a39d9a86" +dependencies = [ + "proc-macro2", + "syn 1.0.109", +] + [[package]] name = "proc-macro2" -version = "1.0.55" +version = "1.0.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d0dd4be24fcdcfeaa12a432d588dc59bbad6cad3510c67e74a2b6b2fc950564" +checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435" dependencies = [ "unicode-ident", ] +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" +dependencies = [ + "bytes", + "heck", + "itertools", + "lazy_static", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn 1.0.109", + "tempfile", + "which", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost", +] + [[package]] name = "pulldown-cmark" version = "0.9.2" @@ -1410,13 +1797,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.7.3" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b1f693b24f6ac912f4893ef08244d70b6067480d2f1a46e950c9691e6749d1d" +checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.7.1", ] [[package]] @@ -1424,6 +1811,9 @@ name = "regex-automata" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] [[package]] name = "regex-syntax" @@ -1431,6 +1821,12 @@ version = "0.6.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" +[[package]] +name = "regex-syntax" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5996294f19bd3aae0453a862ad728f60e6600695733dd5df01da90c54363a3c" + [[package]] name = "remove_dir_all" version = "0.8.2" @@ -1450,12 +1846,12 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.11.16" +version = "0.11.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b71749df584b7f4cac2c426c127a7c785a5106cc98f7a8feb044115f0fa254" +checksum = "13293b639a097af28fc8a90f22add145a9c954e49d77da06263d58cf44d5fb91" dependencies = [ "async-compression", - "base64", + "base64 0.21.0", "bytes", "encoding_rs", "futures-core", @@ -1529,30 +1925,16 @@ dependencies = [ [[package]] name = "rustix" -version = "0.36.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4165c9963ab29e422d6c26fbc1d37f15bace6b2810221f9d925023480fcf0e" -dependencies = [ - "bitflags", - "errno 0.2.8", - "io-lifetimes", - "libc", - "linux-raw-sys 0.1.4", - "windows-sys 0.45.0", -] - -[[package]] -name = "rustix" -version = "0.37.6" +version = "0.37.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d097081ed288dfe45699b72f5b5d648e5f15d64d900c7080273baa20c16a6849" +checksum = "8bbfc1d1c7c40c01715f47d71444744a81669ca84e8b63e25a55e169b1f86433" dependencies = [ "bitflags", - "errno 0.3.0", + "errno", "io-lifetimes", "libc", - "linux-raw-sys 0.3.1", - "windows-sys 0.45.0", + "linux-raw-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1585,7 +1967,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" dependencies = [ - "base64", + "base64 0.21.0", ] [[package]] @@ -1610,12 +1992,15 @@ dependencies = [ "once_cell", "opener", "openssl", + "opentelemetry", + "opentelemetry-otlp", "pulldown-cmark", "rand", "regex", "remove_dir_all", "retry", "rs_tracing", + "rustup-macros", "same-file", "scopeguard", "semver", @@ -1628,7 +2013,11 @@ dependencies = [ "term", "thiserror", "threadpool", + "tokio", "toml", + "tracing", + "tracing-opentelemetry", + "tracing-subscriber", "trycmd", "url", "wait-timeout", @@ -1639,6 +2028,23 @@ dependencies = [ "zstd", ] +[[package]] +name = "rustup-macros" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "sha2", + "syn 2.0.15", +] + +[[package]] +name = "rustversion" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" + [[package]] name = "ryu" version = "1.0.13" @@ -1716,29 +2122,29 @@ checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" [[package]] name = "serde" -version = "1.0.159" +version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c04e8343c3daeec41f58990b9d77068df31209f2af111e059e9fe9646693065" +checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.159" +version = "1.0.160" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c614d17805b093df4b147b51339e7e44bf05ef59fba1e45d83500bcfb4d8585" +checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df" dependencies = [ "proc-macro2", "quote", - "syn 2.0.13", + "syn 2.0.15", ] [[package]] name = "serde_json" -version = "1.0.95" +version = "1.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d721eca97ac802aa7777b701877c8004d950fc142651367300d21c1cc0194744" +checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1" dependencies = [ "itoa", "ryu", @@ -1807,22 +2213,28 @@ dependencies = [ "autocfg", ] +[[package]] +name = "smallvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" + [[package]] name = "smart-default" -version = "0.6.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "133659a15339456eeeb07572eb02a91c91e9815e9cbc89566944d2c8d3efdbf6" +checksum = "0eb01866308440fc64d6c44d9e86c5cc17adfe33c4d6eed55da9145044d0ffc1" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.15", ] [[package]] name = "snapbox" -version = "0.4.10" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9615402f9cff539301119bdf2c2f328739cf2b45c2116666618fb6ac399f75bb" +checksum = "f6bccd62078347f89a914e3004d94582e13824d4e3d8a816317862884c423835" dependencies = [ "anstream", "anstyle", @@ -1842,9 +2254,9 @@ dependencies = [ [[package]] name = "snapbox-macros" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8e40c667388ed1cb5060f545d0013bf0a23efdfa6c5c3e9ef592de391cd860f" +checksum = "eaaf09df9f0eeae82be96290918520214530e738a7fe5a351b0f24cf77c0ca31" dependencies = [ "anstream", ] @@ -1896,15 +2308,21 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.13" +version = "2.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c9da457c5285ac1f936ebd076af6dac17a61cfe7826f2076b4d015cf47bc8ec" +checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + [[package]] name = "sys-info" version = "0.9.1" @@ -1935,7 +2353,7 @@ dependencies = [ "cfg-if 1.0.0", "fastrand", "redox_syscall 0.3.5", - "rustix 0.37.6", + "rustix", "windows-sys 0.45.0", ] @@ -1960,12 +2378,12 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c9afddd2cec1c0909f06b00ef33f94ab2cc0578c4a610aa208ddfec8aa2b43a" +checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" dependencies = [ - "rustix 0.36.11", - "windows-sys 0.45.0", + "rustix", + "windows-sys 0.48.0", ] [[package]] @@ -1994,7 +2412,17 @@ checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.13", + "syn 2.0.15", +] + +[[package]] +name = "thread_local" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", ] [[package]] @@ -2061,9 +2489,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.27.0" +version = "1.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0de47a4eecbe11f498978a9b29d792f0d2692d1dd003650c24c76510e3bc001" +checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f" dependencies = [ "autocfg", "bytes", @@ -2072,7 +2500,29 @@ dependencies = [ "num_cpus", "pin-project-lite", "socket2", - "windows-sys 0.45.0", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", ] [[package]] @@ -2108,11 +2558,22 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + [[package]] name = "tokio-util" -version = "0.7.7" +version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5427d89453009325de0d8f342c9490009f76e999cb7672d77e46267448f7e6b2" +checksum = "806fe8c2c87eccc8b3267cbae29ed3ab2d0bd37fca70ab622e46aaa9375ddb7d" dependencies = [ "bytes", "futures-core", @@ -2156,6 +2617,77 @@ dependencies = [ "winnow", ] +[[package]] +name = "tonic" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f219fad3b929bef19b1f86fbc0358d35daed8f2cac972037ac0dc10bbb8d5fb" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.13.1", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost", + "prost-derive", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", + "tracing-futures", +] + +[[package]] +name = "tonic-build" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bf5e9b9c0f7e0a7c027dcfaba7b2c60816c7049171f679d99ee2ff65d0de8c4" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + [[package]] name = "tower-service" version = "0.3.2" @@ -2170,9 +2702,21 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if 1.0.0", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f57e3ca2a01450b1a921183a9c9cbfda207fd822cef4ccb00a65402cbba7a74" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.15", +] + [[package]] name = "tracing-core" version = "0.1.30" @@ -2180,6 +2724,60 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "tracing-log" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ddad33d2d10b1ed7eb9d1f518a5674713876e97e5bb9b7345a7984fbb4f922" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-opentelemetry" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21ebb87a95ea13271332df069020513ab70bdb5637ca42d6e492dc3bbbad48de" +dependencies = [ + "once_cell", + "opentelemetry", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", ] [[package]] @@ -2190,9 +2788,9 @@ checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" [[package]] name = "trycmd" -version = "0.14.15" +version = "0.14.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32564b3f936a9ebedf5cc07dcf1e7e661204766d35f92c03bf347b099d84e783" +checksum = "2925e71868a12b173c1eb166018c2d2f9dfaedfcaec747bdb6ea2246785d258e" dependencies = [ "glob", "humantime", @@ -2269,6 +2867,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "vcpkg" version = "0.2.15" @@ -2408,6 +3012,17 @@ dependencies = [ "untrusted", ] +[[package]] +name = "which" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269" +dependencies = [ + "either", + "libc", + "once_cell", +] + [[package]] name = "winapi" version = "0.3.9" @@ -2441,11 +3056,11 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.46.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdacb41e6a96a052c6cb63a144f24900236121c6f63f4f8219fef5977ecb0c25" +checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" dependencies = [ - "windows-targets 0.42.2", + "windows-targets 0.48.0", ] [[package]] @@ -2597,9 +3212,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.4.1" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae8970b36c66498d8ff1d66685dc86b91b29db0c7739899012f63a63814b4b28" +checksum = "5617da7e1f97bf363947d767b91aaf3c2bbc19db7fda9c65af1278713d58e0a2" dependencies = [ "memchr", ] @@ -2652,9 +3267,9 @@ dependencies = [ [[package]] name = "zstd-safe" -version = "6.0.4+zstd.1.5.4" +version = "6.0.5+zstd.1.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7afb4b54b8910cf5447638cb54bf4e8a65cbedd783af98b98c62ffe91f185543" +checksum = "d56d9e60b4b1758206c238a10165fbcae3ca37b01744e394c463463f6529d23b" dependencies = [ "libc", "zstd-sys", @@ -2662,9 +3277,9 @@ dependencies = [ [[package]] name = "zstd-sys" -version = "2.0.7+zstd.1.5.4" +version = "2.0.8+zstd.1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94509c3ba2fe55294d752b79842c530ccfab760192521df74a081a78d2b3c7f5" +checksum = "5556e6ee25d32df2586c098bbfa278803692a20d0ab9565e049480d52707ec8c" dependencies = [ "cc", "libc", diff --git a/Cargo.toml b/Cargo.toml index 2c8680d246..c19a19dd2f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,6 +32,15 @@ reqwest-rustls-tls = ["download/reqwest-rustls-tls"] # Include in the default set to disable self-update and uninstall. no-self-update = [] +# Include an Opentelemetry sink for tracing events +otel = [ + "dep:opentelemetry-otlp", + "dep:tracing-opentelemetry", + "dep:tracing-subscriber", + "dep:opentelemetry", + "dep:tokio", +] + # Sorted by alphabetic order [dependencies] anyhow.workspace = true @@ -48,11 +57,14 @@ home = "0.5.4" lazy_static.workspace = true libc = "0.2" num_cpus = "1.15" +once_cell.workspace = true opener = "0.6.0" # Used by `curl` or `reqwest` backend although it isn't imported by our rustup : # this allows controlling the vendoring status without exposing the presence of # the download crate. openssl = { version = "0.10", optional = true } +opentelemetry = { workspace = true, optional = true } +opentelemetry-otlp = { workspace = true, optional = true } pulldown-cmark = { version = "0.9", default-features = false } rand = "0.8" regex = "1" @@ -70,7 +82,13 @@ tempfile.workspace = true term = "=0.5.1" thiserror.workspace = true threadpool = "1" +tokio = { workspace = true, optional = true } toml = "0.7" +tracing-opentelemetry = { workspace = true, optional = true } +tracing-subscriber = { workspace = true, optional = true, features = [ + "env-filter", +] } +tracing.workspace = true url.workspace = true wait-timeout = "0.2" xz2 = "0.1.3" @@ -117,7 +135,9 @@ version = "0.3" [dev-dependencies] enum-map = "2.5.0" -once_cell = "1.17.1" +once_cell.workspace = true +rustup-macros.workspace = true +tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } trycmd = "0.14.13" walkdir = "2" @@ -126,13 +146,21 @@ lazy_static = "1" regex = "1" [workspace] -members = ["download"] +members = ["download", "rustup-macros"] [workspace.dependencies] anyhow = "1.0.69" lazy_static = "1" +once_cell = "1.17.1" +opentelemetry = { version = "0.18.0", features = ["rt-tokio"] } +opentelemetry-otlp = { version = "0.11.0" } +rustup-macros = { path = "rustup-macros" } tempfile = "3.5" thiserror = "1.0" +tokio = { version = "1.26.0", default-features = false } +tracing = "0.1" +tracing-opentelemetry = { version = "0.18.0" } +tracing-subscriber = "0.3.16" url = "2.3" [lib] diff --git a/download/Cargo.toml b/download/Cargo.toml index 024d37e4d8..f1b7c97dad 100644 --- a/download/Cargo.toml +++ b/download/Cargo.toml @@ -17,14 +17,21 @@ reqwest-rustls-tls = ["reqwest/rustls-tls-native-roots"] [dependencies] anyhow.workspace = true -curl = {version = "0.4.44", optional = true} -env_proxy = {version = "0.4.1", optional = true} -lazy_static = {workspace=true, optional = true} -reqwest = {version = "0.11", default-features = false, features = ["blocking", "gzip", "socks"], optional = true} +curl = { version = "0.4.44", optional = true } +env_proxy = { version = "0.4.1", optional = true } +lazy_static = { workspace = true, optional = true } +reqwest = { version = "0.11", default-features = false, features = [ + "blocking", + "gzip", + "socks", +], optional = true } thiserror.workspace = true url.workspace = true [dev-dependencies] -hyper = {version = "0.14", default-features = false, features = ["tcp", "server"]} +hyper = { version = "0.14", default-features = false, features = [ + "tcp", + "server", +] } tempfile.workspace = true -tokio = {version = "1", default-features = false, features = ["sync"]} +tokio = { workspace = true, default-features = false, features = ["sync"] } diff --git a/rustup-macros/Cargo.toml b/rustup-macros/Cargo.toml new file mode 100644 index 0000000000..45c8efdce7 --- /dev/null +++ b/rustup-macros/Cargo.toml @@ -0,0 +1,15 @@ +[package] +edition = "2021" +name = "rustup-macros" +publish = false +version = "0.1.0" + +[lib] +proc-macro = true + +[dependencies] +proc-macro2 = "1.0.51" +quote = "1.0.23" +regex = "1.7.1" +sha2 = "0.10.6" +syn = { version = "2.0.13", features = ["full"] } diff --git a/rustup-macros/src/lib.rs b/rustup-macros/src/lib.rs new file mode 100644 index 0000000000..247f480c98 --- /dev/null +++ b/rustup-macros/src/lib.rs @@ -0,0 +1,147 @@ +//! Procedural macros for `rustup`. + +use ::quote::quote; +use proc_macro2::TokenStream; +use quote::format_ident; +use syn::{parse_macro_input, parse_quote, Block, Expr, ItemFn, LitStr}; + +/// Custom wrapper macro around `#[test]` and `#[tokio::test]`. +/// +/// Calls `rustup::test::before_test()` before the test body, and +/// `rustup::test::after_test()` after, even in the event of an unwinding panic. +/// For async functions calls the async variants of these functions. +#[proc_macro_attribute] +pub fn integration_test( + args: proc_macro::TokenStream, + input: proc_macro::TokenStream, +) -> proc_macro::TokenStream { + let mut path: Option = None; + if !args.is_empty() { + let test_parser = syn::meta::parser(|meta| { + if meta.path.is_ident("mod_path") { + path = Some(meta.value()?.parse()?); + Ok(()) + } else { + Err(meta.error("unsupported test property")) + } + }); + + parse_macro_input!(args with test_parser); + } + let input = parse_macro_input!(input); + test_inner( + path.map(|s| s.value()).unwrap_or("::rustup::test".into()), + Clone::clone(&input), + ) + .unwrap_or_else(|err| { + let err = err.to_compile_error(); + quote! { #err #input } + }) + .into() +} + +/// Custom wrapper macro around `#[test]` and `#[tokio::test]` for unit tests. +/// +/// Calls `rustup::test::before_test()` before the test body, and +/// `rustup::test::after_test()` after, even in the event of an unwinding panic. +/// For async functions calls the async variants of these functions. +#[proc_macro_attribute] +pub fn unit_test( + args: proc_macro::TokenStream, + input: proc_macro::TokenStream, +) -> proc_macro::TokenStream { + let mut path: Option = None; + + if !args.is_empty() { + let test_parser = syn::meta::parser(|meta| { + if meta.path.is_ident("mod_path") { + path = Some(meta.value()?.parse()?); + Ok(()) + } else { + Err(meta.error("unsupported test property")) + } + }); + + parse_macro_input!(args with test_parser); + } + + let input = parse_macro_input!(input); + + test_inner( + path.map(|s| s.value()).unwrap_or("crate::test".into()), + Clone::clone(&input), + ) + .unwrap_or_else(|err| { + let err = err.to_compile_error(); + quote! { #err #input } + }) + .into() +} + +fn test_inner(mod_path: String, mut input: ItemFn) -> syn::Result { + if input.sig.asyncness.is_some() { + let before_ident = format_ident!("{}::before_test_async", mod_path); + let after_ident = format_ident!("{}::after_test_async", mod_path); + + let inner = input.block; + let name = input.sig.ident.clone(); + let new_block: Block = parse_quote! { + { + #before_ident().await; + // Define a function with same name we can instrument inside the + // tracing enablement logic. + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] + async fn #name() { #inner } + // Thunk through a new thread to permit catching the panic + // without grabbing the entire state machine defined by the + // outer test function. + let result = ::std::panic::catch_unwind(||{ + let handle = tokio::runtime::Handle::current().clone(); + ::std::thread::spawn(move || handle.block_on(#name())).join().unwrap() + }); + #after_ident().await; + match result { + Ok(result) => result, + Err(err) => ::std::panic::resume_unwind(err) + } + } + }; + + input.block = Box::new(new_block); + + Ok(quote! { + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] + #[::tokio::test(flavor = "multi_thread", worker_threads = 1)] + #input + }) + } else { + let before_ident = format!("{}::before_test", mod_path); + let before_ident = syn::parse_str::(&before_ident)?; + let after_ident = format!("{}::after_test", mod_path); + let after_ident = syn::parse_str::(&after_ident)?; + + let inner = input.block; + let name = input.sig.ident.clone(); + let new_block: Block = parse_quote! { + { + #before_ident(); + // Define a function with same name we can instrument inside the + // tracing enablement logic. + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] + fn #name() { #inner } + let result = ::std::panic::catch_unwind(#name); + #after_ident(); + match result { + Ok(result) => result, + Err(err) => ::std::panic::resume_unwind(err) + } + } + }; + + input.block = Box::new(new_block); + Ok(quote! { + #[::std::prelude::v1::test] + #input + }) + } +} diff --git a/src/bin/rustup-init.rs b/src/bin/rustup-init.rs index 35ed9866fd..e6bbe59574 100644 --- a/src/bin/rustup-init.rs +++ b/src/bin/rustup-init.rs @@ -30,7 +30,7 @@ use rustup::utils::utils; fn main() { let process = OSProcess::default(); - with(Box::new(process), || match run_rustup() { + with(Box::new(process), || match maybe_trace_rustup() { Err(e) => { common::report_error(&e); std::process::exit(1); @@ -39,6 +39,65 @@ fn main() { }); } +fn maybe_trace_rustup() -> Result { + #[cfg(not(feature = "otel"))] + { + run_rustup() + } + #[cfg(feature = "otel")] + { + use std::time::Duration; + + use opentelemetry::sdk::{ + trace::{self, Sampler}, + Resource, + }; + use opentelemetry::KeyValue; + use opentelemetry::{global, sdk::propagation::TraceContextPropagator}; + use opentelemetry_otlp::WithExportConfig; + use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry}; + + // Background submission requires a runtime, and since we're probably + // going to want async eventually, we just use tokio. + let threaded_rt = tokio::runtime::Runtime::new()?; + + let result = threaded_rt.block_on(async { + global::set_text_map_propagator(TraceContextPropagator::new()); + let tracer = opentelemetry_otlp::new_pipeline() + .tracing() + .with_exporter( + opentelemetry_otlp::new_exporter() + .tonic() + .with_timeout(Duration::from_secs(3)), + ) + .with_trace_config( + trace::config() + .with_sampler(Sampler::AlwaysOn) + .with_resource(Resource::new(vec![KeyValue::new( + "service.name", + "rustup", + )])), + ) + .install_batch(opentelemetry::runtime::Tokio)?; + let env_filter = EnvFilter::try_from_default_env().unwrap_or(EnvFilter::new("INFO")); + let telemetry = tracing_opentelemetry::layer().with_tracer(tracer); + let subscriber = Registry::default().with(env_filter).with(telemetry); + tracing::subscriber::set_global_default(subscriber)?; + let result = run_rustup(); + // We're tracing, so block until all spans are exported. + opentelemetry::global::shutdown_tracer_provider(); + result + }); + // default runtime behaviour is to block until nothing is running; + // instead we supply a timeout, as we're either already errored and are + // reporting back without care for lost threads etc... or everything + // completed. + threaded_rt.shutdown_timeout(Duration::from_millis(5)); + result + } +} + +#[cfg_attr(feature = "otel", tracing::instrument)] fn run_rustup() -> Result { if let Ok(dir) = process().var("RUSTUP_TRACE_DIR") { open_trace_file!(dir)?; @@ -50,6 +109,7 @@ fn run_rustup() -> Result { result } +#[cfg_attr(feature = "otel", tracing::instrument(err))] fn run_rustup_inner() -> Result { // Guard against infinite proxy recursion. This mostly happens due to // bugs in rustup. diff --git a/src/cli/common.rs b/src/cli/common.rs index 9a6a68d4a0..122c0a0f74 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -156,6 +156,7 @@ impl NotifyOnConsole { } } +#[cfg_attr(feature = "otel", tracing::instrument)] pub(crate) fn set_globals(verbose: bool, quiet: bool) -> Result { use std::cell::RefCell; diff --git a/src/cli/download_tracker.rs b/src/cli/download_tracker.rs index c14fd5bfec..7db1373c7a 100644 --- a/src/cli/download_tracker.rs +++ b/src/cli/download_tracker.rs @@ -268,7 +268,10 @@ fn format_dhms(sec: u64) -> (u64, u8, u8, u8) { #[cfg(test)] mod tests { + use rustup_macros::unit_test as test; + use super::format_dhms; + #[test] fn download_tracker_format_dhms_test() { assert_eq!(format_dhms(2), (0, 0, 0, 2)); diff --git a/src/cli/proxy_mode.rs b/src/cli/proxy_mode.rs index 7b62934c31..52813f4f01 100644 --- a/src/cli/proxy_mode.rs +++ b/src/cli/proxy_mode.rs @@ -1,5 +1,4 @@ use std::ffi::OsString; -use std::process; use anyhow::Result; @@ -10,6 +9,7 @@ use crate::command::run_command_for_dir; use crate::utils::utils::{self, ExitCode}; use crate::Cfg; +#[cfg_attr(feature = "otel", tracing::instrument)] pub fn main(arg0: &str) -> Result { self_update::cleanup_self_updater()?; @@ -38,9 +38,10 @@ pub fn main(arg0: &str) -> Result { direct_proxy(&cfg, arg0, toolchain, &cmd_args)? }; - process::exit(c) + Ok(ExitCode(c)) } +#[cfg_attr(feature = "otel", tracing::instrument(skip(cfg)))] fn direct_proxy( cfg: &Cfg, arg0: &str, diff --git a/src/cli/rustup_mode.rs b/src/cli/rustup_mode.rs index 09d137965d..8960d9de29 100644 --- a/src/cli/rustup_mode.rs +++ b/src/cli/rustup_mode.rs @@ -68,6 +68,7 @@ where callee(cfg, matches) } +#[cfg_attr(feature = "otel", tracing::instrument(fields(args = format!("{:?}", process().args_os().collect::>()))))] pub fn main() -> Result { self_update::cleanup_self_updater()?; @@ -82,6 +83,7 @@ pub fn main() -> Result { write!(process().stdout().lock(), "{err}")?; info!("This is the version for the rustup toolchain manager, not the rustc compiler."); + #[cfg_attr(feature = "otel", tracing::instrument)] fn rustc_version() -> std::result::Result> { let cfg = &mut common::set_globals(false, true)?; let cwd = std::env::current_dir()?; @@ -1105,6 +1107,7 @@ fn which(cfg: &Cfg, m: &ArgMatches) -> Result { Ok(utils::ExitCode(0)) } +#[cfg_attr(feature = "otel", tracing::instrument(skip_all))] fn show(cfg: &Cfg, m: &ArgMatches) -> Result { let verbose = m.get_flag("verbose"); @@ -1266,6 +1269,7 @@ fn show(cfg: &Cfg, m: &ArgMatches) -> Result { Ok(utils::ExitCode(0)) } +#[cfg_attr(feature = "otel", tracing::instrument(skip_all))] fn show_active_toolchain(cfg: &Cfg, m: &ArgMatches) -> Result { let verbose = m.get_flag("verbose"); let cwd = utils::current_dir()?; @@ -1293,6 +1297,7 @@ fn show_active_toolchain(cfg: &Cfg, m: &ArgMatches) -> Result { Ok(utils::ExitCode(0)) } +#[cfg_attr(feature = "otel", tracing::instrument(skip_all))] fn show_rustup_home(cfg: &Cfg) -> Result { writeln!(process().stdout(), "{}", cfg.rustup_dir.display())?; Ok(utils::ExitCode(0)) @@ -1665,6 +1670,7 @@ fn set_auto_self_update(cfg: &mut Cfg, m: &ArgMatches) -> Result Result { writeln!(process().stdout(), "{}", cfg.get_profile()?)?; Ok(utils::ExitCode(0)) diff --git a/src/cli/self_update.rs b/src/cli/self_update.rs index 267f26c5e0..3a97ae4c01 100644 --- a/src/cli/self_update.rs +++ b/src/cli/self_update.rs @@ -1210,6 +1210,7 @@ pub(crate) fn check_rustup_update() -> Result<()> { Ok(()) } +#[cfg_attr(feature = "otel", tracing::instrument)] pub(crate) fn cleanup_self_updater() -> Result<()> { let cargo_home = utils::cargo_home()?; let setup = cargo_home.join(format!("bin/rustup-init{EXE_SUFFIX}")); @@ -1235,6 +1236,8 @@ mod tests { use anyhow::Result; + use rustup_macros::unit_test as test; + use crate::cli::common; use crate::dist::dist::ToolchainDesc; use crate::test::{test_dir, with_rustup_home, Env}; diff --git a/src/cli/self_update/windows.rs b/src/cli/self_update/windows.rs index fb7943cbb7..c1e0702e5f 100644 --- a/src/cli/self_update/windows.rs +++ b/src/cli/self_update/windows.rs @@ -259,6 +259,7 @@ fn has_windows_sdk_libs() -> bool { } /// Run by rustup-gc-$num.exe to delete CARGO_HOME +#[cfg_attr(feature = "otel", tracing::instrument)] pub fn complete_windows_uninstall() -> Result { use std::process::Stdio; @@ -703,6 +704,8 @@ mod tests { use winreg::enums::{RegType, HKEY_CURRENT_USER, KEY_READ, KEY_WRITE}; use winreg::{RegKey, RegValue}; + use rustup_macros::unit_test as test; + use crate::currentprocess; use crate::test::with_saved_path; diff --git a/src/cli/setup_mode.rs b/src/cli/setup_mode.rs index 6dd04ec2d4..4f8aec8cb6 100644 --- a/src/cli/setup_mode.rs +++ b/src/cli/setup_mode.rs @@ -7,6 +7,7 @@ use crate::dist::dist::Profile; use crate::process; use crate::utils::utils; +#[cfg_attr(feature = "otel", tracing::instrument)] pub fn main() -> Result { let args: Vec<_> = process().args().collect(); let arg1 = args.get(1).map(|a| &**a); diff --git a/src/config.rs b/src/config.rs index 240dd59c56..acb77d4b5a 100644 --- a/src/config.rs +++ b/src/config.rs @@ -387,6 +387,7 @@ impl Cfg { Ok(toolchain.binary_file(binary)) } + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] pub(crate) fn upgrade_data(&self) -> Result<()> { let current_version = self.settings_file.with(|s| Ok(s.version.clone()))?; @@ -623,6 +624,7 @@ impl Cfg { } } + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] pub(crate) fn find_or_install_override_toolchain_or_default( &self, path: &Path, @@ -731,6 +733,7 @@ impl Cfg { user_opt } + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] pub(crate) fn list_toolchains(&self) -> Result> { if utils::is_directory(&self.toolchains_dir) { let mut toolchains: Vec<_> = utils::read_dir("toolchains", &self.toolchains_dir)? @@ -784,6 +787,7 @@ impl Cfg { Ok(channels.collect()) } + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] pub(crate) fn check_metadata_version(&self) -> Result<()> { utils::assert_is_directory(&self.rustup_dir)?; @@ -887,6 +891,7 @@ impl Cfg { }) } + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] pub(crate) fn get_default_host_triple(&self) -> Result { Ok(self .settings_file @@ -926,6 +931,8 @@ enum ParseMode { #[cfg(test)] mod tests { + use rustup_macros::unit_test as test; + use super::*; #[test] diff --git a/src/currentprocess.rs b/src/currentprocess.rs index f9e579ec9d..1a0bc54e7c 100644 --- a/src/currentprocess.rs +++ b/src/currentprocess.rs @@ -268,6 +268,8 @@ mod tests { use std::collections::HashMap; use std::env; + use rustup_macros::unit_test as test; + use super::{process, with, ProcessSource, TestProcess}; #[test] diff --git a/src/diskio/test.rs b/src/diskio/test.rs index 242e26c38a..45bd407e55 100644 --- a/src/diskio/test.rs +++ b/src/diskio/test.rs @@ -2,6 +2,8 @@ use std::collections::HashMap; use anyhow::Result; +use rustup_macros::unit_test as test; + use crate::test::test_dir; use super::{get_executor, Executor, Item, Kind}; @@ -156,21 +158,21 @@ fn test_complete_file(io_threads: &str) -> Result<()> { } #[test] -fn test_incremental_file_immediate() -> Result<()> { - test_incremental_file("1") +fn test_incremental_file_immediate() { + test_incremental_file("1").unwrap() } #[test] -fn test_incremental_file_threaded() -> Result<()> { - test_incremental_file("2") +fn test_incremental_file_threaded() { + test_incremental_file("2").unwrap() } #[test] -fn test_complete_file_immediate() -> Result<()> { - test_complete_file("1") +fn test_complete_file_immediate() { + test_complete_file("1").unwrap() } #[test] -fn test_complete_file_threaded() -> Result<()> { - test_complete_file("2") +fn test_complete_file_threaded() { + test_complete_file("2").unwrap() } diff --git a/src/dist/dist.rs b/src/dist/dist.rs index 480e61595e..cd6f8e6acf 100644 --- a/src/dist/dist.rs +++ b/src/dist/dist.rs @@ -650,6 +650,7 @@ pub(crate) fn valid_profile_names() -> String { // an upgrade then all the existing components will be upgraded. // // Returns the manifest's hash if anything changed. +#[cfg_attr(feature = "otel", tracing::instrument(skip_all))] pub(crate) fn update_from_dist( download: DownloadCfg<'_>, update_hash: Option<&Path>, @@ -664,7 +665,6 @@ pub(crate) fn update_from_dist( ) -> Result> { let fresh_install = !prefix.path().exists(); let hash_exists = update_hash.map(Path::exists).unwrap_or(false); - // fresh_install means the toolchain isn't present, but hash_exists means there is a stray hash file if fresh_install && hash_exists { // It's ok to unwrap, because hash have to exist at this point @@ -1077,6 +1077,8 @@ fn date_from_manifest_date(date_str: &str) -> Option { #[cfg(test)] mod tests { + use rustup_macros::unit_test as test; + use super::*; #[test] diff --git a/src/dist/manifestation.rs b/src/dist/manifestation.rs index a58b5bae86..48ad384211 100644 --- a/src/dist/manifestation.rs +++ b/src/dist/manifestation.rs @@ -359,6 +359,7 @@ impl Manifestation { } } + #[cfg_attr(feature = "otel", tracing::instrument)] pub fn load_manifest(&self) -> Result> { let prefix = self.installation.prefix(); let old_manifest_path = prefix.manifest_file(DIST_MANIFEST); diff --git a/src/dist/triple.rs b/src/dist/triple.rs index a51e95d303..ad27adb146 100644 --- a/src/dist/triple.rs +++ b/src/dist/triple.rs @@ -97,7 +97,10 @@ impl PartialTargetTriple { #[cfg(test)] mod test { + use rustup_macros::unit_test as test; + use super::*; + #[test] fn test_partial_target_triple_new() { let success_cases = vec![ diff --git a/src/env_var.rs b/src/env_var.rs index 50c66c059d..7d28f054ba 100644 --- a/src/env_var.rs +++ b/src/env_var.rs @@ -38,13 +38,15 @@ pub(crate) fn inc(name: &str, cmd: &mut Command) { #[cfg(test)] mod tests { + use std::collections::HashMap; + use std::ffi::{OsStr, OsString}; + + use rustup_macros::unit_test as test; + use super::*; use crate::currentprocess; use crate::test::{with_saved_path, Env}; - use std::collections::HashMap; - use std::ffi::{OsStr, OsString}; - #[test] fn prepend_unique_path() { let mut vars = HashMap::new(); diff --git a/src/lib.rs b/src/lib.rs index b4e88fa34d..ffe0d8da51 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -100,6 +100,8 @@ pub mod utils; #[cfg(test)] mod tests { + use rustup_macros::unit_test as test; + use crate::{is_proxyable_tools, DUP_TOOLS, TOOLS}; #[test] diff --git a/src/test.rs b/src/test.rs index cbd6fe6513..6914a3ff7c 100644 --- a/src/test.rs +++ b/src/test.rs @@ -169,7 +169,7 @@ macro_rules! for_host { }; } -#[derive(Clone)] +#[derive(Clone, Debug)] /// The smallest form of test isolation: an isolated RUSTUP_HOME, for codepaths /// that read and write config files but do not invoke processes, download data /// etc. @@ -217,3 +217,91 @@ where let rustup_home = RustupHome::new_in(test_dir)?; f(&rustup_home) } + +#[cfg(feature = "otel")] +use once_cell::sync::Lazy; +#[cfg(feature = "otel")] +use tokio; + +/// A tokio runtime for the sync tests, permitting the use of tracing. This is +/// never shutdown, instead it is just dropped at end of process. +#[cfg(feature = "otel")] +static TRACE_RUNTIME: Lazy = + Lazy::new(|| tokio::runtime::Runtime::new().unwrap()); +/// A tracer for the tests. +#[cfg(feature = "otel")] +static TRACER: Lazy = Lazy::new(|| { + use std::time::Duration; + + use opentelemetry::KeyValue; + use opentelemetry::{ + global, + sdk::{ + propagation::TraceContextPropagator, + trace::{self, Sampler}, + Resource, + }, + }; + use opentelemetry_otlp::WithExportConfig; + use tokio::runtime::Handle; + use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry}; + + // Use the current runtime, or the sync test runtime otherwise. + let handle = match Handle::try_current() { + Ok(handle) => handle, + Err(_) => TRACE_RUNTIME.handle().clone(), + }; + let _guard = handle.enter(); + + let tracer = opentelemetry_otlp::new_pipeline() + .tracing() + .with_exporter( + opentelemetry_otlp::new_exporter() + .tonic() + .with_timeout(Duration::from_secs(3)), + ) + .with_trace_config( + trace::config() + .with_sampler(Sampler::AlwaysOn) + .with_resource(Resource::new(vec![KeyValue::new("service.name", "rustup")])), + ) + .install_batch(opentelemetry::runtime::Tokio) + .unwrap(); + + global::set_text_map_propagator(TraceContextPropagator::new()); + let env_filter = EnvFilter::try_from_default_env().unwrap_or(EnvFilter::new("INFO")); + let telemetry = tracing_opentelemetry::layer().with_tracer(tracer.clone()); + let subscriber = Registry::default().with(env_filter).with(telemetry); + tracing::subscriber::set_global_default(subscriber).unwrap(); + tracer +}); + +pub fn before_test() { + #[cfg(feature = "otel")] + { + Lazy::force(&TRACER); + } +} + +pub async fn before_test_async() { + #[cfg(feature = "otel")] + { + Lazy::force(&TRACER); + } +} + +pub fn after_test() { + #[cfg(feature = "otel")] + { + let handle = TRACE_RUNTIME.handle(); + let _guard = handle.enter(); + TRACER.provider().map(|p| p.force_flush()); + } +} + +pub async fn after_test_async() { + #[cfg(feature = "otel")] + { + TRACER.provider().map(|p| p.force_flush()); + } +} diff --git a/src/toolchain.rs b/src/toolchain.rs index 99759ade1d..b88eb4cf6c 100644 --- a/src/toolchain.rs +++ b/src/toolchain.rs @@ -1,4 +1,3 @@ -use std::env; use std::env::consts::EXE_SUFFIX; use std::ffi::OsStr; use std::ffi::OsString; @@ -7,6 +6,7 @@ use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::str::FromStr; use std::time::Duration; +use std::{env, fmt::Debug}; use anyhow::{anyhow, bail, Context, Result}; use thiserror::Error as ThisError; @@ -240,6 +240,7 @@ impl<'a> Toolchain<'a> { path } // Distributable and Custom. Installed only. + #[cfg_attr(feature = "otel", tracing::instrument)] pub fn rustc_version(&self) -> String { if let Ok(installed) = self.as_installed_common() { let rustc_path = self.binary_file("rustc"); @@ -521,6 +522,7 @@ impl<'a> InstalledToolchain<'a> for CustomToolchain<'a> { } /// Newtype to facilitate splitting out distributable-toolchain specific code. +#[derive(Debug)] pub struct DistributableToolchain<'a>(&'a Toolchain<'a>); impl<'a> DistributableToolchain<'a> { @@ -803,6 +805,7 @@ impl<'a> DistributableToolchain<'a> { } } + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] pub(crate) fn get_toolchain_desc_with_manifest( &self, ) -> Result> { @@ -824,6 +827,7 @@ impl<'a> DistributableToolchain<'a> { })) } + #[cfg_attr(feature = "otel", tracing::instrument)] pub fn list_components(&self) -> Result> { if let Some(toolchain) = self.get_toolchain_desc_with_manifest()? { toolchain.list_components() diff --git a/src/utils/units.rs b/src/utils/units.rs index 365c99d7c5..7dbf64a632 100644 --- a/src/utils/units.rs +++ b/src/utils/units.rs @@ -77,6 +77,8 @@ impl Display for Size { #[cfg(test)] mod tests { + use rustup_macros::unit_test as test; + #[test] fn unit_formatter_test() { use crate::utils::units::{Size, Unit, UnitMode}; diff --git a/src/utils/utils.rs b/src/utils/utils.rs index 0d065aed04..04ab85117a 100644 --- a/src/utils/utils.rs +++ b/src/utils/utils.rs @@ -741,6 +741,8 @@ pub(crate) fn home_dir_from_passwd() -> Option { #[cfg(test)] mod tests { + use rustup_macros::unit_test as test; + use super::*; #[test] diff --git a/tests/mock/clitools.rs b/tests/mock/clitools.rs index 6d4a0d5fe1..64aa9dfaf9 100644 --- a/tests/mock/clitools.rs +++ b/tests/mock/clitools.rs @@ -32,6 +32,7 @@ use crate::mock::topical_doc_data; use crate::mock::{MockComponentBuilder, MockFile, MockInstallerBuilder}; /// The configuration used by the tests in this module +#[derive(Debug)] pub struct Config { /// Where we put the rustup / rustc / cargo bins pub exedir: PathBuf, @@ -678,6 +679,7 @@ impl Config { output } + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] pub(crate) fn run_inprocess(&self, name: &str, args: I, env: &[(&str, &str)]) -> Output where I: IntoIterator, @@ -957,6 +959,7 @@ impl Release { } } + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] fn link(&self, path: &Path) { // Also create the manifests for releases by version let _ = hard_link( @@ -1009,6 +1012,7 @@ impl Release { } // Creates a mock dist server populated with some test data +#[cfg_attr(feature = "otel", tracing::instrument(skip_all))] fn create_mock_dist_server(path: &Path, s: Scenario) { let chans = match s { Scenario::None => return, diff --git a/tests/mock/dist.rs b/tests/mock/dist.rs index 8d1aad2b8c..1be0807a8f 100644 --- a/tests/mock/dist.rs +++ b/tests/mock/dist.rs @@ -65,6 +65,7 @@ pub const MOCK_MANIFEST_VERSION: &str = "2"; // A mock Rust v2 distribution server. Create it and and run `write` // to write its structure to a directory. +#[derive(Debug)] pub struct MockDistServer { // The local path to the dist server root pub path: PathBuf, @@ -72,6 +73,7 @@ pub struct MockDistServer { } // A Rust distribution channel +#[derive(Debug)] pub struct MockChannel { // e.g. "nightly" pub name: String, @@ -121,6 +123,7 @@ pub enum ManifestVersion { } impl MockDistServer { + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] pub fn write(&self, vs: &[ManifestVersion], enable_xz: bool, enable_zst: bool) { fs::create_dir_all(&self.path).unwrap(); @@ -139,6 +142,7 @@ impl MockDistServer { } } + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] fn build_package( &self, channel: &MockChannel, @@ -179,6 +183,7 @@ impl MockDistServer { } // Returns the hash of the tarball + #[cfg_attr(feature = "otel", tracing::instrument(skip_all, fields(format=%format)))] fn build_target_package( &self, channel: &MockChannel, @@ -267,6 +272,7 @@ impl MockDistServer { } // The v1 manifest is just the directory listing of the rust tarballs + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] fn write_manifest_v1(&self, channel: &MockChannel) { let mut buf = String::new(); let package = channel.packages.iter().find(|p| p.name == "rust").unwrap(); @@ -295,6 +301,7 @@ impl MockDistServer { hard_link(&hash_path, archive_hash_path).unwrap(); } + #[cfg_attr(feature = "otel", tracing::instrument(skip_all))] fn write_manifest_v2( &self, channel: &MockChannel, diff --git a/tests/suite/cli_exact.rs b/tests/suite/cli_exact.rs index d650ab4932..21a6d8a1d2 100644 --- a/tests/suite/cli_exact.rs +++ b/tests/suite/cli_exact.rs @@ -1,9 +1,11 @@ //! Yet more cli test cases. These are testing that the output //! is exactly as expected. -use crate::mock::clitools::{self, set_current_dist_date, with_update_server, Config, Scenario}; use rustup::for_host; use rustup::test::this_host_triple; +use rustup_macros::integration_test as test; + +use crate::mock::clitools::{self, set_current_dist_date, with_update_server, Config, Scenario}; fn test(f: &dyn Fn(&mut Config)) { clitools::test(Scenario::None, f); diff --git a/tests/suite/cli_inst_interactive.rs b/tests/suite/cli_inst_interactive.rs index 0c00ce255a..4d73cea9bf 100644 --- a/tests/suite/cli_inst_interactive.rs +++ b/tests/suite/cli_inst_interactive.rs @@ -8,6 +8,7 @@ use rustup::for_host; use rustup::test::this_host_triple; use rustup::test::with_saved_path; use rustup::utils::raw; +use rustup_macros::integration_test as test; use crate::mock::clitools::{self, set_current_dist_date, Config, SanitizedOutput, Scenario}; diff --git a/tests/suite/cli_misc.rs b/tests/suite/cli_misc.rs index b793b2ebfe..1b0f92953e 100644 --- a/tests/suite/cli_misc.rs +++ b/tests/suite/cli_misc.rs @@ -7,6 +7,7 @@ use std::{env::consts::EXE_SUFFIX, path::Path}; use rustup::for_host; use rustup::test::this_host_triple; use rustup::utils::utils; +use rustup_macros::integration_test as test; use crate::mock::clitools::{self, set_current_dist_date, Config, Scenario}; diff --git a/tests/suite/cli_paths.rs b/tests/suite/cli_paths.rs index bf645f802d..7c155dcd5a 100644 --- a/tests/suite/cli_paths.rs +++ b/tests/suite/cli_paths.rs @@ -12,6 +12,7 @@ mod unix { use std::path::PathBuf; use rustup::utils::raw; + use rustup_macros::integration_test as test; use super::INIT_NONE; use crate::mock::clitools::{self, Scenario}; @@ -351,6 +352,7 @@ export PATH="$HOME/apple/bin" #[cfg(windows)] mod windows { use rustup::test::{get_path, with_saved_path}; + use rustup_macros::integration_test as test; use super::INIT_NONE; use crate::mock::clitools::{self, Scenario}; diff --git a/tests/suite/cli_rustup.rs b/tests/suite/cli_rustup.rs index 43efd9dd39..8b8588e90c 100644 --- a/tests/suite/cli_rustup.rs +++ b/tests/suite/cli_rustup.rs @@ -7,6 +7,7 @@ use std::path::{PathBuf, MAIN_SEPARATOR}; use rustup::for_host; use rustup::test::this_host_triple; use rustup::utils::raw; +use rustup_macros::integration_test as test; use crate::mock::{ self, diff --git a/tests/suite/cli_self_upd.rs b/tests/suite/cli_self_upd.rs index d20c502c98..0ad0be95f8 100644 --- a/tests/suite/cli_self_upd.rs +++ b/tests/suite/cli_self_upd.rs @@ -11,6 +11,7 @@ use remove_dir_all::remove_dir_all; use rustup::test::{this_host_triple, with_saved_path}; use rustup::utils::{raw, utils}; use rustup::{for_host, Notification, DUP_TOOLS, TOOLS}; +use rustup_macros::integration_test as test; use crate::mock::{ clitools::{self, output_release_file, self_update_setup, Config, Scenario}, diff --git a/tests/suite/cli_ui.rs b/tests/suite/cli_ui.rs index 3349f81a33..afa8d8831a 100644 --- a/tests/suite/cli_ui.rs +++ b/tests/suite/cli_ui.rs @@ -1,5 +1,7 @@ use std::{fs, path::PathBuf}; +use rustup_macros::integration_test as test; + #[test] fn rustup_ui_doc_text_tests() { let t = trycmd::TestCases::new(); diff --git a/tests/suite/cli_v1.rs b/tests/suite/cli_v1.rs index 10b14cf967..274701fef9 100644 --- a/tests/suite/cli_v1.rs +++ b/tests/suite/cli_v1.rs @@ -4,6 +4,7 @@ use std::fs; use rustup::for_host; +use rustup_macros::integration_test as test; use crate::mock::clitools::{self, set_current_dist_date, Config, Scenario}; diff --git a/tests/suite/cli_v2.rs b/tests/suite/cli_v2.rs index ef13462882..54d2c4c3ab 100644 --- a/tests/suite/cli_v2.rs +++ b/tests/suite/cli_v2.rs @@ -7,6 +7,7 @@ use std::io::Write; use rustup::dist::dist::TargetTriple; use rustup::for_host; use rustup::test::this_host_triple; +use rustup_macros::integration_test as test; use crate::mock::clitools::{self, set_current_dist_date, Config, Scenario}; diff --git a/tests/suite/dist.rs b/tests/suite/dist.rs index 87a9db6290..d473792a85 100644 --- a/tests/suite/dist.rs +++ b/tests/suite/dist.rs @@ -24,6 +24,7 @@ use rustup::dist::Notification; use rustup::errors::RustupError; use rustup::utils::raw as utils_raw; use rustup::utils::utils; +use rustup_macros::integration_test as test; use crate::mock::dist::*; use crate::mock::{MockComponentBuilder, MockFile, MockInstallerBuilder}; diff --git a/tests/suite/dist_install.rs b/tests/suite/dist_install.rs index 9e33c0de06..c26576a8f5 100644 --- a/tests/suite/dist_install.rs +++ b/tests/suite/dist_install.rs @@ -9,6 +9,7 @@ use rustup::dist::prefix::InstallPrefix; use rustup::dist::temp; use rustup::dist::Notification; use rustup::utils::utils; +use rustup_macros::integration_test as test; use crate::mock::{MockComponentBuilder, MockFile, MockInstallerBuilder}; diff --git a/tests/suite/dist_manifest.rs b/tests/suite/dist_manifest.rs index ab8c77978a..6d4a75c2da 100644 --- a/tests/suite/dist_manifest.rs +++ b/tests/suite/dist_manifest.rs @@ -1,6 +1,7 @@ use rustup::dist::dist::TargetTriple; use rustup::dist::manifest::Manifest; use rustup::RustupError; +use rustup_macros::integration_test as test; // Example manifest from https://public.etherpad-mozilla.org/p/Rust-infra-work-week static EXAMPLE: &str = include_str!("channel-rust-nightly-example.toml"); diff --git a/tests/suite/dist_transactions.rs b/tests/suite/dist_transactions.rs index c4728513a5..b82164c598 100644 --- a/tests/suite/dist_transactions.rs +++ b/tests/suite/dist_transactions.rs @@ -1,3 +1,7 @@ +use std::fs; +use std::io::Write; +use std::path::PathBuf; + use rustup::dist::component::Transaction; use rustup::dist::dist::DEFAULT_DIST_SERVER; use rustup::dist::prefix::InstallPrefix; @@ -6,9 +10,7 @@ use rustup::dist::Notification; use rustup::utils::raw as utils_raw; use rustup::utils::utils; use rustup::RustupError; -use std::fs; -use std::io::Write; -use std::path::PathBuf; +use rustup_macros::integration_test as test; #[test] fn add_file() {