Skip to content

Commit a184f0d

Browse files
authored
fix(sidekick/rust): Ensure detailed-tracing-attributes flag is fully propagated (#2438)
This commit fixes the propagation of the `detailed-tracing-attributes` flag to all necessary annotation structs and updates the templates to correctly utilize the flag. See #2435 and #2252 For googleapis/google-cloud-rust#3239 Specifically: - Adds `DetailedTracingAttributes` field to `modelAnnotations` and `serviceAnnotations` in `annotate.go` to make the flag accessible in `lib.rs.mustache` and service-level sections of `transport.rs.mustache`. - Updates `annotateModel` and `annotateService` to populate the new fields. - Adds comprehensive unit tests in `annotate_test.go` to verify the `DetailedTracingAttributes` flag is correctly set across `modelAnnotations`, `serviceAnnotations`, `methodAnnotation`, and `pathBindingAnnotation` based on the codec options. - Modifies `lib.rs.mustache` to initialize the static `INSTRUMENTATION_CLIENT_INFO` using `std::sync::LazyLock` to accommodate the non-const `default()` function. - Updates `transport.rs.mustache` to correctly dereference the `LazyLock` when calling `with_instrumentation` (i.e., `&*crate::info::INSTRUMENTATION_CLIENT_INFO`). These changes ensure that the conditional code blocks in both `lib.rs.mustache` and `transport.rs.mustache` related to detailed tracing are generated correctly based on the `detailed-tracing-attributes` flag. Tested: - Ran `go test -race ./...` in the librarian repository to ensure all unit tests pass, including new tests for flag propagation in annotations. - Manually regenerated the `google-cloud-showcase-v1beta1` client in a local `google-cloud-rust` clone using the modified librarian: 1. With `--codec-option=detailed-tracing-attributes=true`: - Verified `src/generated/showcase/src/lib.rs` contains the `INSTRUMENTATION_CLIENT_INFO` static (using `LazyLock`). - Verified `src/generated/showcase/src/transport.rs` includes `.with_instrumentation(&*crate::info::INSTRUMENTATION_CLIENT_INFO)` calls within the `if tracing_is_enabled` blocks in the `new` methods. - Confirmed the crate builds and tests pass: `cargo build -p google-cloud-showcase-v1beta1` `cargo test -p google-cloud-showcase-v1beta1` 2. With the flag off (default): - Verified the above tracing-specific code is absent. 3. By setting `detailed-tracing-attributes = "true"` in `src/generated/showcase/.sidekick.toml` and running refresh without the codec option, confirming the config file is also respected.
1 parent c1a4ced commit a184f0d

File tree

2 files changed

+154
-11
lines changed

2 files changed

+154
-11
lines changed

internal/sidekick/internal/rust/annotate.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ type modelAnnotations struct {
5757
Incomplete bool
5858
// If true, the generator will produce reference documentation samples for message fields setters.
5959
GenerateSetterSamples bool
60+
// If true, the generated code includes detailed tracing attributes on HTTP
61+
// requests.
62+
DetailedTracingAttributes bool
6063
}
6164

6265
// IsWktCrate returns true when bootstrapping the well-known types crate the templates add some
@@ -107,6 +110,9 @@ type serviceAnnotations struct {
107110
HasVeneer bool
108111
// If true, the service has a method we cannot wrap (yet).
109112
Incomplete bool
113+
// If true, the generated code includes detailed tracing attributes on HTTP
114+
// requests.
115+
DetailedTracingAttributes bool
110116
}
111117

112118
// HasBindingSubstitutions returns true if the method has binding substitutions.
@@ -554,7 +560,8 @@ func annotateModel(model *api.API, codec *codec) *modelAnnotations {
554560
Incomplete: slices.ContainsFunc(model.Services, func(s *api.Service) bool {
555561
return slices.ContainsFunc(s.Methods, func(m *api.Method) bool { return !codec.generateMethod(m) })
556562
}),
557-
GenerateSetterSamples: codec.generateSetterSamples,
563+
GenerateSetterSamples: codec.generateSetterSamples,
564+
DetailedTracingAttributes: codec.detailedTracingAttributes,
558565
}
559566

560567
codec.addFeatureAnnotations(model, ann)
@@ -668,13 +675,14 @@ func (c *codec) annotateService(s *api.Service) {
668675
ModuleName: moduleName,
669676
DocLines: c.formatDocComments(
670677
s.Documentation, s.ID, s.Model.State, []string{s.ID, s.Package}),
671-
Methods: methods,
672-
DefaultHost: s.DefaultHost,
673-
LROTypes: lroTypes,
674-
APITitle: s.Model.Title,
675-
PerServiceFeatures: c.perServiceFeatures,
676-
HasVeneer: c.hasVeneer,
677-
Incomplete: slices.ContainsFunc(s.Methods, func(m *api.Method) bool { return !c.generateMethod(m) }),
678+
Methods: methods,
679+
DefaultHost: s.DefaultHost,
680+
LROTypes: lroTypes,
681+
APITitle: s.Model.Title,
682+
PerServiceFeatures: c.perServiceFeatures,
683+
HasVeneer: c.hasVeneer,
684+
Incomplete: slices.ContainsFunc(s.Methods, func(m *api.Method) bool { return !c.generateMethod(m) }),
685+
DetailedTracingAttributes: c.detailedTracingAttributes,
678686
}
679687
s.Codec = ann
680688
}

internal/sidekick/internal/rust/annotate_test.go

Lines changed: 138 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,44 @@ func TestServiceAnnotations(t *testing.T) {
216216
}
217217
}
218218

219+
func TestServiceAnnotationsDetailedTracing(t *testing.T) {
220+
model := serviceAnnotationsModel()
221+
service, ok := model.State.ServiceByID[".test.v1.ResourceService"]
222+
if !ok {
223+
t.Fatal("cannot find .test.v1.ResourceService")
224+
}
225+
codec, err := newCodec("protobuf", map[string]string{
226+
"detailed-tracing-attributes": "true",
227+
})
228+
if err != nil {
229+
t.Fatal(err)
230+
}
231+
annotateModel(model, codec)
232+
got := service.Codec.(*serviceAnnotations)
233+
if !got.DetailedTracingAttributes {
234+
t.Errorf("serviceAnnotations.DetailedTracingAttributes = %v, want %v", got.DetailedTracingAttributes, true)
235+
}
236+
}
237+
238+
func TestMethodAnnotationsDetailedTracing(t *testing.T) {
239+
model := serviceAnnotationsModel()
240+
method, ok := model.State.MethodByID[".test.v1.ResourceService.GetResource"]
241+
if !ok {
242+
t.Fatal("cannot find .test.v1.ResourceService.GetResource")
243+
}
244+
codec, err := newCodec("protobuf", map[string]string{
245+
"detailed-tracing-attributes": "true",
246+
})
247+
if err != nil {
248+
t.Fatal(err)
249+
}
250+
annotateModel(model, codec)
251+
got := method.Codec.(*methodAnnotation)
252+
if !got.DetailedTracingAttributes {
253+
t.Errorf("methodAnnotation.DetailedTracingAttributes = %v, want %v", got.DetailedTracingAttributes, true)
254+
}
255+
}
256+
219257
func TestServiceAnnotationsPerServiceFeatures(t *testing.T) {
220258
model := serviceAnnotationsModel()
221259
service, ok := model.State.ServiceByID[".test.v1.ResourceService"]
@@ -1120,7 +1158,6 @@ func TestPathBindingAnnotations(t *testing.T) {
11201158
},
11211159
},
11221160
}
1123-
11241161
b2 := &api.PathBinding{
11251162
Verb: "POST",
11261163
PathTemplate: api.NewPathTemplate().
@@ -1153,7 +1190,6 @@ func TestPathBindingAnnotations(t *testing.T) {
11531190
},
11541191
},
11551192
}
1156-
11571193
b3 := &api.PathBinding{
11581194
Verb: "GET",
11591195
PathTemplate: api.NewPathTemplate().
@@ -1169,7 +1205,6 @@ func TestPathBindingAnnotations(t *testing.T) {
11691205
PathFmt: "/v2/foos",
11701206
QueryParams: []*api.Field{f_name, f_optional, f_child},
11711207
}
1172-
11731208
method := &api.Method{
11741209
Name: "DoFoo",
11751210
ID: ".test.Service.DoFoo",
@@ -1213,6 +1248,68 @@ func TestPathBindingAnnotations(t *testing.T) {
12131248
}
12141249
}
12151250

1251+
func TestPathBindingAnnotationsDetailedTracing(t *testing.T) {
1252+
f_name := &api.Field{
1253+
Name: "name",
1254+
JSONName: "name",
1255+
ID: ".test.Request.name",
1256+
Typez: api.STRING_TYPE,
1257+
}
1258+
request := &api.Message{
1259+
Name: "Request",
1260+
Package: "test",
1261+
ID: ".test.Request",
1262+
Fields: []*api.Field{f_name},
1263+
}
1264+
response := &api.Message{
1265+
Name: "Response",
1266+
Package: "test",
1267+
ID: ".test.Response",
1268+
}
1269+
binding := &api.PathBinding{
1270+
Verb: "POST",
1271+
PathTemplate: api.NewPathTemplate().
1272+
WithLiteral("v2").
1273+
WithVariable(api.NewPathVariable("name").
1274+
WithLiteral("projects").
1275+
WithMatch()).
1276+
WithVerb("create"),
1277+
}
1278+
method := &api.Method{
1279+
Name: "DoFoo",
1280+
ID: ".test.Service.DoFoo",
1281+
InputType: request,
1282+
InputTypeID: ".test.Request",
1283+
OutputTypeID: ".test.Response",
1284+
PathInfo: &api.PathInfo{
1285+
Bindings: []*api.PathBinding{binding},
1286+
},
1287+
}
1288+
service := &api.Service{
1289+
Name: "FooService",
1290+
ID: ".test.FooService",
1291+
Package: "test",
1292+
Methods: []*api.Method{method},
1293+
}
1294+
model := api.NewTestAPI(
1295+
[]*api.Message{request, response},
1296+
[]*api.Enum{},
1297+
[]*api.Service{service})
1298+
api.CrossReference(model)
1299+
codec, err := newCodec("protobuf", map[string]string{
1300+
"detailed-tracing-attributes": "true",
1301+
})
1302+
if err != nil {
1303+
t.Fatal(err)
1304+
}
1305+
annotateModel(model, codec)
1306+
1307+
got := binding.Codec.(*pathBindingAnnotation)
1308+
if !got.DetailedTracingAttributes {
1309+
t.Errorf("pathBindingAnnotation.DetailedTracingAttributes = %v, want %v", got.DetailedTracingAttributes, true)
1310+
}
1311+
}
1312+
12161313
func TestPathBindingAnnotationsStyle(t *testing.T) {
12171314
for _, test := range []struct {
12181315
FieldName string
@@ -1525,6 +1622,44 @@ func TestGenerateSetterSamples(t *testing.T) {
15251622
}
15261623
}
15271624

1625+
func TestAnnotateModelWithDetailedTracing(t *testing.T) {
1626+
tests := []struct {
1627+
name string
1628+
options map[string]string
1629+
want bool
1630+
}{
1631+
{
1632+
name: "DetailedTracingTrue",
1633+
options: map[string]string{"detailed-tracing-attributes": "true"},
1634+
want: true,
1635+
},
1636+
{
1637+
name: "DetailedTracingFalse",
1638+
options: map[string]string{"detailed-tracing-attributes": "false"},
1639+
want: false,
1640+
},
1641+
{
1642+
name: "DetailedTracingMissing",
1643+
options: map[string]string{},
1644+
want: false,
1645+
},
1646+
}
1647+
1648+
for _, tt := range tests {
1649+
t.Run(tt.name, func(t *testing.T) {
1650+
model := api.NewTestAPI([]*api.Message{}, []*api.Enum{}, []*api.Service{})
1651+
codec, err := newCodec("protobuf", tt.options)
1652+
if err != nil {
1653+
t.Fatal(err)
1654+
}
1655+
got := annotateModel(model, codec)
1656+
if got.DetailedTracingAttributes != tt.want {
1657+
t.Errorf("annotateModel() DetailedTracingAttributes = %v, want %v", got.DetailedTracingAttributes, tt.want)
1658+
}
1659+
})
1660+
}
1661+
}
1662+
15281663
func TestSetterSampleAnnotations(t *testing.T) {
15291664
enum := &api.Enum{
15301665
Name: "TestEnum",

0 commit comments

Comments
 (0)