@@ -4534,3 +4534,81 @@ func TestRemovingOfflineRemotes(t *testing.T) {
4534
4534
cancelReconfig ()
4535
4535
wg .Wait ()
4536
4536
}
4537
+
4538
+ // TestModuleNamePassing asserts that module names are passed from viam-server -> module
4539
+ // properly. Such that incoming requests from module -> viam-server identify themselves. And can be
4540
+ // observed on contexts via `[r]grpc.GetModuleName(ctx)`.
4541
+ func TestModuleNamePassing (t * testing.T ) {
4542
+ logger := logging .NewTestLogger (t )
4543
+
4544
+ ctx := context .Background ()
4545
+
4546
+ // We will inject a `ReadingsFunc` handler. The request should come from the `testmodule` and
4547
+ // the interceptors should pass along a module name. Which will get captured in the
4548
+ // `moduleNameCh` that the end of the test will assert on.
4549
+ //
4550
+ // The channel must be buffered to such that the `ReadingsFunc` returns without waiting on a
4551
+ // reader of the channel.
4552
+ moduleNameCh := make (chan string , 1 )
4553
+ callbackSensor := & inject.Sensor {
4554
+ ReadingsFunc : func (ctx context.Context , extra map [string ]any ) (map [string ]any , error ) {
4555
+ moduleNameCh <- rgrpc .GetModuleName (ctx )
4556
+ return map [string ]any {
4557
+ "reading" : 42 ,
4558
+ }, nil
4559
+ },
4560
+ CloseFunc : func (ctx context.Context ) error {
4561
+ return nil
4562
+ },
4563
+ }
4564
+
4565
+ // The resource registry is a global. We must use unique model names to avoid unexpected
4566
+ // collisions.
4567
+ callbackModelName := resource .DefaultModelFamily .WithModel (utils .RandomAlphaString (8 ))
4568
+ resource .RegisterComponent (
4569
+ sensor .API ,
4570
+ callbackModelName ,
4571
+ resource.Registration [sensor.Sensor , resource.NoNativeConfig ]{Constructor : func (
4572
+ ctx context.Context ,
4573
+ deps resource.Dependencies ,
4574
+ conf resource.Config ,
4575
+ logger logging.Logger ,
4576
+ ) (sensor.Sensor , error ) {
4577
+ // Be lazy -- just return an a singleton object.
4578
+ return callbackSensor , nil
4579
+ }})
4580
+
4581
+ const moduleName = "fancy_module_name"
4582
+ localRobot := setupLocalRobot (t , ctx , & config.Config {
4583
+ Modules : []config.Module {
4584
+ {
4585
+ Name : moduleName ,
4586
+ ExePath : rtestutils .BuildTempModule (t , "module/testmodule" ),
4587
+ Type : config .ModuleTypeLocal ,
4588
+ },
4589
+ },
4590
+ Components : []resource.Config {
4591
+ // We will invoke a special `DoCommand` on `modularComp`. It will expect its `DependsOn:
4592
+ // "foo"` to be a sensor. And call the `Readings` API on that sensor.
4593
+ {
4594
+ Name : "modularComp" ,
4595
+ API : generic .API ,
4596
+ Model : resource .NewModel ("rdk" , "test" , "helper" ),
4597
+ DependsOn : []string {"foo" },
4598
+ },
4599
+ // `foo` will be a sensor that we've instrumented with the injected `ReadingsFunc`.
4600
+ {
4601
+ Name : "foo" ,
4602
+ API : sensor .API ,
4603
+ Model : callbackModelName ,
4604
+ },
4605
+ },
4606
+ }, logger )
4607
+
4608
+ res , err := localRobot .ResourceByName (generic .Named ("modularComp" ))
4609
+ test .That (t , err , test .ShouldBeNil )
4610
+
4611
+ _ , err = res .DoCommand (ctx , map [string ]interface {}{"command" : "do_readings_on_dep" })
4612
+ test .That (t , err , test .ShouldBeNil )
4613
+ test .That (t , <- moduleNameCh , test .ShouldEqual , moduleName )
4614
+ }
0 commit comments