From 4e1dd53a01cedaec593ef45e6e679fb568400c46 Mon Sep 17 00:00:00 2001
From: teowa <104055472+teowa@users.noreply.github.com>
Date: Tue, 10 Sep 2024 12:24:02 +0000
Subject: [PATCH 1/9] fix coverage count and report
---
commands/credential_scan.go | 4 +-
coverage/coverage.go | 34 ++++++++
coverage/coverage_test.go | 150 ++++++++++++++++++++++--------------
coverage/expand.go | 3 +
coverage/index.go | 12 +--
coverage/index_test.go | 14 +++-
coverage/report.go | 143 +++++++++++++++++++++++-----------
7 files changed, 245 insertions(+), 115 deletions(-)
diff --git a/commands/credential_scan.go b/commands/credential_scan.go
index 8dee80d..de983a9 100644
--- a/commands/credential_scan.go
+++ b/commands/credential_scan.go
@@ -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,
@@ -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,
diff --git a/coverage/coverage.go b/coverage/coverage.go
index fb69081..d2b8299 100644
--- a/coverage/coverage.go
+++ b/coverage/coverage.go
@@ -22,10 +22,13 @@ 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"`
@@ -272,6 +275,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
}
@@ -281,6 +298,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
}
diff --git a/coverage/coverage_test.go b/coverage/coverage_test.go
index 03c1219..e26d06d 100644
--- a/coverage/coverage_test.go
+++ b/coverage/coverage_test.go
@@ -15,11 +15,13 @@ import (
)
type testCase struct {
- name string
- apiVersion string
- apiPath string
- rawRequest []string
- resourceType string
+ name string
+ apiPath string
+ rawRequest []string
+ resourceType string
+ method string
+ expectedCoveredCount int
+ expectedTotalCount int
}
func normarlizePath(path string) string {
@@ -28,10 +30,12 @@ func normarlizePath(path string) string {
func TestCoverage_ResourceGroup(t *testing.T) {
tc := testCase{
- name: "ResourceGroup",
- resourceType: "Microsoft.Resources/resourceGroups@2022-09-01",
- apiVersion: "2022-09-01",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rgName",
+ name: "ResourceGroup",
+ resourceType: "Microsoft.Resources/resourceGroups@2022-09-01",
+ method: "PUT",
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rgName",
+ expectedCoveredCount: 1,
+ expectedTotalCount: 3,
rawRequest: []string{
`{
"location": "westeurope"
@@ -44,14 +48,6 @@ func TestCoverage_ResourceGroup(t *testing.T) {
t.Fatalf("process coverage: %+v", err)
}
- if model.CoveredCount != 1 {
- t.Fatalf("expected CoveredCount 1, got %d", model.CoveredCount)
- }
-
- if model.TotalCount != 3 {
- t.Fatalf("expected TotalCount 3, got %d", model.TotalCount)
- }
-
if model.Properties == nil {
t.Fatalf("expected properties, got none")
}
@@ -65,12 +61,36 @@ func TestCoverage_ResourceGroup(t *testing.T) {
}
}
+func TestCoverage_AzureTerraform(t *testing.T) {
+ tc := testCase{
+ name: "AzureTerraform",
+ resourceType: "Microsoft.AzureTerraform@2023-07-01-preview",
+ method: "POST",
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.AzureTerraform/exportTerraform",
+ expectedCoveredCount: 2,
+ expectedTotalCount: 25,
+ rawRequest: []string{
+ `{
+ "resourceGroupName" : "rg1",
+ "type" : "ExportResourceGroup"
+ }`,
+ },
+ }
+
+ _, err := testCoverage(t, tc)
+ if err != nil {
+ t.Fatalf("process coverage: %+v", err)
+ }
+}
+
func TestCoverage_HealthcareDicom(t *testing.T) {
tc := testCase{
- name: "HealthcareApisDicom",
- resourceType: "Microsoft.HealthcareApis/workspaces/dicomservices@2024-03-31",
- apiVersion: "2024-03-31",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rgName/providers/Microsoft.HealthcareApis/workspaces/workspaceName/dicomservices/dicomServiceName",
+ name: "HealthcareApisDicom",
+ resourceType: "Microsoft.HealthcareApis/workspaces/dicomservices@2024-03-31",
+ method: "PUT",
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rgName/providers/Microsoft.HealthcareApis/workspaces/workspaceName/dicomservices/dicomServiceName",
+ expectedCoveredCount: 12,
+ expectedTotalCount: 14,
// bulkImportConfiguration property not in swagger
rawRequest: []string{
`{
@@ -131,8 +151,8 @@ func TestCoverage_HealthcareDicom(t *testing.T) {
func TestCoverage_MachineLearningServicesWorkspacesJobs(t *testing.T) {
tc := testCase{
name: "MachineLearningServicesWorkspacesJobs",
- resourceType: "Microsoft.MachineLearningServices/workspaces/jobs",
- apiVersion: "2023-06-01-preview",
+ resourceType: "Microsoft.MachineLearningServices/workspaces/jobs@2023-06-01-preview",
+ method: "PUT",
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.MachineLearningServices/workspaces/works1/jobs/job1",
rawRequest: []string{
`{
@@ -193,8 +213,8 @@ func TestCoverage_MachineLearningServicesWorkspacesJobs(t *testing.T) {
func TestCoverage_MachineLearningServicesWorkspacesDataVersions(t *testing.T) {
tc := testCase{
name: "MachineLearningServicesWorkspacesDataVersions",
- resourceType: "Microsoft.MachineLearningServices/workspaces/data/versions",
- apiVersion: "2023-06-01-preview",
+ resourceType: "Microsoft.MachineLearningServices/workspaces/data/versions@2023-06-01-preview",
+ method: "PUT",
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.MachineLearningServices/workspaces/works1/data/data1/versions/version1",
rawRequest: []string{
`{
@@ -233,7 +253,7 @@ func TestCoverage_DeviceSecurityGroup(t *testing.T) {
tc := testCase{
name: "DeviceSecurityGroup",
resourceType: "Microsoft.Security/deviceSecurityGroups@2019-08-01",
- apiVersion: "2019-08-01",
+ method: "PUT",
apiPath: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/SampleRG/providers/Microsoft.Devices/iotHubs/sampleiothub/providers/Microsoft.Security/deviceSecurityGroups/samplesecuritygroup",
rawRequest: []string{
`{
@@ -269,7 +289,7 @@ func TestCoverage_DataMigrationServiceTasks(t *testing.T) {
tc := testCase{
name: "DataMigrationServiceTasks",
resourceType: "Microsoft.DataMigration/services/serviceTasks@2021-06-30",
- apiVersion: "2021-06-30",
+ method: "PUT",
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/DmsSdkRg/providers/Microsoft.DataMigration/services/DmsSdkService/serviceTasks/DmsSdkTask",
rawRequest: []string{
`{
@@ -293,7 +313,7 @@ func TestCoverage_SCVMM(t *testing.T) {
tc := testCase{
name: "SCVMM",
resourceType: "Microsoft.ScVmm/virtualMachineInstances@2023-10-07",
- apiVersion: "2023-10-07",
+ method: "PUT",
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/cli-test-rg-vmm/providers/Microsoft.HybridCompute/machines/test-vm-tf/providers/Microsoft.ScVmm/virtualMachineInstances/default",
rawRequest: []string{
`{
@@ -327,7 +347,7 @@ func TestCoverage_DataMigrationTasks(t *testing.T) {
tc := testCase{
name: "DataMigrationTasks",
resourceType: "Microsoft.DataMigration/services/projects/tasks@2021-06-30",
- apiVersion: "2021-06-30",
+ method: "PUT",
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/DmsSdkRg/providers/Microsoft.DataMigration/services/DmsSdkService/projects/DmsSdkProject/tasks/DmsSdkTask",
rawRequest: []string{
`{
@@ -364,7 +384,7 @@ func TestCoverage_KeyVault(t *testing.T) {
tc := testCase{
name: "KeyVault",
resourceType: "Microsoft.KeyVault/vaults@2023-02-01",
- apiVersion: "2023-02-01",
+ method: "PUT",
apiPath: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sample-resource-group/providers/Microsoft.KeyVault/vaults/sample-vault",
rawRequest: []string{
`{
@@ -451,7 +471,7 @@ func TestCoverage_StorageAccount(t *testing.T) {
tc := testCase{
name: "StorageAccount",
resourceType: "Microsoft.Storage/storageAccounts@2022-09-01",
- apiVersion: "2022-09-01",
+ method: "PUT",
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/res9101/providers/Microsoft.Storage/storageAccounts/sto4445",
rawRequest: []string{
`{
@@ -520,7 +540,7 @@ func TestCoverage_VM(t *testing.T) {
tc := testCase{
name: "VM",
resourceType: "Microsoft.Compute/virtualMachines@2023-03-01",
- apiVersion: "2023-03-01",
+ method: "PUT",
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.Compute/virtualMachines/vm",
rawRequest: []string{
`{
@@ -591,7 +611,7 @@ func TestCoverage_VNet(t *testing.T) {
tc := testCase{
name: "VNet",
resourceType: "Microsoft.Network/virtualNetworks@2023-02-01",
- apiVersion: "2023-02-01",
+ method: "PUT",
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.Network/virtualNetworks/virtualNetwork",
rawRequest: []string{
`{
@@ -630,7 +650,7 @@ func TestCoverage_DataCollectionRule(t *testing.T) {
tc := testCase{
name: "DataCollectionRule",
resourceType: "Microsoft.Insights/dataCollectionRules@2022-06-01",
- apiVersion: "2022-06-01",
+ method: "PUT",
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/test-resources/providers/Microsoft.Insights/dataCollectionRules/testDCR",
rawRequest: []string{
`{
@@ -957,7 +977,7 @@ func TestCoverage_WebSite(t *testing.T) {
tc := testCase{
name: "WebSites",
resourceType: "Microsoft.Web/sites@2022-09-01",
- apiVersion: "2022-09-01",
+ method: "PUT",
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/testrg123/providers/Microsoft.Web/sites/sitef6141",
rawRequest: []string{
`{
@@ -983,10 +1003,12 @@ func TestCoverage_WebSite(t *testing.T) {
func TestCoverage_AKS(t *testing.T) {
tc := testCase{
- name: "AKS",
- resourceType: "Microsoft.ContainerService/ManagedClusters@2023-05-02-preview",
- apiVersion: "2023-05-02-preview",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourcegroups/rg1/providers/Microsoft.ContainerService/managedClusters/clustername1",
+ name: "AKS",
+ resourceType: "Microsoft.ContainerService/ManagedClusters@2024-05-01",
+ method: "PUT",
+ expectedCoveredCount: 33,
+ expectedTotalCount: 234,
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourcegroups/rg1/providers/Microsoft.ContainerService/managedClusters/clustername1",
rawRequest: []string{`{
"location": "location1",
"tags": {
@@ -1074,8 +1096,8 @@ func TestCoverage_AKS(t *testing.T) {
func TestCoverage_CosmosDB(t *testing.T) {
tc := testCase{
name: "CosmosDB",
- resourceType: "Microsoft.DocumentDB/databaseAccounts@2023-04-15",
- apiVersion: "2023-04-15",
+ resourceType: "Microsoft.DocumentDB/databaseAccounts@2024-05-15",
+ method: "PUT",
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.DocumentDB/databaseAccounts/testdb",
rawRequest: []string{
`{
@@ -1302,8 +1324,8 @@ func TestCoverage_CosmosDB(t *testing.T) {
func TestCoverage_DataFactoryPipelines(t *testing.T) {
tc := testCase{
name: "DataFactoryPipelines",
- apiVersion: "2018-06-01",
resourceType: "Microsoft.DataFactory/factories/pipelines@2018-06-01",
+ method: "PUT",
apiPath: "/subscriptions/12345678-1234-1234-1234-12345678abc/resourceGroups/exampleResourceGroup/providers/Microsoft.DataFactory/factories/exampleFactoryName/pipelines/examplePipeline",
rawRequest: []string{
`{
@@ -1404,7 +1426,7 @@ func TestCoverage_DataFactoryLinkedServices(t *testing.T) {
tc := testCase{
name: "DataFactoryLinkedServices",
resourceType: "Microsoft.DataFactory/factories/linkedServices@2018-06-01",
- apiVersion: "2018-06-01",
+ method: "PUT",
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.DataFactory/factories/factory1/linkedServices/linked",
rawRequest: []string{
`{
@@ -1501,10 +1523,13 @@ func TestCoverage_DataFactoryLinkedServices(t *testing.T) {
}
func testCoverage(t *testing.T, tc testCase) (*coverage.Model, error) {
- swaggerModel, err := coverage.GetModelInfoFromIndex(
+ apiVersion := strings.Split(tc.resourceType, "@")[1]
+ swaggerModel, err := coverage.GetModelInfoFromLocalIndex(
tc.apiPath,
- tc.apiVersion,
- "",
+ apiVersion,
+ tc.method,
+ "/home/wangta/project/go/azure-rest-api-specs/specification/",
+ "index0910.json",
)
t.Logf("swaggerModel: %+v", swaggerModel)
@@ -1518,11 +1543,11 @@ func testCoverage(t *testing.T, tc testCase) (*coverage.Model, error) {
return nil, fmt.Errorf("expand model: %+v", err)
}
- //out, err := json.MarshalIndent(model, "", "\t")
- //if err != nil {
- // t.Error(err)
- //}
- //t.Logf("expand model %s", string(out))
+ // out, err := json.MarshalIndent(model, "", "\t")
+ // if err != nil {
+ // t.Error(err)
+ // }
+ // t.Logf("expand model %s", string(out))
for _, rq := range tc.rawRequest {
request := map[string]interface{}{}
@@ -1536,11 +1561,19 @@ func testCoverage(t *testing.T, tc testCase) (*coverage.Model, error) {
model.CountCoverage()
- //out, err = json.MarshalIndent(model, "", "\t")
- //if err != nil {
- // t.Error(err)
- //}
- //t.Logf("coverage model %s", string(out))
+ if model.RootCoveredCount != tc.expectedCoveredCount {
+ t.Errorf("expected CoveredCount %d, got %d", tc.expectedCoveredCount, model.RootCoveredCount)
+ }
+
+ if model.RootTotalCount != tc.expectedTotalCount {
+ t.Errorf("expected TotalCount %d, got %d", tc.expectedTotalCount, model.RootTotalCount)
+ }
+
+ // out, err = json.MarshalIndent(model, "", "\t")
+ // if err != nil {
+ // t.Error(err)
+ // }
+ // t.Logf("coverage model %s", string(out))
coverageReport := coverage.CoverageReport{
Coverages: map[string]*coverage.CoverageItem{
@@ -1578,9 +1611,11 @@ func storeCoverageReport(passReport types.PassReport, coverageReport coverage.Co
}
func testCredScan(t *testing.T, tc testCase) (*map[string]string, error) {
+ apiVersion := strings.Split(tc.resourceType, "@")[1]
swaggerModel, err := coverage.GetModelInfoFromIndex(
tc.apiPath,
- tc.apiVersion,
+ apiVersion,
+ "PUT",
"",
)
@@ -1623,7 +1658,6 @@ func TestCredScan(t *testing.T) {
tc := testCase{
name: "VM",
resourceType: "Microsoft.Compute/virtualMachines@2023-03-01",
- apiVersion: "2023-03-01",
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.Compute/virtualMachines/vm",
rawRequest: []string{
`{
diff --git a/coverage/expand.go b/coverage/expand.go
index 18b3d50..3fca964 100644
--- a/coverage/expand.go
+++ b/coverage/expand.go
@@ -89,6 +89,8 @@ func Expand(modelName, swaggerPath string) (*Model, error) {
output := expandSchema(modelSchema, swaggerPath, modelName, "#", spec, map[string]interface{}{}, map[string]interface{}{})
+ output.IsRoot = true
+
return output, nil
}
@@ -178,6 +180,7 @@ func expandSchema(input openapiSpec.Schema, swaggerPath, modelName, identifier s
properties[k] = v
}
}
+ output.ModelName = referenceModel.ModelName
if referenceModel.Enum != nil {
output.Enum = referenceModel.Enum
}
diff --git a/coverage/index.go b/coverage/index.go
index b27d5b6..7eb6697 100644
--- a/coverage/index.go
+++ b/coverage/index.go
@@ -165,7 +165,7 @@ type SwaggerModel struct {
// GetModelInfoFromIndex will try to download online index from https://github.com/teowa/azure-rest-api-index-file, and get model info from it
// if the index is already downloaded as in {indexFilePath}, it will use the cached index
-func GetModelInfoFromIndex(resourceId, apiVersion, indexFilePath string) (*SwaggerModel, error) {
+func GetModelInfoFromIndex(resourceId, apiVersion, method, indexFilePath string) (*SwaggerModel, error) {
index, err := GetIndex(indexFilePath)
if err != nil {
return nil, err
@@ -176,7 +176,7 @@ func GetModelInfoFromIndex(resourceId, apiVersion, indexFilePath string) (*Swagg
if err != nil {
return nil, fmt.Errorf("parsing URL %s: %+v", resourceURL, err)
}
- ref, err := index.Lookup("PUT", *uRL)
+ ref, err := index.Lookup(method, *uRL)
if err != nil {
return nil, fmt.Errorf("lookup PUT URL %s in index: %+v", resourceURL, err)
}
@@ -193,7 +193,7 @@ func GetModelInfoFromIndex(resourceId, apiVersion, indexFilePath string) (*Swagg
}
// GetModelInfoFromLocalIndex tries to build index from local swagger repo and get model info from it
-func GetModelInfoFromLocalIndex(resourceId, apiVersion, swaggerRepo, indexCacheFile string) (*SwaggerModel, error) {
+func GetModelInfoFromLocalIndex(resourceId, apiVersion, method, swaggerRepo, indexCacheFile string) (*SwaggerModel, error) {
swaggerRepo, err := filepath.Abs(swaggerRepo)
if err != nil {
return nil, fmt.Errorf("swagger repo path %q is invalid: %+v", swaggerRepo, err)
@@ -221,7 +221,7 @@ func GetModelInfoFromLocalIndex(resourceId, apiVersion, swaggerRepo, indexCacheF
if err != nil {
return nil, fmt.Errorf("parsing URL %s: %+v", resourceURL, err)
}
- ref, err := index.Lookup("PUT", *uRL)
+ ref, err := index.Lookup(method, *uRL)
if err != nil {
return nil, fmt.Errorf("lookup PUT URL %s in index: %+v", resourceURL, err)
}
@@ -309,7 +309,7 @@ func MockResourceIDFromType(azapiResourceType string) (string, string) {
return fmt.Sprintf("%s/%s/providers/%s/%s", subscritionSeg, resourceGroupSeg, resourceProvider, typeIds), apiVersion
}
-func GetModelInfoFromIndexWithType(azapiResourceType, indexCacheFile string) (*SwaggerModel, error) {
+func GetModelInfoFromIndexWithType(azapiResourceType, method, indexCacheFile string) (*SwaggerModel, error) {
resourceId, apiVersion := MockResourceIDFromType(azapiResourceType)
- return GetModelInfoFromIndex(resourceId, apiVersion, indexCacheFile)
+ return GetModelInfoFromIndex(resourceId, apiVersion, method, indexCacheFile)
}
diff --git a/coverage/index_test.go b/coverage/index_test.go
index a70a1a0..88cd4e9 100644
--- a/coverage/index_test.go
+++ b/coverage/index_test.go
@@ -17,6 +17,7 @@ func TestGetModelInfoFromIndex_DataCollectionRule(t *testing.T) {
swaggerModel, err := coverage.GetModelInfoFromIndex(
"/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/test-resources/providers/Microsoft.Insights/dataCollectionRules/testDCR",
apiVersion,
+ "PUT",
"",
)
if err != nil {
@@ -44,6 +45,7 @@ func TestGetModelInfoFromIndexWithCache_DataCollectionRule(t *testing.T) {
swaggerModel, err := coverage.GetModelInfoFromIndex(
"/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/test-resources/providers/Microsoft.Insights/dataCollectionRules/testDCR",
apiVersion,
+ "PUT",
indexFilePath,
)
if err != nil {
@@ -71,6 +73,7 @@ func TestGetModelInfoFromIndex_DeviceSecurityGroups(t *testing.T) {
swaggerModel, err := coverage.GetModelInfoFromIndex(
"/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/SampleRG/providers/Microsoft.Devices/iotHubs/sampleiothub/providers/Microsoft.Security/deviceSecurityGroups/samplesecuritygroup",
apiVersion,
+ "PUT",
"",
)
if err != nil {
@@ -95,7 +98,7 @@ func TestGetModelInfoFromIndex_DeviceSecurityGroups(t *testing.T) {
func TestGetModelInfoFromIndexWithType_DataCollectionRule(t *testing.T) {
azapiResourceType := "Microsoft.Insights/dataCollectionRules@2022-06-01"
- swaggerModel, err := coverage.GetModelInfoFromIndexWithType(azapiResourceType, "")
+ swaggerModel, err := coverage.GetModelInfoFromIndexWithType(azapiResourceType, "PUT", "")
if err != nil {
t.Fatalf("get model info from index error: %+v", err)
}
@@ -108,7 +111,7 @@ func TestGetModelInfoFromIndexWithType_DataCollectionRule(t *testing.T) {
func TestGetModelInfoFromIndexWithTypeWithCache_DataCollectionRule(t *testing.T) {
azapiResourceType := "Microsoft.Insights/dataCollectionRules@2022-06-01"
- swaggerModel, err := coverage.GetModelInfoFromIndexWithType(azapiResourceType, indexFilePath)
+ swaggerModel, err := coverage.GetModelInfoFromIndexWithType(azapiResourceType, "PUT", indexFilePath)
if err != nil {
t.Fatalf("get model info from index error: %+v", err)
}
@@ -118,7 +121,7 @@ func TestGetModelInfoFromIndexWithTypeWithCache_DataCollectionRule(t *testing.T)
t.Fatalf("expected apiPath %s, got %s", expectedApiPath, swaggerModel.ApiPath)
}
- _, err = coverage.GetModelInfoFromIndexWithType(azapiResourceType, indexFilePath)
+ _, err = coverage.GetModelInfoFromIndexWithType(azapiResourceType, "PUT", indexFilePath)
if err != nil {
t.Fatalf("get model info from index error: %+v", err)
}
@@ -126,7 +129,7 @@ func TestGetModelInfoFromIndexWithTypeWithCache_DataCollectionRule(t *testing.T)
func TestGetModelInfoFromIndexWithType_DeviceSecurityGroups(t *testing.T) {
azapiResourceType := "Microsoft.Security/deviceSecurityGroups@2019-08-01"
- swaggerModel, err := coverage.GetModelInfoFromIndexWithType(azapiResourceType, "")
+ swaggerModel, err := coverage.GetModelInfoFromIndexWithType(azapiResourceType, "PUT", "")
if err != nil {
t.Fatalf("get model info from index error: %+v", err)
}
@@ -147,6 +150,7 @@ func TestGetModelInfoFromLocalIndex_DataCollectionRule(t *testing.T) {
swaggerModel, err := coverage.GetModelInfoFromLocalIndex(
"/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/test-resources/providers/Microsoft.Insights/dataCollectionRules/testDCR",
apiVersion,
+ "PUT",
azureRepoDir,
"",
)
@@ -180,6 +184,7 @@ func TestGetModelInfoFromLocalIndexWithCache_DataCollectionRule(t *testing.T) {
swaggerModel, err := coverage.GetModelInfoFromLocalIndex(
"/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/test-resources/providers/Microsoft.Insights/dataCollectionRules/testDCR",
apiVersion,
+ "PUT",
azureRepoDir,
indexFilePath,
)
@@ -205,6 +210,7 @@ func TestGetModelInfoFromLocalIndexWithCache_DataCollectionRule(t *testing.T) {
_, err = coverage.GetModelInfoFromLocalIndex(
"/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/test-resources/providers/Microsoft.Insights/dataCollectionRules/testDCR",
apiVersion,
+ "PUT",
azureRepoDir,
indexFilePath,
)
diff --git a/coverage/report.go b/coverage/report.go
index 421ddd6..6f5f09c 100644
--- a/coverage/report.go
+++ b/coverage/report.go
@@ -33,7 +33,7 @@ func (c *CoverageReport) AddCoverageFromState(resourceId, resourceType string, j
swaggerModel = swaggerModelFromLocal
}
if swaggerModel == nil {
- swaggerModelFromIndex, err := GetModelInfoFromIndex(resourceId, apiVersion, "")
+ swaggerModelFromIndex, err := GetModelInfoFromIndex(resourceId, apiVersion, "PUT", "")
if err != nil {
return fmt.Errorf("error find the path for %s from index: %+v", resourceId, err)
}
@@ -98,7 +98,7 @@ ${coverage_details}
for _, v := range c.Coverages {
count++
- reportDetail := getReport(v.Model)
+ reportDetail := getReport(v.Model.ModelName, v.Model)
sort.Strings(reportDetail)
coverages = append(coverages, fmt.Sprintf(`#####
@@ -107,20 +107,14 @@ ${coverage_details}
[swagger](%[3]v)
-
-%[5]v(%[6]v/%[7]v)
-
-
-%[8]v
-
-
+%[4]v
---
-`, v.DisplayName, v.ApiPath, v.Model.SourceFile, getStyle(v.Model.IsFullyCovered), v.Model.ModelName, v.Model.CoveredCount, v.Model.TotalCount, strings.Join(reportDetail, "\n\n")))
+`, v.DisplayName, v.ApiPath, v.Model.SourceFile, strings.Join(reportDetail, "\n\n")))
}
sort.Strings(coverages)
@@ -158,8 +152,21 @@ func (c *CoverageReport) MarkdownContentCompact() string {
return template + content
}
-func getReport(model *Model) []string {
+func getReport(displayName string, model *Model) []string {
out := make([]string, 0)
+ style := getStyle(model.IsFullyCovered)
+
+ if hasNoDetail(model) {
+ // leaf property
+ out = append(out,
+ fmt.Sprintf(`
+
+%[3]v
+
+ `, model.Identifier, style, displayName),
+ )
+ return out
+ }
if isBoolEnumDisplayed {
if model.Enum != nil {
@@ -178,7 +185,7 @@ func getReport(model *Model) []string {
}
if model.Item != nil {
- return getReport(model.Item)
+ return getReport(displayName, model.Item)
}
if model.Properties != nil {
@@ -196,17 +203,16 @@ func getReport(model *Model) []string {
if v.VariantType != nil {
variantType = *v.VariantType
}
- variantKey := fmt.Sprintf("%s{%s}", k, variantType)
-
- out = append(out, getChildReport(variantKey, v))
+ variantKey := getDiscriminatorKey(k, variantType)
+ out = append(out, getReport(variantKey, v)...)
for variantType, variant := range *v.Variants {
variantType := variantType
if variant.VariantType != nil {
variantType = *variant.VariantType
}
- variantKey := fmt.Sprintf("%s{%s}", k, variantType)
- out = append(out, getChildReport(variantKey, variant))
+ variantKey := getDiscriminatorKey(k, variantType)
+ out = append(out, getReport(variantKey, variant)...)
}
continue
}
@@ -216,25 +222,68 @@ func getReport(model *Model) []string {
if v.Item.VariantType != nil {
variantType = *v.Item.VariantType
}
- variantKey := fmt.Sprintf("%s{%s}", k, variantType)
- out = append(out, getChildReport(variantKey, v))
+ variantKey := getDiscriminatorKey(k, variantType)
+ out = append(out, getReport(variantKey, v)...)
for variantType, variant := range *v.Item.Variants {
variantType := variantType
if variant.VariantType != nil {
variantType = *variant.VariantType
}
- variantKey := fmt.Sprintf("%s{%s}", k, variantType)
- out = append(out, getChildReport(variantKey, variant))
+ variantKey := getDiscriminatorKey(k, variantType)
+ out = append(out, getReport(variantKey, variant)...)
}
continue
}
- out = append(out, getChildReport(k, v))
+ out = append(out, getReport(k, v)...)
+ }
+ }
+
+ sort.Strings(out)
+
+ outWithoutVariant := []string{
+ fmt.Sprintf(`
+
+%[3]v %[4]v
+
+
+%[5]v
+
+
+ `, model.Identifier, style, displayName, getCoverageCount(model), strings.Join(out, "\n\n")),
+ }
+
+ if model.IsRoot {
+ var variants *map[string]*Model
+ if model.Variants != nil {
+ variants = model.Variants
+ }
+ if model.Item != nil && model.Item.Variants != nil {
+ variants = model.Item.Variants
+ }
+
+ if variants != nil {
+ outWithVariant := make([]string, 0)
+ outWithVariant = append(outWithVariant, outWithoutVariant...)
+
+ for variantType, variant := range *variants {
+ variantType := variantType
+ if variant.VariantType != nil {
+ variantType = *variant.VariantType
+ }
+ variantKey := getDiscriminatorKey(displayName, variantType)
+ outWithVariant = append(outWithVariant, getReport(variantKey, variant)...)
+ }
+
+ sort.Strings(outWithVariant)
+
+ return outWithVariant
}
}
- return out
+ return outWithoutVariant
+
}
func getEnumBoolReport(name string, isCovered bool) string {
@@ -251,34 +300,34 @@ func getCoverageCount(model *Model) string {
return fmt.Sprintf("(%v/%v)", model.CoveredCount, model.TotalCount)
}
-func getChildReport(name string, model *Model) string {
- var style, report string
+// func getChildReport(name string, model *Model) string {
+// var style, report string
- style = getStyle(model.IsFullyCovered)
+// style = getStyle(model.IsFullyCovered)
- if hasNoDetail(model) {
- // leaf property
- report = fmt.Sprintf(`
-
-%[3]v
+// if hasNoDetail(model) {
+// // leaf property
+// report = fmt.Sprintf(`
+//
+// %[3]v
- `, model.Identifier, style, name)
- } else {
- childReport := getReport(model)
- sort.Strings(childReport)
- report = fmt.Sprintf(`
-
-%[3]v %[4]v
-
+//
`, model.Identifier, style, name)
+// } else {
+// childReport := getReport(model, model.ModelName)
+// sort.Strings(childReport)
+// report = fmt.Sprintf(`
+//
+// %[3]v %[4]v
+//
-%[5]v
+// %[5]v
-
- `, model.Identifier, style, name, getCoverageCount(model), strings.Join(childReport, "\n\n"))
- }
+//
+// `, model.Identifier, style, name, getCoverageCount(model), strings.Join(childReport, "\n\n"))
+// }
- return report
-}
+// return report
+// }
func hasNoDetail(model *Model) bool {
if model.Properties == nil && model.Variants == nil && model.Item == nil && (!isBoolEnumDisplayed || (model.Bool == nil && model.Enum == nil)) {
@@ -299,3 +348,7 @@ func getStyle(isFullyCovered bool) string {
}
return " style=\"color:red\""
}
+
+func getDiscriminatorKey(modelName, variantType string) string {
+ return fmt.Sprintf("%s{%s}", modelName, variantType)
+}
From 3899268e053b0977358a634c06fc266257917345 Mon Sep 17 00:00:00 2001
From: teowa <104055472+teowa@users.noreply.github.com>
Date: Wed, 11 Sep 2024 02:40:01 +0000
Subject: [PATCH 2/9] enhance test
---
.gitignore | 2 +-
coverage/coverage_test.go | 314 ++++++++++++++++++--------------------
coverage/expand.go | 10 ++
coverage/expand_test.go | 2 +-
4 files changed, 158 insertions(+), 170 deletions(-)
diff --git a/.gitignore b/.gitignore
index e87a764..1a1e5b5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,5 +16,5 @@ armstrong
armstrong.exe
# test output
-coverage/test_coverage_report*.md
+coverage/testdata/test_coverage_report*.md
coverage/testdata/index.json
diff --git a/coverage/coverage_test.go b/coverage/coverage_test.go
index e26d06d..5016a88 100644
--- a/coverage/coverage_test.go
+++ b/coverage/coverage_test.go
@@ -138,22 +138,20 @@ func TestCoverage_HealthcareDicom(t *testing.T) {
},
}
- model, err := testCoverage(t, tc)
+ _, err := testCoverage(t, tc)
if err != nil {
t.Fatalf("process coverage: %+v", err)
}
-
- if model.CoveredCount != 12 {
- t.Fatalf("expected CoveredCount 12, got %d", model.CoveredCount)
- }
}
func TestCoverage_MachineLearningServicesWorkspacesJobs(t *testing.T) {
tc := testCase{
- name: "MachineLearningServicesWorkspacesJobs",
- resourceType: "Microsoft.MachineLearningServices/workspaces/jobs@2023-06-01-preview",
- method: "PUT",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.MachineLearningServices/workspaces/works1/jobs/job1",
+ name: "MachineLearningServicesWorkspacesJobs",
+ resourceType: "Microsoft.MachineLearningServices/workspaces/jobs@2024-04-01",
+ method: "PUT",
+ expectedCoveredCount: 11,
+ expectedTotalCount: 895,
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.MachineLearningServices/workspaces/works1/jobs/job1",
rawRequest: []string{
`{
"properties": {
@@ -199,23 +197,20 @@ func TestCoverage_MachineLearningServicesWorkspacesJobs(t *testing.T) {
},
}
- model, err := testCoverage(t, tc)
+ _, err := testCoverage(t, tc)
if err != nil {
t.Fatalf("process coverage: %+v", err)
}
-
- expected := 11
- if model.CoveredCount != expected {
- t.Fatalf("expected CoveredCount %d, got %d", expected, model.CoveredCount)
- }
}
func TestCoverage_MachineLearningServicesWorkspacesDataVersions(t *testing.T) {
tc := testCase{
- name: "MachineLearningServicesWorkspacesDataVersions",
- resourceType: "Microsoft.MachineLearningServices/workspaces/data/versions@2023-06-01-preview",
- method: "PUT",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.MachineLearningServices/workspaces/works1/data/data1/versions/version1",
+ name: "MachineLearningServicesWorkspacesDataVersions",
+ resourceType: "Microsoft.MachineLearningServices/workspaces/data/versions@2024-04-01",
+ method: "PUT",
+ expectedCoveredCount: 8,
+ expectedTotalCount: 29,
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.MachineLearningServices/workspaces/works1/data/data1/versions/version1",
rawRequest: []string{
`{
"properties": {
@@ -238,23 +233,20 @@ func TestCoverage_MachineLearningServicesWorkspacesDataVersions(t *testing.T) {
},
}
- model, err := testCoverage(t, tc)
+ _, err := testCoverage(t, tc)
if err != nil {
t.Fatalf("process coverage: %+v", err)
}
-
- expected := 8
- if model.CoveredCount != expected {
- t.Fatalf("expected CoveredCount %d, got %d", expected, model.CoveredCount)
- }
}
func TestCoverage_DeviceSecurityGroup(t *testing.T) {
tc := testCase{
- name: "DeviceSecurityGroup",
- resourceType: "Microsoft.Security/deviceSecurityGroups@2019-08-01",
- method: "PUT",
- apiPath: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/SampleRG/providers/Microsoft.Devices/iotHubs/sampleiothub/providers/Microsoft.Security/deviceSecurityGroups/samplesecuritygroup",
+ name: "DeviceSecurityGroup",
+ resourceType: "Microsoft.Security/deviceSecurityGroups@2019-08-01",
+ method: "PUT",
+ expectedCoveredCount: 5,
+ expectedTotalCount: 192,
+ apiPath: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/SampleRG/providers/Microsoft.Devices/iotHubs/sampleiothub/providers/Microsoft.Security/deviceSecurityGroups/samplesecuritygroup",
rawRequest: []string{
`{
"properties": {
@@ -273,30 +265,32 @@ func TestCoverage_DeviceSecurityGroup(t *testing.T) {
},
}
- model, err := testCoverage(t, tc)
+ _, err := testCoverage(t, tc)
if err != nil {
t.Fatalf("process coverage: %+v", err)
}
- expected := 5
- if model.CoveredCount != expected {
- t.Fatalf("expected CoveredCount %d, got %d", expected, model.CoveredCount)
- }
}
-func TestCoverage_DataMigrationServiceTasks(t *testing.T) {
- // Do we need to support cross file discriminator reference? Now seems only DataMigration has this. e.g., https://github.com/Azure/azure-rest-api-specs/blob/0ab5469dc0d75594f5747493dcfe8774e22d728f/specification/datamigration/resource-manager/Microsoft.DataMigration/stable/2021-06-30/definitions/ServiceTasks.json#L39
+func TestCoverage_SCVMM(t *testing.T) {
tc := testCase{
- name: "DataMigrationServiceTasks",
- resourceType: "Microsoft.DataMigration/services/serviceTasks@2021-06-30",
- method: "PUT",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/DmsSdkRg/providers/Microsoft.DataMigration/services/DmsSdkService/serviceTasks/DmsSdkTask",
+ name: "SCVMM",
+ resourceType: "Microsoft.ScVmm/virtualMachineInstances@2023-10-07",
+ method: "PUT",
+ expectedCoveredCount: 5,
+ expectedTotalCount: 39,
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/cli-test-rg-vmm/providers/Microsoft.HybridCompute/machines/test-vm-tf/providers/Microsoft.ScVmm/virtualMachineInstances/default",
rawRequest: []string{
`{
+ "extendedLocation": {
+ "name": "/subscriptions/12345678-1234-9876-4563-123456789012/resourcegroups/syntheticsscvmmcan/providers/microsoft.extendedlocation/customlocations/terraform-test-cl",
+ "type": "customLocation"
+ },
"properties": {
- "taskType": "Service.Check.OCI",
- "input": {
- "serverVersion": "NA"
+ "infrastructureProfile": {
+ "cloudId": "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/cli-test-rg-vmm/providers/Microsoft.SCVMM/Clouds/azcli-test-cloud",
+ "templateId": "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/cli-test-rg-vmm/providers/Microsoft.SCVMM/VirtualMachineTemplates/azcli-test-vm-template-win19",
+ "vmmServerId": "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/SyntheticsSCVMMCan/providers/microsoft.scvmm/vmmservers/tf-test-vmmserver"
}
}
}`,
@@ -309,46 +303,41 @@ func TestCoverage_DataMigrationServiceTasks(t *testing.T) {
}
}
-func TestCoverage_SCVMM(t *testing.T) {
+func TestCoverage_DataMigrationServiceTasks(t *testing.T) {
+ // Do we need to support cross file discriminator reference? Now seems only DataMigration has this. e.g., https://github.com/Azure/azure-rest-api-specs/blob/0ab5469dc0d75594f5747493dcfe8774e22d728f/specification/datamigration/resource-manager/Microsoft.DataMigration/stable/2021-06-30/definitions/ServiceTasks.json#L39
tc := testCase{
- name: "SCVMM",
- resourceType: "Microsoft.ScVmm/virtualMachineInstances@2023-10-07",
- method: "PUT",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/cli-test-rg-vmm/providers/Microsoft.HybridCompute/machines/test-vm-tf/providers/Microsoft.ScVmm/virtualMachineInstances/default",
+ name: "DataMigrationServiceTasks",
+ resourceType: "Microsoft.DataMigration/services/serviceTasks@2021-06-30",
+ method: "PUT",
+ expectedCoveredCount: 1,
+ expectedTotalCount: 615,
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/DmsSdkRg/providers/Microsoft.DataMigration/services/DmsSdkService/serviceTasks/DmsSdkTask",
rawRequest: []string{
`{
- "extendedLocation": {
- "name": "/subscriptions/12345678-1234-9876-4563-123456789012/resourcegroups/syntheticsscvmmcan/providers/microsoft.extendedlocation/customlocations/terraform-test-cl",
- "type": "customLocation"
- },
"properties": {
- "infrastructureProfile": {
- "cloudId": "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/cli-test-rg-vmm/providers/Microsoft.SCVMM/Clouds/azcli-test-cloud",
- "templateId": "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/cli-test-rg-vmm/providers/Microsoft.SCVMM/VirtualMachineTemplates/azcli-test-vm-template-win19",
- "vmmServerId": "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/SyntheticsSCVMMCan/providers/microsoft.scvmm/vmmservers/tf-test-vmmserver"
+ "taskType": "Service.Check.OCI",
+ "input": {
+ "serverVersion": "NA"
}
}
}`,
},
}
- model, err := testCoverage(t, tc)
+ _, err := testCoverage(t, tc)
if err != nil {
t.Fatalf("process coverage: %+v", err)
}
-
- expected := 5
- if model.CoveredCount != expected {
- t.Fatalf("expected CoveredCount %d, got %d", expected, model.CoveredCount)
- }
}
func TestCoverage_DataMigrationTasks(t *testing.T) {
tc := testCase{
- name: "DataMigrationTasks",
- resourceType: "Microsoft.DataMigration/services/projects/tasks@2021-06-30",
- method: "PUT",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/DmsSdkRg/providers/Microsoft.DataMigration/services/DmsSdkService/projects/DmsSdkProject/tasks/DmsSdkTask",
+ name: "DataMigrationTasks",
+ resourceType: "Microsoft.DataMigration/services/projects/tasks@2021-06-30",
+ method: "PUT",
+ expectedCoveredCount: 8,
+ expectedTotalCount: 615,
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/DmsSdkRg/providers/Microsoft.DataMigration/services/DmsSdkService/projects/DmsSdkProject/tasks/DmsSdkTask",
rawRequest: []string{
`{
"properties": {
@@ -369,23 +358,20 @@ func TestCoverage_DataMigrationTasks(t *testing.T) {
},
}
- model, err := testCoverage(t, tc)
+ _, err := testCoverage(t, tc)
if err != nil {
t.Fatalf("process coverage: %+v", err)
}
-
- expected := 8
- if model.CoveredCount != expected {
- t.Fatalf("expected CoveredCount %d, got %d", expected, model.CoveredCount)
- }
}
func TestCoverage_KeyVault(t *testing.T) {
tc := testCase{
- name: "KeyVault",
- resourceType: "Microsoft.KeyVault/vaults@2023-02-01",
- method: "PUT",
- apiPath: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sample-resource-group/providers/Microsoft.KeyVault/vaults/sample-vault",
+ name: "KeyVault",
+ resourceType: "Microsoft.KeyVault/vaults@2023-02-01",
+ method: "PUT",
+ expectedCoveredCount: 13,
+ expectedTotalCount: 28,
+ apiPath: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/sample-resource-group/providers/Microsoft.KeyVault/vaults/sample-vault",
rawRequest: []string{
`{
"location": "westus",
@@ -456,23 +442,20 @@ func TestCoverage_KeyVault(t *testing.T) {
},
}
- model, err := testCoverage(t, tc)
+ _, err := testCoverage(t, tc)
if err != nil {
t.Fatalf("process coverage: %+v", err)
}
-
- expected := 13
- if model.CoveredCount != expected {
- t.Fatalf("expected CoveredCount %d, got %d", expected, model.CoveredCount)
- }
}
func TestCoverage_StorageAccount(t *testing.T) {
tc := testCase{
- name: "StorageAccount",
- resourceType: "Microsoft.Storage/storageAccounts@2022-09-01",
- method: "PUT",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/res9101/providers/Microsoft.Storage/storageAccounts/sto4445",
+ name: "StorageAccount",
+ resourceType: "Microsoft.Storage/storageAccounts@2023-01-01",
+ method: "PUT",
+ expectedCoveredCount: 24,
+ expectedTotalCount: 69,
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/res9101/providers/Microsoft.Storage/storageAccounts/sto4445",
rawRequest: []string{
`{
"sku": {
@@ -525,23 +508,20 @@ func TestCoverage_StorageAccount(t *testing.T) {
}`,
},
}
- model, err := testCoverage(t, tc)
+ _, err := testCoverage(t, tc)
if err != nil {
t.Fatalf("process coverage: %+v", err)
}
-
- expected := 24
- if model.CoveredCount != expected {
- t.Fatalf("expected CoveredCount %d, got %d", expected, model.CoveredCount)
- }
}
func TestCoverage_VM(t *testing.T) {
tc := testCase{
- name: "VM",
- resourceType: "Microsoft.Compute/virtualMachines@2023-03-01",
- method: "PUT",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.Compute/virtualMachines/vm",
+ name: "VM",
+ resourceType: "Microsoft.Compute/virtualMachines@2024-03-01",
+ method: "PUT",
+ expectedCoveredCount: 20,
+ expectedTotalCount: 166,
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.Compute/virtualMachines/vm",
rawRequest: []string{
`{
"location": "westus",
@@ -596,23 +576,20 @@ func TestCoverage_VM(t *testing.T) {
},
}
- model, err := testCoverage(t, tc)
+ _, err := testCoverage(t, tc)
if err != nil {
t.Fatalf("process coverage: %+v", err)
}
-
- expected := 20
- if model.CoveredCount != expected {
- t.Fatalf("expected CoveredCount %d, got %d", expected, model.CoveredCount)
- }
}
func TestCoverage_VNet(t *testing.T) {
tc := testCase{
- name: "VNet",
- resourceType: "Microsoft.Network/virtualNetworks@2023-02-01",
- method: "PUT",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.Network/virtualNetworks/virtualNetwork",
+ name: "VNet",
+ resourceType: "Microsoft.Network/virtualNetworks@2024-01-01",
+ method: "PUT",
+ expectedCoveredCount: 4,
+ expectedTotalCount: 104,
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.Network/virtualNetworks/virtualNetwork",
rawRequest: []string{
`{
"properties": {
@@ -635,23 +612,20 @@ func TestCoverage_VNet(t *testing.T) {
},
}
- model, err := testCoverage(t, tc)
+ _, err := testCoverage(t, tc)
if err != nil {
t.Fatalf("process coverage: %+v", err)
}
-
- expected := 4
- if model.CoveredCount != expected {
- t.Fatalf("expected CoveredCount %d, got %d", expected, model.CoveredCount)
- }
}
func TestCoverage_DataCollectionRule(t *testing.T) {
tc := testCase{
- name: "DataCollectionRule",
- resourceType: "Microsoft.Insights/dataCollectionRules@2022-06-01",
- method: "PUT",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/test-resources/providers/Microsoft.Insights/dataCollectionRules/testDCR",
+ name: "DataCollectionRule",
+ resourceType: "Microsoft.Insights/dataCollectionRules@2022-06-01",
+ method: "PUT",
+ expectedCoveredCount: 65,
+ expectedTotalCount: 65,
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/test-resources/providers/Microsoft.Insights/dataCollectionRules/testDCR",
rawRequest: []string{
`{
"location": "westeurope",
@@ -975,10 +949,12 @@ func TestCoverage_DataCollectionRule(t *testing.T) {
func TestCoverage_WebSite(t *testing.T) {
tc := testCase{
- name: "WebSites",
- resourceType: "Microsoft.Web/sites@2022-09-01",
- method: "PUT",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/testrg123/providers/Microsoft.Web/sites/sitef6141",
+ name: "WebSites",
+ resourceType: "Microsoft.Web/sites@2023-01-01",
+ method: "PUT",
+ expectedCoveredCount: 3,
+ expectedTotalCount: 198,
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/testrg123/providers/Microsoft.Web/sites/sitef6141",
rawRequest: []string{
`{
"kind": "app",
@@ -990,15 +966,10 @@ func TestCoverage_WebSite(t *testing.T) {
},
}
- model, err := testCoverage(t, tc)
+ _, err := testCoverage(t, tc)
if err != nil {
t.Fatalf("process coverage: %+v", err)
}
-
- expected := 3
- if model.CoveredCount != expected {
- t.Fatalf("expected CoveredCount %d, got %d", expected, model.CoveredCount)
- }
}
func TestCoverage_AKS(t *testing.T) {
@@ -1082,23 +1053,20 @@ func TestCoverage_AKS(t *testing.T) {
}`},
}
- model, err := testCoverage(t, tc)
+ _, err := testCoverage(t, tc)
if err != nil {
t.Fatalf("process coverage: %+v", err)
}
-
- expected := 33
- if model.CoveredCount != expected {
- t.Fatalf("expected TotalCount %d, got %d", expected, model.CoveredCount)
- }
}
func TestCoverage_CosmosDB(t *testing.T) {
tc := testCase{
- name: "CosmosDB",
- resourceType: "Microsoft.DocumentDB/databaseAccounts@2024-05-15",
- method: "PUT",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.DocumentDB/databaseAccounts/testdb",
+ name: "CosmosDB",
+ resourceType: "Microsoft.DocumentDB/databaseAccounts@2024-05-15",
+ method: "PUT",
+ expectedCoveredCount: 33,
+ expectedTotalCount: 67,
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.DocumentDB/databaseAccounts/testdb",
rawRequest: []string{
`{
"location": "westus",
@@ -1187,11 +1155,6 @@ func TestCoverage_CosmosDB(t *testing.T) {
t.Fatalf("process coverage: %v", err)
}
- expected := 33
- if model.CoveredCount != expected {
- t.Fatalf("expected CoveredCount %d, got %d", expected, model.CoveredCount)
- }
-
if model.Properties == nil {
t.Fatalf("expected properties, got none")
}
@@ -1323,10 +1286,12 @@ func TestCoverage_CosmosDB(t *testing.T) {
func TestCoverage_DataFactoryPipelines(t *testing.T) {
tc := testCase{
- name: "DataFactoryPipelines",
- resourceType: "Microsoft.DataFactory/factories/pipelines@2018-06-01",
- method: "PUT",
- apiPath: "/subscriptions/12345678-1234-1234-1234-12345678abc/resourceGroups/exampleResourceGroup/providers/Microsoft.DataFactory/factories/exampleFactoryName/pipelines/examplePipeline",
+ name: "DataFactoryPipelines",
+ resourceType: "Microsoft.DataFactory/factories/pipelines@2018-06-01",
+ method: "PUT",
+ expectedCoveredCount: 11,
+ expectedTotalCount: 7239,
+ apiPath: "/subscriptions/12345678-1234-1234-1234-12345678abc/resourceGroups/exampleResourceGroup/providers/Microsoft.DataFactory/factories/exampleFactoryName/pipelines/examplePipeline",
rawRequest: []string{
`{
"properties": {
@@ -1411,23 +1376,20 @@ func TestCoverage_DataFactoryPipelines(t *testing.T) {
},
}
- model, err := testCoverage(t, tc)
+ _, err := testCoverage(t, tc)
if err != nil {
t.Fatalf("process coverage: %+v", err)
}
-
- expected := 11
- if model.CoveredCount != expected {
- t.Fatalf("expected TotalCount %d, got %d", expected, model.CoveredCount)
- }
}
func TestCoverage_DataFactoryLinkedServices(t *testing.T) {
tc := testCase{
- name: "DataFactoryLinkedServices",
- resourceType: "Microsoft.DataFactory/factories/linkedServices@2018-06-01",
- method: "PUT",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.DataFactory/factories/factory1/linkedServices/linked",
+ name: "DataFactoryLinkedServices",
+ resourceType: "Microsoft.DataFactory/factories/linkedServices@2018-06-01",
+ method: "PUT",
+ expectedCoveredCount: 2,
+ expectedTotalCount: 3450,
+ apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.DataFactory/factories/factory1/linkedServices/linked",
rawRequest: []string{
`{
"properties": {
@@ -1448,11 +1410,6 @@ func TestCoverage_DataFactoryLinkedServices(t *testing.T) {
t.Fatalf("process coverage: %+v", err)
}
- expected := 2
- if model.CoveredCount != expected {
- t.Fatalf("expected TotalCount %d, got %d", expected, model.CoveredCount)
- }
-
if model.Properties == nil {
t.Fatalf("expected properties, got none")
}
@@ -1524,14 +1481,35 @@ func TestCoverage_DataFactoryLinkedServices(t *testing.T) {
func testCoverage(t *testing.T, tc testCase) (*coverage.Model, error) {
apiVersion := strings.Split(tc.resourceType, "@")[1]
- swaggerModel, err := coverage.GetModelInfoFromLocalIndex(
- tc.apiPath,
- apiVersion,
- tc.method,
- "/home/wangta/project/go/azure-rest-api-specs/specification/",
- "index0910.json",
- )
+ var swaggerModel *coverage.SwaggerModel
+ var err error
+ azureRepoDir := os.Getenv("AZURE_REST_REPO_DIR")
+ if azureRepoDir != "" {
+ if strings.HasSuffix(azureRepoDir, "specification") {
+ azureRepoDir += "/"
+ }
+ if !strings.HasSuffix(normarlizePath(azureRepoDir), "specification/") {
+ t.Fatalf("AZURE_REST_REPO_DIR must specify the specification folder, e.g., AZURE_REST_REPO_DIR=\"/home/test/go/src/github.com/azure/azure-rest-api-specs/specification/\"")
+ }
+
+ t.Logf("AZURE_REST_REPO_DIR: %s", azureRepoDir)
+
+ swaggerModel, err = coverage.GetModelInfoFromLocalIndex(
+ tc.apiPath,
+ apiVersion,
+ tc.method,
+ azureRepoDir,
+ "./testdata/index.json",
+ )
+ } else {
+ swaggerModel, err = coverage.GetModelInfoFromIndex(
+ tc.apiPath,
+ apiVersion,
+ tc.method,
+ "./testdata/index.json",
+ )
+ }
t.Logf("swaggerModel: %+v", swaggerModel)
if err != nil {
@@ -1594,7 +1572,7 @@ func testCoverage(t *testing.T, tc testCase) (*coverage.Model, error) {
},
}
- storeCoverageReport(passReport, coverageReport, ".", fmt.Sprintf("test_coverage_report_%s.md", tc.name))
+ storeCoverageReport(passReport, coverageReport, "./testdata/", fmt.Sprintf("test_coverage_report_%s.md", tc.name))
return model, nil
}
diff --git a/coverage/expand.go b/coverage/expand.go
index 3fca964..a0af0e7 100644
--- a/coverage/expand.go
+++ b/coverage/expand.go
@@ -70,11 +70,20 @@ func getAllOfTable(swaggerPath string) (map[string]map[string]interface{}, error
return allOfTable, nil
}
+func trimPath(path string) string {
+ if strings.Contains(path, "\\") {
+ return strings.ReplaceAll(path, "\\.\\", "\\")
+ }
+ return strings.ReplaceAll(path, "/./", "/")
+}
+
func Expand(modelName, swaggerPath string) (*Model, error) {
if modelName == "" {
return nil, fmt.Errorf("modelName is empty")
}
+ swaggerPath = trimPath(swaggerPath)
+
doc, err := loadSwagger(swaggerPath)
if err != nil {
return nil, err
@@ -330,6 +339,7 @@ func SchemaNamePathFromRef(swaggerPath string, ref openapiSpec.Ref) (schemaName
} else {
swaggerPath, _ := filepath.Split(swaggerPath)
schemaPath = swaggerPath + schemaPath
+ schemaPath = trimPath(schemaPath)
}
fragments := strings.Split(refUrl.Fragment, "/")
diff --git a/coverage/expand_test.go b/coverage/expand_test.go
index e84f72b..58b3f56 100644
--- a/coverage/expand_test.go
+++ b/coverage/expand_test.go
@@ -123,7 +123,7 @@ func TestExpandAll(t *testing.T) {
t.Fatalf("AZURE_REST_REPO_DIR must specify the specification folder, e.g., AZURE_REST_REPO_DIR=\"/home/test/go/src/github.com/azure/azure-rest-api-specs/specification/\"")
}
- t.Logf("azure repo dir: %s", azureRepoDir)
+ t.Logf("AZURE_REST_REPO_DIR: %s", azureRepoDir)
testResultFilePath := os.Getenv("TEST_RESULT_PATH")
From 3cd01850dbf1bcc24c018fa06fcad25093247b1a Mon Sep 17 00:00:00 2001
From: teowa <104055472+teowa@users.noreply.github.com>
Date: Wed, 11 Sep 2024 02:43:11 +0000
Subject: [PATCH 3/9] remove unused
---
coverage/report.go | 29 -----------------------------
1 file changed, 29 deletions(-)
diff --git a/coverage/report.go b/coverage/report.go
index 6f5f09c..5a96020 100644
--- a/coverage/report.go
+++ b/coverage/report.go
@@ -300,35 +300,6 @@ func getCoverageCount(model *Model) string {
return fmt.Sprintf("(%v/%v)", model.CoveredCount, model.TotalCount)
}
-// func getChildReport(name string, model *Model) string {
-// var style, report string
-
-// style = getStyle(model.IsFullyCovered)
-
-// if hasNoDetail(model) {
-// // leaf property
-// report = fmt.Sprintf(`
-//
-// %[3]v
-
-// `, model.Identifier, style, name)
-// } else {
-// childReport := getReport(model, model.ModelName)
-// sort.Strings(childReport)
-// report = fmt.Sprintf(`
-//
-// %[3]v %[4]v
-//
-
-// %[5]v
-
-//
-// `, model.Identifier, style, name, getCoverageCount(model), strings.Join(childReport, "\n\n"))
-// }
-
-// return report
-// }
-
func hasNoDetail(model *Model) bool {
if model.Properties == nil && model.Variants == nil && model.Item == nil && (!isBoolEnumDisplayed || (model.Bool == nil && model.Enum == nil)) {
return true
From 1effd4c4f5c7501719171951489d1bea5ec5d57e Mon Sep 17 00:00:00 2001
From: teowa <104055472+teowa@users.noreply.github.com>
Date: Wed, 11 Sep 2024 02:47:15 +0000
Subject: [PATCH 4/9] update report coverage count
---
coverage/report.go | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/coverage/report.go b/coverage/report.go
index 5a96020..e4acf8a 100644
--- a/coverage/report.go
+++ b/coverage/report.go
@@ -79,7 +79,7 @@ ${coverage_details}
if v.Model.IsFullyCovered {
fullyCoveredPath = append(fullyCoveredPath, v.DisplayName)
} else {
- partiallyCoveredPath = append(partiallyCoveredPath, fmt.Sprintf("%v (%v/%v)", v.DisplayName, v.Model.CoveredCount, v.Model.TotalCount))
+ partiallyCoveredPath = append(partiallyCoveredPath, fmt.Sprintf("%v (%v/%v)", v.DisplayName, v.Model.RootCoveredCount, v.Model.RootTotalCount))
}
}
@@ -136,11 +136,11 @@ func (c *CoverageReport) MarkdownContentCompact() string {
for _, v := range c.Coverages {
coverage := 100.0
if v.Model.TotalCount > 0 {
- coverage = float64(v.Model.CoveredCount * 100 / v.Model.TotalCount)
+ coverage = float64(v.Model.RootCoveredCount * 100 / v.Model.RootTotalCount)
}
- content += fmt.Sprintf("|%s|%d|%d|%.1f%%|\n", v.DisplayName, v.Model.CoveredCount, v.Model.TotalCount, coverage)
- total += v.Model.TotalCount
- covered += v.Model.CoveredCount
+ content += fmt.Sprintf("|%s|%d|%d|%.1f%%|\n", v.DisplayName, v.Model.RootCoveredCount, v.Model.RootTotalCount, coverage)
+ total += v.Model.RootTotalCount
+ covered += v.Model.RootCoveredCount
}
coverage := 100.0
From 8a2d91d5731e57fffca71119e6340f3e9eb3d4b5 Mon Sep 17 00:00:00 2001
From: teowa <104055472+teowa@users.noreply.github.com>
Date: Wed, 11 Sep 2024 03:18:04 +0000
Subject: [PATCH 5/9] fix test
---
coverage/coverage_test.go | 32 +++-----------------------------
coverage/index.go | 4 ++--
2 files changed, 5 insertions(+), 31 deletions(-)
diff --git a/coverage/coverage_test.go b/coverage/coverage_test.go
index 5016a88..8eda804 100644
--- a/coverage/coverage_test.go
+++ b/coverage/coverage_test.go
@@ -61,28 +61,6 @@ func TestCoverage_ResourceGroup(t *testing.T) {
}
}
-func TestCoverage_AzureTerraform(t *testing.T) {
- tc := testCase{
- name: "AzureTerraform",
- resourceType: "Microsoft.AzureTerraform@2023-07-01-preview",
- method: "POST",
- apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/providers/Microsoft.AzureTerraform/exportTerraform",
- expectedCoveredCount: 2,
- expectedTotalCount: 25,
- rawRequest: []string{
- `{
- "resourceGroupName" : "rg1",
- "type" : "ExportResourceGroup"
- }`,
- },
- }
-
- _, err := testCoverage(t, tc)
- if err != nil {
- t.Fatalf("process coverage: %+v", err)
- }
-}
-
func TestCoverage_HealthcareDicom(t *testing.T) {
tc := testCase{
name: "HealthcareApisDicom",
@@ -91,7 +69,6 @@ func TestCoverage_HealthcareDicom(t *testing.T) {
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rgName/providers/Microsoft.HealthcareApis/workspaces/workspaceName/dicomservices/dicomServiceName",
expectedCoveredCount: 12,
expectedTotalCount: 14,
- // bulkImportConfiguration property not in swagger
rawRequest: []string{
`{
"identity": {
@@ -120,9 +97,6 @@ func TestCoverage_HealthcareDicom(t *testing.T) {
"*"
]
},
- "bulkImportConfiguration": {
- "enabled": false
- },
"enableDataPartitions": false,
"encryption": {
"customerManagedKeyEncryption": {
@@ -309,15 +283,15 @@ func TestCoverage_DataMigrationServiceTasks(t *testing.T) {
name: "DataMigrationServiceTasks",
resourceType: "Microsoft.DataMigration/services/serviceTasks@2021-06-30",
method: "PUT",
- expectedCoveredCount: 1,
+ expectedCoveredCount: 2,
expectedTotalCount: 615,
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/DmsSdkRg/providers/Microsoft.DataMigration/services/DmsSdkService/serviceTasks/DmsSdkTask",
rawRequest: []string{
`{
"properties": {
- "taskType": "Service.Check.OCI",
+ "taskType": "ConnectToSource.MySql",
"input": {
- "serverVersion": "NA"
+ "targetPlatform": "string"
}
}
}`,
diff --git a/coverage/index.go b/coverage/index.go
index 7eb6697..97538d2 100644
--- a/coverage/index.go
+++ b/coverage/index.go
@@ -178,7 +178,7 @@ func GetModelInfoFromIndex(resourceId, apiVersion, method, indexFilePath string)
}
ref, err := index.Lookup(method, *uRL)
if err != nil {
- return nil, fmt.Errorf("lookup PUT URL %s in index: %+v", resourceURL, err)
+ return nil, fmt.Errorf("lookup %s URL %s in index: %+v", method, resourceURL, err)
}
model, err := GetModelInfoFromIndexRef(openapispec.Ref{Ref: *ref}, azureRepoURL)
@@ -223,7 +223,7 @@ func GetModelInfoFromLocalIndex(resourceId, apiVersion, method, swaggerRepo, ind
}
ref, err := index.Lookup(method, *uRL)
if err != nil {
- return nil, fmt.Errorf("lookup PUT URL %s in index: %+v", resourceURL, err)
+ return nil, fmt.Errorf("lookup %s URL %s in index: %+v", method, resourceURL, err)
}
model, err := GetModelInfoFromIndexRef(openapispec.Ref{Ref: *ref}, swaggerRepo)
From 2139807d586c9ab1ee8f579fdc52b4fbe0acc7cf Mon Sep 17 00:00:00 2001
From: teowa <104055472+teowa@users.noreply.github.com>
Date: Wed, 11 Sep 2024 04:22:15 +0000
Subject: [PATCH 6/9] fix error message level
---
coverage/coverage.go | 7 +++----
coverage/coverage_test.go | 11 ++++++-----
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/coverage/coverage.go b/coverage/coverage.go
index d2b8299..270b3c0 100644
--- a/coverage/coverage.go
+++ b/coverage/coverage.go
@@ -131,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
@@ -192,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 {
diff --git a/coverage/coverage_test.go b/coverage/coverage_test.go
index 8eda804..c5cd972 100644
--- a/coverage/coverage_test.go
+++ b/coverage/coverage_test.go
@@ -291,7 +291,9 @@ func TestCoverage_DataMigrationServiceTasks(t *testing.T) {
"properties": {
"taskType": "ConnectToSource.MySql",
"input": {
- "targetPlatform": "string"
+ "sourceConnectionInfo": {
+ "serverName": "mySqlService"
+ }
}
}
}`,
@@ -873,8 +875,7 @@ func TestCoverage_DataCollectionRule(t *testing.T) {
"extensions": [
{
"streams": [
- "Microsoft-WindowsEvent",
- "Microsoft-ServiceMap"
+ "Microsoft-WindowsEvent"
],
"inputDataSources": [
"test-datasource-wineventlog"
@@ -961,7 +962,7 @@ func TestCoverage_AKS(t *testing.T) {
"archv2": ""
},
"sku": {
- "name": "Basic",
+ "name": "Base",
"tier": "Free"
},
"properties": {
@@ -1505,7 +1506,7 @@ func testCoverage(t *testing.T, tc testCase) (*coverage.Model, error) {
request := map[string]interface{}{}
err = json.Unmarshal([]byte(rq), &request)
if err != nil {
- t.Error(err)
+ t.Errorf("error unmarshal request json: %v", err)
}
model.MarkCovered(request)
From f49b539bfa72d344d524049c3cd82107127d1e03 Mon Sep 17 00:00:00 2001
From: teowa <104055472+teowa@users.noreply.github.com>
Date: Wed, 11 Sep 2024 04:36:00 +0000
Subject: [PATCH 7/9] fix vnet test
---
coverage/coverage_test.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/coverage/coverage_test.go b/coverage/coverage_test.go
index c5cd972..b3e4a17 100644
--- a/coverage/coverage_test.go
+++ b/coverage/coverage_test.go
@@ -564,7 +564,7 @@ func TestCoverage_VNet(t *testing.T) {
resourceType: "Microsoft.Network/virtualNetworks@2024-01-01",
method: "PUT",
expectedCoveredCount: 4,
- expectedTotalCount: 104,
+ expectedTotalCount: 103,
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.Network/virtualNetworks/virtualNetwork",
rawRequest: []string{
`{
From bc1d049ae0026efab69837a0f93987a87188bde2 Mon Sep 17 00:00:00 2001
From: teowa <104055472+teowa@users.noreply.github.com>
Date: Wed, 11 Sep 2024 05:25:20 +0000
Subject: [PATCH 8/9] always match base discriminator
---
coverage/coverage.go | 6 +++---
coverage/coverage_test.go | 21 ++++++++++-----------
2 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/coverage/coverage.go b/coverage/coverage.go
index 270b3c0..577f223 100644
--- a/coverage/coverage.go
+++ b/coverage/coverage.go
@@ -32,7 +32,7 @@ type Model struct {
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
}
@@ -171,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
diff --git a/coverage/coverage_test.go b/coverage/coverage_test.go
index b3e4a17..748626c 100644
--- a/coverage/coverage_test.go
+++ b/coverage/coverage_test.go
@@ -123,7 +123,7 @@ func TestCoverage_MachineLearningServicesWorkspacesJobs(t *testing.T) {
name: "MachineLearningServicesWorkspacesJobs",
resourceType: "Microsoft.MachineLearningServices/workspaces/jobs@2024-04-01",
method: "PUT",
- expectedCoveredCount: 11,
+ expectedCoveredCount: 19,
expectedTotalCount: 895,
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.MachineLearningServices/workspaces/works1/jobs/job1",
rawRequest: []string{
@@ -182,7 +182,7 @@ func TestCoverage_MachineLearningServicesWorkspacesDataVersions(t *testing.T) {
name: "MachineLearningServicesWorkspacesDataVersions",
resourceType: "Microsoft.MachineLearningServices/workspaces/data/versions@2024-04-01",
method: "PUT",
- expectedCoveredCount: 8,
+ expectedCoveredCount: 15,
expectedTotalCount: 29,
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.MachineLearningServices/workspaces/works1/data/data1/versions/version1",
rawRequest: []string{
@@ -218,7 +218,7 @@ func TestCoverage_DeviceSecurityGroup(t *testing.T) {
name: "DeviceSecurityGroup",
resourceType: "Microsoft.Security/deviceSecurityGroups@2019-08-01",
method: "PUT",
- expectedCoveredCount: 5,
+ expectedCoveredCount: 10,
expectedTotalCount: 192,
apiPath: "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/SampleRG/providers/Microsoft.Devices/iotHubs/sampleiothub/providers/Microsoft.Security/deviceSecurityGroups/samplesecuritygroup",
rawRequest: []string{
@@ -243,7 +243,6 @@ func TestCoverage_DeviceSecurityGroup(t *testing.T) {
if err != nil {
t.Fatalf("process coverage: %+v", err)
}
-
}
func TestCoverage_SCVMM(t *testing.T) {
@@ -283,7 +282,7 @@ func TestCoverage_DataMigrationServiceTasks(t *testing.T) {
name: "DataMigrationServiceTasks",
resourceType: "Microsoft.DataMigration/services/serviceTasks@2021-06-30",
method: "PUT",
- expectedCoveredCount: 2,
+ expectedCoveredCount: 3,
expectedTotalCount: 615,
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/DmsSdkRg/providers/Microsoft.DataMigration/services/DmsSdkService/serviceTasks/DmsSdkTask",
rawRequest: []string{
@@ -311,7 +310,7 @@ func TestCoverage_DataMigrationTasks(t *testing.T) {
name: "DataMigrationTasks",
resourceType: "Microsoft.DataMigration/services/projects/tasks@2021-06-30",
method: "PUT",
- expectedCoveredCount: 8,
+ expectedCoveredCount: 9,
expectedTotalCount: 615,
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/DmsSdkRg/providers/Microsoft.DataMigration/services/DmsSdkService/projects/DmsSdkProject/tasks/DmsSdkTask",
rawRequest: []string{
@@ -1039,7 +1038,7 @@ func TestCoverage_CosmosDB(t *testing.T) {
name: "CosmosDB",
resourceType: "Microsoft.DocumentDB/databaseAccounts@2024-05-15",
method: "PUT",
- expectedCoveredCount: 33,
+ expectedCoveredCount: 34,
expectedTotalCount: 67,
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.DocumentDB/databaseAccounts/testdb",
rawRequest: []string{
@@ -1264,7 +1263,7 @@ func TestCoverage_DataFactoryPipelines(t *testing.T) {
name: "DataFactoryPipelines",
resourceType: "Microsoft.DataFactory/factories/pipelines@2018-06-01",
method: "PUT",
- expectedCoveredCount: 11,
+ expectedCoveredCount: 13,
expectedTotalCount: 7239,
apiPath: "/subscriptions/12345678-1234-1234-1234-12345678abc/resourceGroups/exampleResourceGroup/providers/Microsoft.DataFactory/factories/exampleFactoryName/pipelines/examplePipeline",
rawRequest: []string{
@@ -1362,7 +1361,7 @@ func TestCoverage_DataFactoryLinkedServices(t *testing.T) {
name: "DataFactoryLinkedServices",
resourceType: "Microsoft.DataFactory/factories/linkedServices@2018-06-01",
method: "PUT",
- expectedCoveredCount: 2,
+ expectedCoveredCount: 3,
expectedTotalCount: 3450,
apiPath: "/subscriptions/12345678-1234-9876-4563-123456789012/resourceGroups/rg1/providers/Microsoft.DataFactory/factories/factory1/linkedServices/linked",
rawRequest: []string{
@@ -1397,8 +1396,8 @@ func TestCoverage_DataFactoryLinkedServices(t *testing.T) {
t.Fatalf("expected properties type property, got none")
}
- if (*(*model.Properties)["properties"].Properties)["type"].IsAnyCovered {
- t.Fatalf("expected properties type IsAnyCovered false, got true")
+ if !(*(*model.Properties)["properties"].Properties)["type"].IsAnyCovered {
+ t.Fatalf("expected properties type IsAnyCovered true, got false")
}
if (*model.Properties)["properties"].Discriminator == nil {
From a88e1511c37ae4c89830cdaf0f25542fe1b1f04c Mon Sep 17 00:00:00 2001
From: teowa <104055472+teowa@users.noreply.github.com>
Date: Wed, 11 Sep 2024 05:43:33 +0000
Subject: [PATCH 9/9] suppress error message for base discriminator prop match
---
coverage/coverage.go | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/coverage/coverage.go b/coverage/coverage.go
index 577f223..d57918f 100644
--- a/coverage/coverage.go
+++ b/coverage/coverage.go
@@ -93,13 +93,14 @@ func (m *Model) CredScan(root interface{}, secrets map[string]string) {
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
+
+ logrus.Warnf("unexpected key %s in %s", k, m.Identifier)
continue
}
if _, ok := (*m.Properties)[k]; !ok {
- if !m.HasAdditionalProperties {
+ if !m.HasAdditionalProperties && m.Discriminator == nil {
logrus.Errorf("unexpected key %s in %s", k, m.Identifier)
continue
}
@@ -194,10 +195,12 @@ func (m *Model) MarkCovered(root interface{}) {
if m.Properties == nil {
// 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
+ logrus.Warnf("unexpected key %s in %s", k, m.Identifier)
+
continue
}
if _, ok := (*m.Properties)[k]; !ok {
- if !m.HasAdditionalProperties {
+ if !m.HasAdditionalProperties && m.Discriminator == nil {
logrus.Errorf("unexpected key %s in %s", k, m.Identifier)
continue
}