Skip to content

Commit

Permalink
Add windup analysis load
Browse files Browse the repository at this point in the history
Adding analysis-windup package to hack dir to allow take known
application analysis testcases, run analysis on Konveyor ~>0.2 and dump
analysis results in api.Analysis&api.Issue format.

This should help for getting samples for LSP&Windup analyzers feature parity.

Signed-off-by: Marek Aufart <maufart@redhat.com>
  • Loading branch information
aufi committed Sep 8, 2023
1 parent 16f8aba commit ca6b94e
Show file tree
Hide file tree
Showing 7 changed files with 255 additions and 25 deletions.
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
VENDOR_DIR ?= /tmp/konveyor-vendor
ARCH ?= amd64
MINIKUBE_IP ?= `minikube ip`
# HUB_BASE_URL="http://${MINIKUBE_IP}/hub"

# Setup local minikube with tackle - work in progress (TODO: enable auth)
# This is for local setup, CI uses shared github actions
Expand Down Expand Up @@ -44,11 +45,11 @@ test-tier2:

# Application analysis tests.
test-analysis:
HUB_BASE_URL="http://${MINIKUBE_IP}/hub" go test -count=1 -timeout 7200s -v ./analysis/...
go test -count=1 -timeout 7200s -v ./analysis/...

# Metrics.
test-metrics:
HUB_BASE_URL="http://${MINIKUBE_IP}/hub" ginkgo -v ./e2e/metrics/...
ginkgo -v ./e2e/metrics/...

# Add next features tests here and call the target from appropriate tier.

Expand Down
17 changes: 4 additions & 13 deletions analysis/analysis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (

"github.com/konveyor/go-konveyor-tests/hack/addon"
"github.com/konveyor/go-konveyor-tests/hack/uniq"
"github.com/konveyor/go-konveyor-tests/hack/windupreport"
"github.com/konveyor/tackle2-hub/api"
"github.com/konveyor/tackle2-hub/binding"
"github.com/konveyor/tackle2-hub/test/assert"
Expand Down Expand Up @@ -63,7 +62,7 @@ func TestApplicationAnalysis(t *testing.T) {
// Prepare and submit the analyze task.
// tc.Task.Addon = analyzerAddon
tc.Task.Application = &api.Ref{ID: tc.Application.ID}
taskData := tc.Task.Data.(addon.Data) // addon / addonwindup
taskData := tc.Task.Data.(addon.Data)
//for _, r := range tc.CustomRules {
// taskData.Rules = append(taskData.Rules, api.Ref{ID: r.ID, Name: r.Name})
//}
Expand Down Expand Up @@ -96,17 +95,9 @@ func TestApplicationAnalysis(t *testing.T) {

var gotAnalysis api.Analysis

if tc.Task.Addon == "windup" {
// Old Windup check version parsing windup HTML report
CheckWindupReportContent(t, &tc)

// Parse report for windup, to api.Analysis structure
gotAnalysis = windupreport.Parse(t, tc.Application.ID)
} else {
// Get LSP analysis directly form Hub API
analysisPath := binding.Path(api.AppAnalysisRoot).Inject(binding.Params{api.ID: tc.Application.ID})
assert.Should(t, Client.Get(analysisPath, &gotAnalysis))
}
// Get LSP analysis directly form Hub API
analysisPath := binding.Path(api.AppAnalysisRoot).Inject(binding.Params{api.ID: tc.Application.ID})
assert.Should(t, Client.Get(analysisPath, &gotAnalysis))

// Check the analysis result (effort, issues, etc).
if gotAnalysis.Effort != tc.Analysis.Effort {
Expand Down
2 changes: 1 addition & 1 deletion analysis/analyzer_defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"github.com/konveyor/tackle2-hub/api"
)

var AnalyzeLsp = api.Task{
var Analyze = api.Task{
State: "Ready", // Created / Ready
Data: defaultAnalyzerData,
Addon: "analyzer",
Expand Down
6 changes: 0 additions & 6 deletions analysis/test_cases.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,3 @@ var Tier1TestCases = []TC{
var Tier2TestCases = []TC{
Daytrader,
}

//
// Switch analyzers:
// - AnalyzeLsp
// - AnalyzeWindup
var Analyze = AnalyzeLsp
216 changes: 216 additions & 0 deletions hack/analysis-windup/analysis_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
package analysiswindup

import (
"fmt"
"os"
"testing"
"time"

"github.com/konveyor/go-konveyor-tests/analysis"
"github.com/konveyor/go-konveyor-tests/hack/addonwindup"
"github.com/konveyor/go-konveyor-tests/hack/uniq"
"github.com/konveyor/go-konveyor-tests/hack/windupreport"
"github.com/konveyor/tackle2-hub/api"
"github.com/konveyor/tackle2-hub/test/assert"
)

// Test application analysis
func TestApplicationAnalysis(t *testing.T) {
// Find right test cases for given Tier (include Tier0 always).
testCases := analysis.Tier0TestCases
_, tier1 := os.LookupEnv("TIER1")
if tier1 {
testCases = analysis.Tier1TestCases
}
_, tier2 := os.LookupEnv("TIER2")
if tier2 {
testCases = analysis.Tier2TestCases
}
// Run test cases.
for _, testcase := range testCases {
t.Run(testcase.Name, func(t *testing.T) {
// Prepare parallel execution if env variable PARALLEL is set.
tc := testcase
_, parallel := os.LookupEnv("PARALLEL")
if parallel {
t.Parallel()
}

// Create the application.
uniq.ApplicationName(&tc.Application)
assert.Should(t, RichClient.Application.Create(&tc.Application))

// Prepare custom rules.
for i := range tc.CustomRules {
r := &tc.CustomRules[i]
uniq.RuleSetName(r)
// ruleFiles := []api.File{}
rules := []api.Rule{}
for _, rule := range r.Rules {
ruleFile, err := RichClient.File.Put(rule.File.Name)
assert.Should(t, err)
rules = append(rules, api.Rule{
File: &api.Ref{
ID: ruleFile.ID,
},
})
// ruleFiles = append(ruleFiles, *ruleFile)
}
r.Rules = rules
assert.Should(t, RichClient.RuleSet.Create(r))
}

// Prepare and submit the analyze task.
tc.Task = AnalyzeWindup
tc.Task.Application = &api.Ref{ID: tc.Application.ID}
taskData := tc.Task.Data.(addonwindup.Data) // addon / addonwindup
//for _, r := range tc.CustomRules {
// taskData.Rules = append(taskData.Rules, api.Ref{ID: r.ID, Name: r.Name})
//}
if len(tc.Sources) > 0 {
taskData.Sources = tc.Sources
}
if len(tc.Targets) > 0 {
taskData.Targets = tc.Targets
}
//if tc.Rules.Path != "" { // TODO: better rules handling
// taskData.Rules = tc.Rules
//}
tc.Task.Data = taskData
assert.Should(t, RichClient.Task.Create(&tc.Task))

// Wait until task finishes
var task *api.Task
var err error
for i := 0; i < Retry; i++ {
task, err = RichClient.Task.Get(tc.Task.ID)
if err != nil || task.State == "Succeeded" || task.State == "Failed" {
break
}
time.Sleep(Wait)
}

if task.State != "Succeeded" {
t.Errorf("Analyze Task failed. Details: %+v", task)
}

var gotAnalysis api.Analysis

// Old Windup check version parsing windup HTML report
CheckWindupReportContent(t, &tc)

// Parse report for windup, to api.Analysis structure
gotAnalysis = windupreport.Parse(t, tc.Application.ID)
DumpAnalysis(t, gotAnalysis)

// Check the analysis result (effort, issues, etc).
if gotAnalysis.Effort != tc.Analysis.Effort {
t.Errorf("Different effort error. Got %d, expected %d", gotAnalysis.Effort, tc.Analysis.Effort)
}

//// Check the analysis issues
//if len(gotAnalysis.Issues) != len(tc.Analysis.Issues) {
// t.Errorf("Different amount of issues error. Got %d, expected %d.", len(gotAnalysis.Issues), len(tc.Analysis.Issues))
//}
//for i, got := range gotAnalysis.Issues {
// expected := tc.Analysis.Issues[i]
// if got.Category != expected.Category || got.RuleSet != expected.RuleSet || got.Rule != expected.Rule || got.Effort != expected.Effort || !strings.HasPrefix(got.Description, expected.Description) {
// t.Errorf("\nDifferent issue error. Got %+v, expected %+v.\n\n", got, expected)
// }
//
// // Incidents check.
// if len(expected.Incidents) == 0 {
// t.Log("Skipping empty expected Incidents check.")
// break
// }
// if len(got.Incidents) != len(expected.Incidents) {
// t.Errorf("Different amount of incident error. Got %d, expected %d.", len(got.Incidents), len(expected.Incidents))
// }
// for j, gotInc := range got.Incidents {
// expectedInc := expected.Incidents[j]
// if gotInc.File != expectedInc.File || gotInc.Line != expectedInc.Line || !strings.HasPrefix(gotInc.Message, expectedInc.Message) {
// t.Errorf("\nDifferent incident error. Got %+v, expected %+v.\n\n", gotInc, expectedInc)
// }
// }
//}
//
//// Check analysis-created Tags.
//gotApp, _ := RichClient.Application.Get(tc.Application.ID)
//for _, expected := range tc.AnalysisTags {
// found := false
// for _, got := range gotApp.Tags {
// if got.Name == expected.Name && got.Source == "Analysis" {
// found = true
// break
// }
// }
// if !found {
// t.Errorf("Missing expected tag '%s'.\n", expected.Name)
// }
//}

// TODO(maufart): analysis tagger creates duplicate tags, not sure if it is expected, check later.
//if len(tc.AnalysisTags) != len(gotApp.Tags) {
// t.Errorf("Different Tags amount error. Got: %d, expected: %d.\n", len(gotApp.Tags), len(tc.AnalysisTags))
//}
//found, gotAnalysisTags := 0, 0
//for _, t := range gotApp.Tags {
// if t.Source == "Analysis" {
// gotAnalysisTags = gotAnalysisTags + 1
// for _, expectedTag := range tc.AnalysisTags {
// if expectedTag.Name == t.Name {
// found = found + 1
// break
// }
// }
// }
//}
//if found != len(tc.AnalysisTags) || found < gotAnalysisTags {
// t.Errorf("Analysis Tags don't match. Got:\n %v\nexpected:\n %v\n", gotApp.Tags, tc.AnalysisTags)
//}

// Allow skip cleanup to keep applications and analysis results for debugging etc.
_, keep := os.LookupEnv("KEEP")
if keep {
return
}
// Cleanup Application.
assert.Must(t, RichClient.Application.Delete(tc.Application.ID))

// Cleanup custom rules and their files.
for _, r := range tc.CustomRules {
assert.Should(t, RichClient.RuleSet.Delete(r.ID))
for _, rl := range r.Rules {
assert.Should(t, RichClient.File.Delete(rl.File.ID))
}
}
})
}
}

func DumpAnalysis(t *testing.T, analysis api.Analysis) {
fmt.Println("GOT ANALYSIS DUMP:")
fmt.Printf("api.Analysis{\n")
fmt.Printf(" Effort: %d,\n", analysis.Effort)
fmt.Printf(" Issues: []api.Issue{\n")
for _, issue := range analysis.Issues {
fmt.Printf(" {\n")
fmt.Printf(" Category: \"%s\",\n", issue.Category)
fmt.Printf(" Description: \"%s\",\n", issue.Description)
fmt.Printf(" Effort: %d,\n", issue.Effort)
fmt.Printf(" RuleSet: \"%s\",\n", issue.RuleSet)
fmt.Printf(" Rule: \"%s\",\n", issue.Rule)
fmt.Printf(" Incidents: []api.Incident{\n")
for _, incident := range issue.Incidents {
fmt.Printf(" {\n")
fmt.Printf(" File: \"%s\",\n", incident.File)
fmt.Printf(" Line: \"%d\",\n", incident.Line)
fmt.Printf(" Message: \"%s\",\n", incident.Message)
fmt.Printf(" },\n")
}
fmt.Printf(" },\n")
fmt.Printf(" },\n")
}
fmt.Printf(" }\n")
fmt.Printf("}\n")
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package analysis
package analysiswindup

import (
"os"
Expand All @@ -7,6 +7,7 @@ import (
"strings"
"testing"

"github.com/konveyor/go-konveyor-tests/analysis"
"github.com/konveyor/go-konveyor-tests/hack/addonwindup"
"github.com/konveyor/tackle2-hub/api"
"github.com/konveyor/tackle2-hub/test/assert"
Expand Down Expand Up @@ -49,7 +50,7 @@ var defaultWindupData = addonwindup.Data{
},
}

func GetReportText(t *testing.T, tc *TC, path string) (text string) {
func GetReportText(t *testing.T, tc *analysis.TC, path string) (text string) {
// Get report file.
dirName, err := os.MkdirTemp("/tmp", tc.Name)
assert.Must(t, err)
Expand All @@ -67,7 +68,7 @@ func GetReportText(t *testing.T, tc *TC, path string) (text string) {
return
}

func CheckWindupReportContent(t *testing.T, tc *TC) {
func CheckWindupReportContent(t *testing.T, tc *analysis.TC) {
// Check the report content.
for path, expectedElems := range tc.ReportContent {
content := GetReportText(t, tc, path)
Expand Down
27 changes: 27 additions & 0 deletions hack/analysis-windup/pkg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package analysiswindup

import (
"time"

"github.com/konveyor/tackle2-hub/binding"
"github.com/konveyor/tackle2-hub/test/api/client"
)

var (
// Setup Hub API client
Client *binding.Client
RichClient *binding.RichClient

// Analysis waiting loop 5 minutes (60 * 5s)
Retry = 100
Wait = 5 * time.Second
)

func init() {
// Prepare RichClient and login to Hub API (configured from env variables).
RichClient = client.PrepareRichClient()

// Access REST client directly (some test API call need it)
Client = RichClient.Client
}

0 comments on commit ca6b94e

Please sign in to comment.