master
rs 79 lines 2.63 KB
Raw
1 //! Regeneration check for vendored protobuf files.
2 //!
3 //! This test compiles the .proto definitions under `proto/` and compares the
4 //! output against the committed files in `src/routing/proto/`.
5 //!
6 //! - Locally: if there is a diff, the test **overwrites** the committed files
7 //! and fails with instructions to re-run and commit.
8 //! - In CI (`CI` env var set): the test fails without overwriting.
9 //!
10 //! Run with: `cargo test -p netflow-plugin --test grpc_build`
11
12 use std::path::Path;
13
14 fn configure_protoc() {
15 if std::env::var_os("PROTOC").is_some() {
16 return;
17 }
18 let protoc = protoc_bin_vendored::protoc_bin_path()
19 .expect("vendored protoc not available and PROTOC not set");
20 unsafe {
21 std::env::set_var("PROTOC", protoc);
22 }
23 }
24
25 #[test]
26 fn vendored_proto_files_are_up_to_date() {
27 configure_protoc();
28
29 let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
30 let proto_root = manifest_dir.join("proto");
31 let vendored_dir = manifest_dir.join("src/routing/proto");
32
33 let proto_files = [
34 proto_root.join("net/api/net.proto"),
35 proto_root.join("route/api/route.proto"),
36 proto_root.join("cmd/ris/api/ris.proto"),
37 ];
38
39 let tmp_dir = tempfile::tempdir().expect("create temp dir");
40
41 tonic_prost_build::configure()
42 .out_dir(tmp_dir.path())
43 .compile_protos(&proto_files, &[proto_root.clone()])
44 .expect("protobuf compilation failed");
45
46 let generated_files = ["bio.net.rs", "bio.route.rs", "bio.ris.rs"];
47 let mut stale = Vec::new();
48
49 for name in &generated_files {
50 let fresh = std::fs::read_to_string(tmp_dir.path().join(name))
51 .unwrap_or_else(|e| panic!("read generated {name}: {e}"));
52 let committed_path = vendored_dir.join(name);
53 let committed = std::fs::read_to_string(&committed_path).unwrap_or_default();
54
55 if fresh != committed {
56 stale.push(*name);
57
58 if std::env::var_os("CI").is_none() {
59 std::fs::write(&committed_path, &fresh)
60 .unwrap_or_else(|e| panic!("write {}: {e}", committed_path.display()));
61 }
62 }
63 }
64
65 if !stale.is_empty() {
66 let files = stale.join(", ");
67 if std::env::var_os("CI").is_some() {
68 panic!(
69 "vendored proto files are stale: {files}\n\
70 Run `cargo test -p netflow-plugin --test grpc_build` locally and commit the updated files."
71 );
72 } else {
73 panic!(
74 "vendored proto files were stale and have been updated: {files}\n\
75 Please re-run tests and commit the changes."
76 );
77 }
78 }
79 }