Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

coverage - correctly handle root level discriminator #109

Merged
merged 9 commits into from
Sep 11, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ armstrong
armstrong.exe

# test output
coverage/test_coverage_report*.md
coverage/testdata/test_coverage_report*.md
coverage/testdata/index.json
4 changes: 2 additions & 2 deletions commands/credential_scan.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ func (c CredentialScanCommand) Execute() int {
var swaggerModel *coverage.SwaggerModel
if c.swaggerRepoPath != "" {
logrus.Infof("scan based on local swagger repo: %s", c.swaggerRepoPath)
swaggerModel, err = coverage.GetModelInfoFromLocalIndex(mockedResourceId, apiVersion, c.swaggerRepoPath, c.swaggerIndexFile)
swaggerModel, err = coverage.GetModelInfoFromLocalIndex(mockedResourceId, apiVersion, "PUT", c.swaggerRepoPath, c.swaggerIndexFile)
if err != nil {
credScanErr := makeCredScanError(
azapiResource,
Expand All @@ -248,7 +248,7 @@ func (c CredentialScanCommand) Execute() int {
continue
}
} else {
swaggerModel, err = coverage.GetModelInfoFromIndex(mockedResourceId, apiVersion, c.swaggerIndexFile)
swaggerModel, err = coverage.GetModelInfoFromIndex(mockedResourceId, apiVersion, "PUT", c.swaggerIndexFile)
if err != nil {
credScanErr := makeCredScanError(
azapiResource,
Expand Down
47 changes: 40 additions & 7 deletions coverage/coverage.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@ type Model struct {
IsFullyCovered bool `json:"IsFullyCovered,omitempty"`
IsReadOnly bool `json:"IsReadOnly,omitempty"`
IsRequired bool `json:"IsRequired,omitempty"`
IsRoot bool `json:"IsRoot,omitempty"`
IsSecret bool `json:"IsSecret,omitempty"` // related to x-ms-secret
Item *Model `json:"Item,omitempty"`
ModelName string `json:"ModelName,omitempty"`
Properties *map[string]*Model `json:"Properties,omitempty"`
RootCoveredCount int `json:"RootCoveredCount,omitempty"` // only for root model, covered count plus all variant count if any
RootTotalCount int `json:"RootTotalCount,omitempty"` // only for root model, total count plus all variant count if any
SourceFile string `json:"SourceFile,omitempty"`
TotalCount int `json:"TotalCount,omitempty"`
Type *string `json:"Type,omitempty"`
Variants *map[string]*Model `json:"Variants,omitempty"` // variant model name is used as key, this may only contains
Variants *map[string]*Model `json:"Variants,omitempty"` // variant model name is used as key, in case x-ms-discriminator-value is not available
VariantType *string `json:"VariantType,omitempty"` // the x-ms-discriminator-value of the variant model if exists, otherwise model name
}

Expand Down Expand Up @@ -128,7 +131,7 @@ func (m *Model) MarkCovered(root interface{}) {
if m.Enum != nil {
strValue := fmt.Sprintf("%v", value)
if _, ok := (*m.Enum)[strValue]; !ok {
logrus.Errorf("unexpected enum %s in %s", value, m.Identifier)
logrus.Warningf("unexpected enum %s in %s", value, m.Identifier)
}

(*m.Enum)[strValue] = true
Expand Down Expand Up @@ -168,14 +171,14 @@ func (m *Model) MarkCovered(root interface{}) {

// either the discriminator value hit the variant model name or variant type, we match the variant
if variant, ok := (*m.Variants)[v.(string)]; ok {
isMatchProperty = false
isMatchProperty = true
variant.MarkCovered(value)

break
}
for _, variant := range *m.Variants {
if variant.VariantType != nil && *variant.VariantType == v.(string) {
isMatchProperty = false
isMatchProperty = true
variant.MarkCovered(value)

break Loop
Expand All @@ -189,9 +192,8 @@ func (m *Model) MarkCovered(root interface{}) {
if isMatchProperty {
for k, v := range value {
if m.Properties == nil {
if !m.HasAdditionalProperties {
logrus.Errorf("unexpected key %s in %s", k, m.Identifier)
}
// some objects has no properties defined
// https://github.com/Azure/azure-rest-api-specs/blob/3519c80fe510a268f6e59a29ccac8a53fdec15b6/specification/monitor/resource-manager/Microsoft.Insights/stable/2023-03-11/dataCollectionRules_API.json#L724
continue
}
if _, ok := (*m.Properties)[k]; !ok {
Expand Down Expand Up @@ -272,6 +274,20 @@ func (m *Model) CountCoverage() (int, int) {
}
}

if m.IsRoot {
if m.Variants != nil {
for _, v := range *m.Variants {
v.CountCoverage()
}
}

if m.Item != nil && m.Item.Variants != nil {
for _, v := range *m.Item.Variants {
v.CountCoverage()
}
}
}

if m.TotalCount == 0 {
m.TotalCount = 1
}
Expand All @@ -281,6 +297,23 @@ func (m *Model) CountCoverage() (int, int) {

m.IsFullyCovered = m.TotalCount > 0 && m.CoveredCount == m.TotalCount

if m.IsRoot {
m.RootCoveredCount = m.CoveredCount
m.RootTotalCount = m.TotalCount
if m.Variants != nil {
for _, v := range *m.Variants {
m.RootCoveredCount += v.CoveredCount
m.RootTotalCount += v.TotalCount
}
}
if m.Item != nil && m.Item.Variants != nil {
for _, v := range *m.Item.Variants {
m.RootCoveredCount += v.CoveredCount
m.RootTotalCount += v.TotalCount
}
}
}

return m.CoveredCount, m.TotalCount
}

Expand Down
Loading
Loading