Skip to content

Commit

Permalink
Add UnmarshalText for StabilityLevel (#11520)
Browse files Browse the repository at this point in the history
This PR also starts using the fact that StabilityLevel implements
UnmarshalText and cleans up the mdatagen stability structure.

Signed-off-by: Bogdan Drutu <bogdandrutu@gmail.com>
  • Loading branch information
bogdandrutu authored Oct 23, 2024
1 parent 0daa813 commit 9897574
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 54 deletions.
25 changes: 25 additions & 0 deletions .chloggen/stabilityunmarshal.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
component: component

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add UnmarshalText for StabilityLevel

# One or more tracking issues or pull requests related to the change
issues: [11520]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext:

# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: [api]
2 changes: 1 addition & 1 deletion cmd/mdatagen/internal/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func TestValidate(t *testing.T) {
},
{
name: "testdata/invalid_stability.yaml",
wantErr: "decoding failed due to the following error(s):\n\nerror decoding 'status.stability': invalid stability level: incorrectstability",
wantErr: "decoding failed due to the following error(s):\n\nerror decoding 'status.stability': unsupported stability level: \"incorrectstability\"",
},
{
name: "testdata/no_stability_component.yaml",
Expand Down
46 changes: 8 additions & 38 deletions cmd/mdatagen/internal/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@ import (
"errors"
"fmt"
"sort"
"strings"

"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/confmap"
)

// Distros is a collection of distributions that can be referenced in the metadata.yaml files.
Expand Down Expand Up @@ -70,7 +68,7 @@ func (s *Status) Validate() error {
if err := s.validateClass(); err != nil {
errs = errors.Join(errs, err)
}
if err := s.validateStability(); err != nil {
if err := s.Stability.Validate(); err != nil {
errs = errors.Join(errs, err)
}
return errs
Expand All @@ -86,16 +84,18 @@ func (s *Status) validateClass() error {
return nil
}

func (s *Status) validateStability() error {
type StabilityMap map[component.StabilityLevel][]string

func (ms StabilityMap) Validate() error {
var errs error
if len(s.Stability) == 0 {
if len(ms) == 0 {
return errors.New("missing stability")
}
for stability, component := range s.Stability {
if len(component) == 0 {
for stability, cmps := range ms {
if len(cmps) == 0 {
errs = errors.Join(errs, fmt.Errorf("missing component for stability: %v", stability))
}
for _, c := range component {
for _, c := range cmps {
if c != "metrics" &&
c != "traces" &&
c != "logs" &&
Expand Down Expand Up @@ -123,33 +123,3 @@ func (s *Status) validateStability() error {
}
return errs
}

type StabilityMap map[component.StabilityLevel][]string

func (ms *StabilityMap) Unmarshal(parser *confmap.Conf) error {
*ms = make(StabilityMap)
raw := make(map[string][]string)
err := parser.Unmarshal(&raw)
if err != nil {
return err
}
for k, v := range raw {
switch strings.ToLower(k) {
case strings.ToLower(component.StabilityLevelUnmaintained.String()):
(*ms)[component.StabilityLevelUnmaintained] = v
case strings.ToLower(component.StabilityLevelDeprecated.String()):
(*ms)[component.StabilityLevelDeprecated] = v
case strings.ToLower(component.StabilityLevelDevelopment.String()):
(*ms)[component.StabilityLevelDevelopment] = v
case strings.ToLower(component.StabilityLevelAlpha.String()):
(*ms)[component.StabilityLevelAlpha] = v
case strings.ToLower(component.StabilityLevelBeta.String()):
(*ms)[component.StabilityLevelBeta] = v
case strings.ToLower(component.StabilityLevelStable.String()):
(*ms)[component.StabilityLevelStable] = v
default:
return errors.New("invalid stability level: " + k)
}
}
return nil
}
25 changes: 25 additions & 0 deletions component/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ package component // import "go.opentelemetry.io/collector/component"

import (
"context"
"fmt"
"strings"
)

// Component is either a receiver, exporter, processor, connector, or an extension.
Expand Down Expand Up @@ -119,6 +121,29 @@ const (
StabilityLevelStable
)

func (sl *StabilityLevel) UnmarshalText(in []byte) error {
str := strings.ToLower(string(in))
switch str {
case "undefined":
*sl = StabilityLevelUndefined
case "unmaintained":
*sl = StabilityLevelUnmaintained
case "deprecated":
*sl = StabilityLevelDeprecated
case "development":
*sl = StabilityLevelDevelopment
case "alpha":
*sl = StabilityLevelAlpha
case "beta":
*sl = StabilityLevelBeta
case "stable":
*sl = StabilityLevelStable
default:
return fmt.Errorf("unsupported stability level: %q", string(in))
}
return nil
}

func (sl StabilityLevel) String() string {
switch sl {
case StabilityLevelUndefined:
Expand Down
82 changes: 67 additions & 15 deletions component/component_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,76 @@ import (
)

func TestKindString(t *testing.T) {
assert.EqualValues(t, "", Kind(0).String())
assert.EqualValues(t, "Receiver", KindReceiver.String())
assert.EqualValues(t, "Processor", KindProcessor.String())
assert.EqualValues(t, "Exporter", KindExporter.String())
assert.EqualValues(t, "Extension", KindExtension.String())
assert.EqualValues(t, "Connector", KindConnector.String())
assert.EqualValues(t, "", Kind(100).String())
assert.Equal(t, "", Kind(0).String())
assert.Equal(t, "Receiver", KindReceiver.String())
assert.Equal(t, "Processor", KindProcessor.String())
assert.Equal(t, "Exporter", KindExporter.String())
assert.Equal(t, "Extension", KindExtension.String())
assert.Equal(t, "Connector", KindConnector.String())
assert.Equal(t, "", Kind(100).String())
}

func TestStabilityLevelUnmarshal(t *testing.T) {
tests := []struct {
input string
output StabilityLevel
expectedErr string
}{
{
input: "Undefined",
output: StabilityLevelUndefined,
},
{
input: "UnmaintaineD",
output: StabilityLevelUnmaintained,
},
{
input: "DepreCated",
output: StabilityLevelDeprecated,
},
{
input: "Development",
output: StabilityLevelDevelopment,
},
{
input: "alpha",
output: StabilityLevelAlpha,
},
{
input: "BETA",
output: StabilityLevelBeta,
},
{
input: "sTABLe",
output: StabilityLevelStable,
},
{
input: "notfound",
expectedErr: "unsupported stability level: \"notfound\"",
},
}
for _, test := range tests {
t.Run(test.input, func(t *testing.T) {
var sl StabilityLevel
err := sl.UnmarshalText([]byte(test.input))
if test.expectedErr != "" {
assert.EqualError(t, err, test.expectedErr)
} else {
assert.Equal(t, test.output, sl)
}
})
}
}

func TestStabilityLevelString(t *testing.T) {
assert.EqualValues(t, "Undefined", StabilityLevelUndefined.String())
assert.EqualValues(t, "Unmaintained", StabilityLevelUnmaintained.String())
assert.EqualValues(t, "Deprecated", StabilityLevelDeprecated.String())
assert.EqualValues(t, "Development", StabilityLevelDevelopment.String())
assert.EqualValues(t, "Alpha", StabilityLevelAlpha.String())
assert.EqualValues(t, "Beta", StabilityLevelBeta.String())
assert.EqualValues(t, "Stable", StabilityLevelStable.String())
assert.EqualValues(t, "", StabilityLevel(100).String())
assert.Equal(t, "Undefined", StabilityLevelUndefined.String())
assert.Equal(t, "Unmaintained", StabilityLevelUnmaintained.String())
assert.Equal(t, "Deprecated", StabilityLevelDeprecated.String())
assert.Equal(t, "Development", StabilityLevelDevelopment.String())
assert.Equal(t, "Alpha", StabilityLevelAlpha.String())
assert.Equal(t, "Beta", StabilityLevelBeta.String())
assert.Equal(t, "Stable", StabilityLevelStable.String())
assert.Equal(t, "", StabilityLevel(100).String())
}

func TestStabilityLevelLogMessage(t *testing.T) {
Expand Down

0 comments on commit 9897574

Please sign in to comment.