@@ -633,4 +633,236 @@ mod tests {
633633 Some ( "42" ) ,
634634 ) ;
635635 }
636+
637+ // --- Simple-field exhaustive coverage --------------------------------
638+ //
639+ // Every `LogField` variant goes through the same `simple_path` table.
640+ // The cases below confirm get/set/delete behave consistently across
641+ // every variant we expose (Body and SeverityText already had bespoke
642+ // tests; these round out the rest).
643+
644+ /// One get/delete/set cycle for a simple field. Helper rather than
645+ /// per-variant duplication so future `LogField` additions just append a
646+ /// caller below.
647+ fn assert_simple_round_trip ( field : LogField , event_path : & str ) {
648+ let m = mapping ( ) ;
649+
650+ // get
651+ let mut log = LogEvent :: default ( ) ;
652+ log. insert ( event_path, "initial" ) ;
653+ {
654+ let adapter = VectorLogAdapter :: new ( & mut log, & m) ;
655+ assert_eq ! (
656+ adapter
657+ . get_field( & LogFieldSelector :: Simple ( field) )
658+ . as_deref( ) ,
659+ Some ( "initial" ) ,
660+ "get failed for {field:?} at {event_path:?}" ,
661+ ) ;
662+ }
663+
664+ // delete
665+ let was_present = {
666+ let mut adapter = VectorLogAdapter :: new ( & mut log, & m) ;
667+ adapter. delete_field ( & LogFieldSelector :: Simple ( field) )
668+ } ;
669+ assert ! ( was_present, "delete returned false for {field:?}" ) ;
670+ assert ! (
671+ log. get( event_path) . is_none( ) ,
672+ "delete left {event_path:?} present for {field:?}" ,
673+ ) ;
674+
675+ // set
676+ {
677+ let mut adapter = VectorLogAdapter :: new ( & mut log, & m) ;
678+ adapter. set_field ( & LogFieldSelector :: Simple ( field) , "after-set" ) ;
679+ }
680+ assert_eq ! (
681+ log. get( event_path) . and_then( |v| v. as_str( ) ) ,
682+ Some ( "after-set" . into( ) ) ,
683+ "set didn't insert at {event_path:?} for {field:?}" ,
684+ ) ;
685+ }
686+
687+ #[ test]
688+ fn round_trip_simple_body ( ) {
689+ assert_simple_round_trip ( LogField :: Body , "message" ) ;
690+ }
691+
692+ #[ test]
693+ fn round_trip_simple_severity_text ( ) {
694+ assert_simple_round_trip ( LogField :: SeverityText , "severity_text" ) ;
695+ }
696+
697+ #[ test]
698+ fn round_trip_simple_trace_id ( ) {
699+ assert_simple_round_trip ( LogField :: TraceId , "trace_id" ) ;
700+ }
701+
702+ #[ test]
703+ fn round_trip_simple_span_id ( ) {
704+ assert_simple_round_trip ( LogField :: SpanId , "span_id" ) ;
705+ }
706+
707+ #[ test]
708+ fn round_trip_simple_event_name ( ) {
709+ assert_simple_round_trip ( LogField :: EventName , "event_name" ) ;
710+ }
711+
712+ #[ test]
713+ fn round_trip_simple_resource_schema_url ( ) {
714+ assert_simple_round_trip ( LogField :: ResourceSchemaUrl , "resource.schema_url" ) ;
715+ }
716+
717+ #[ test]
718+ fn round_trip_simple_scope_schema_url ( ) {
719+ assert_simple_round_trip ( LogField :: ScopeSchemaUrl , "scope.schema_url" ) ;
720+ }
721+
722+ // --- Resource / scope attribute Transformable coverage ---------------
723+ //
724+ // `LogAttribute` is already covered in detail. These mirror the same
725+ // operations for the resource and scope namespaces so the namespace
726+ // dispatch in `path_for` is exercised end-to-end.
727+
728+ #[ test]
729+ fn set_resource_attribute_flat ( ) {
730+ let mut log = LogEvent :: default ( ) ;
731+ {
732+ let m = mapping ( ) ;
733+ let mut adapter = VectorLogAdapter :: new ( & mut log, & m) ;
734+ adapter. set_field (
735+ & LogFieldSelector :: ResourceAttribute ( vec ! [ "region" . to_string( ) ] ) ,
736+ "us-east-1" ,
737+ ) ;
738+ }
739+ assert_eq ! (
740+ log. get( "resource.attributes.region" )
741+ . and_then( |v| v. as_str( ) ) ,
742+ Some ( "us-east-1" . into( ) ) ,
743+ ) ;
744+ }
745+
746+ #[ test]
747+ fn set_resource_attribute_nested ( ) {
748+ let mut log = LogEvent :: default ( ) ;
749+ {
750+ let m = mapping ( ) ;
751+ let mut adapter = VectorLogAdapter :: new ( & mut log, & m) ;
752+ adapter. set_field (
753+ & LogFieldSelector :: ResourceAttribute ( vec ! [ "k8s" . to_string( ) , "pod" . to_string( ) ] ) ,
754+ "vector-0" ,
755+ ) ;
756+ }
757+ assert_eq ! (
758+ log. get( "resource.attributes.k8s.pod" )
759+ . and_then( |v| v. as_str( ) ) ,
760+ Some ( "vector-0" . into( ) ) ,
761+ ) ;
762+ }
763+
764+ #[ test]
765+ fn delete_resource_attribute ( ) {
766+ let mut log = LogEvent :: default ( ) ;
767+ log. insert ( "resource.attributes.region" , "us-east-1" ) ;
768+ let was_present = {
769+ let m = mapping ( ) ;
770+ let mut adapter = VectorLogAdapter :: new ( & mut log, & m) ;
771+ adapter. delete_field ( & LogFieldSelector :: ResourceAttribute ( vec ! [
772+ "region" . to_string( ) ,
773+ ] ) )
774+ } ;
775+ assert ! ( was_present) ;
776+ assert ! ( log. get( "resource.attributes.region" ) . is_none( ) ) ;
777+ }
778+
779+ #[ test]
780+ fn move_resource_attribute_within_namespace ( ) {
781+ let mut log = LogEvent :: default ( ) ;
782+ log. insert ( "resource.attributes.zone" , "ap-south-1a" ) ;
783+ {
784+ let m = mapping ( ) ;
785+ let mut adapter = VectorLogAdapter :: new ( & mut log, & m) ;
786+ adapter. move_field (
787+ & LogFieldSelector :: ResourceAttribute ( vec ! [ "zone" . to_string( ) ] ) ,
788+ & LogFieldSelector :: ResourceAttribute ( vec ! [ "availability_zone" . to_string( ) ] ) ,
789+ ) ;
790+ }
791+ assert ! ( log. get( "resource.attributes.zone" ) . is_none( ) ) ;
792+ assert_eq ! (
793+ log. get( "resource.attributes.availability_zone" )
794+ . and_then( |v| v. as_str( ) ) ,
795+ Some ( "ap-south-1a" . into( ) ) ,
796+ ) ;
797+ }
798+
799+ #[ test]
800+ fn set_scope_attribute_flat ( ) {
801+ let mut log = LogEvent :: default ( ) ;
802+ {
803+ let m = mapping ( ) ;
804+ let mut adapter = VectorLogAdapter :: new ( & mut log, & m) ;
805+ adapter. set_field (
806+ & LogFieldSelector :: ScopeAttribute ( vec ! [ "lib_version" . to_string( ) ] ) ,
807+ "1.2.3" ,
808+ ) ;
809+ }
810+ assert_eq ! (
811+ log. get( "scope.attributes.lib_version" )
812+ . and_then( |v| v. as_str( ) ) ,
813+ Some ( "1.2.3" . into( ) ) ,
814+ ) ;
815+ }
816+
817+ #[ test]
818+ fn set_scope_attribute_nested ( ) {
819+ let mut log = LogEvent :: default ( ) ;
820+ {
821+ let m = mapping ( ) ;
822+ let mut adapter = VectorLogAdapter :: new ( & mut log, & m) ;
823+ adapter. set_field (
824+ & LogFieldSelector :: ScopeAttribute ( vec ! [ "vendor" . to_string( ) , "name" . to_string( ) ] ) ,
825+ "otel" ,
826+ ) ;
827+ }
828+ assert_eq ! (
829+ log. get( "scope.attributes.vendor.name" )
830+ . and_then( |v| v. as_str( ) ) ,
831+ Some ( "otel" . into( ) ) ,
832+ ) ;
833+ }
834+
835+ #[ test]
836+ fn delete_scope_attribute ( ) {
837+ let mut log = LogEvent :: default ( ) ;
838+ log. insert ( "scope.attributes.lib_version" , "1.2.3" ) ;
839+ let was_present = {
840+ let m = mapping ( ) ;
841+ let mut adapter = VectorLogAdapter :: new ( & mut log, & m) ;
842+ adapter. delete_field ( & LogFieldSelector :: ScopeAttribute ( vec ! [
843+ "lib_version" . to_string( ) ,
844+ ] ) )
845+ } ;
846+ assert ! ( was_present) ;
847+ assert ! ( log. get( "scope.attributes.lib_version" ) . is_none( ) ) ;
848+ }
849+
850+ #[ test]
851+ fn move_scope_attribute_within_namespace ( ) {
852+ let mut log = LogEvent :: default ( ) ;
853+ log. insert ( "scope.attributes.legacy" , "x" ) ;
854+ {
855+ let m = mapping ( ) ;
856+ let mut adapter = VectorLogAdapter :: new ( & mut log, & m) ;
857+ adapter. move_field (
858+ & LogFieldSelector :: ScopeAttribute ( vec ! [ "legacy" . to_string( ) ] ) ,
859+ & LogFieldSelector :: ScopeAttribute ( vec ! [ "renamed" . to_string( ) ] ) ,
860+ ) ;
861+ }
862+ assert ! ( log. get( "scope.attributes.legacy" ) . is_none( ) ) ;
863+ assert_eq ! (
864+ log. get( "scope.attributes.renamed" ) . and_then( |v| v. as_str( ) ) ,
865+ Some ( "x" . into( ) ) ,
866+ ) ;
867+ }
636868}
0 commit comments