Skip to content

Commit

Permalink
Merge pull request #10380 from daehyeok/profile_list_light
Browse files Browse the repository at this point in the history
Add -l/--light option for profile list command.
  • Loading branch information
medyagh authored Feb 11, 2021
2 parents 984b079 + f457bde commit a3609d3
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 28 deletions.
23 changes: 21 additions & 2 deletions cmd/minikube/cmd/config/profile_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import (
)

var output string
var isLight bool

var profileListCmd = &cobra.Command{
Use: "list",
Expand All @@ -58,8 +59,18 @@ var profileListCmd = &cobra.Command{
},
}

func listProfiles() (validProfiles, invalidProfiles []*config.Profile, err error) {
if isLight {
validProfiles, err = config.ListValidProfiles()
} else {
validProfiles, invalidProfiles, err = config.ListProfiles()
}

return validProfiles, invalidProfiles, err
}

func printProfilesTable() {
validProfiles, invalidProfiles, err := config.ListProfiles()
validProfiles, invalidProfiles, err := listProfiles()

if err != nil {
klog.Warningf("error loading profiles: %v", err)
Expand All @@ -75,6 +86,13 @@ func printProfilesTable() {
}

func updateProfilesStatus(profiles []*config.Profile) {
if isLight {
for _, p := range profiles {
p.Status = "Skipped"
}
return
}

api, err := machine.NewAPIClient()
if err != nil {
klog.Errorf("failed to get machine api client %v", err)
Expand Down Expand Up @@ -168,7 +186,7 @@ func warnInvalidProfiles(invalidProfiles []*config.Profile) {
}

func printProfilesJSON() {
validProfiles, invalidProfiles, err := config.ListProfiles()
validProfiles, invalidProfiles, err := listProfiles()

updateProfilesStatus(validProfiles)

Expand All @@ -195,5 +213,6 @@ func profilesOrDefault(profiles []*config.Profile) []*config.Profile {

func init() {
profileListCmd.Flags().StringVarP(&output, "output", "o", "table", "The output format. One of 'json', 'table'")
profileListCmd.Flags().BoolVarP(&isLight, "light", "l", false, "If true, returns list of profiles faster by skipping validating the status of the cluster.")
ProfileCmd.AddCommand(profileListCmd)
}
1 change: 1 addition & 0 deletions site/content/en/docs/commands/profile.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ minikube profile list [flags]
### Options

```
-l, --light If true, returns list of profiles faster by skipping validating the status of the cluster.
-o, --output string The output format. One of 'json', 'table' (default "table")
```

Expand Down
100 changes: 74 additions & 26 deletions test/integration/functional_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -811,50 +811,98 @@ func validateProfileCmd(ctx context.Context, t *testing.T, profile string) {
})

t.Run("profile_list", func(t *testing.T) {
// helper function to run command then, return target profile line from table output.
extractrofileListFunc := func(rr *RunResult) string {
listLines := strings.Split(strings.TrimSpace(rr.Stdout.String()), "\n")
for i := 3; i < (len(listLines) - 1); i++ {
profileLine := listLines[i]
if strings.Contains(profileLine, profile) {
return profileLine
}
}
return ""
}

// List profiles
start := time.Now()
rr, err := Run(t, exec.CommandContext(ctx, Target(), "profile", "list"))
elapsed := time.Since(start)
if err != nil {
t.Errorf("failed to list profiles: args %q : %v", rr.Command(), err)
}
t.Logf("Took %q to run %q", elapsed, rr.Command())

// Table output
listLines := strings.Split(strings.TrimSpace(rr.Stdout.String()), "\n")
profileExists := false
for i := 3; i < (len(listLines) - 1); i++ {
profileLine := listLines[i]
if strings.Contains(profileLine, profile) {
profileExists = true
break
}
}
if !profileExists {
profileLine := extractrofileListFunc(rr)
if profileLine == "" {
t.Errorf("expected 'profile list' output to include %q but got *%q*. args: %q", profile, rr.Stdout.String(), rr.Command())
}

// List profiles with light option.
start = time.Now()
lrr, err := Run(t, exec.CommandContext(ctx, Target(), "profile", "list", "-l"))
lightElapsed := time.Since(start)
if err != nil {
t.Errorf("failed to list profiles: args %q : %v", lrr.Command(), err)
}
t.Logf("Took %q to run %q", lightElapsed, lrr.Command())

profileLine = extractrofileListFunc(lrr)
if profileLine == "" || !strings.Contains(profileLine, "Skipped") {
t.Errorf("expected 'profile list' output to include %q with 'Skipped' status but got *%q*. args: %q", profile, rr.Stdout.String(), rr.Command())
}

if lightElapsed > 3*time.Second {
t.Errorf("expected running time of '%q' is less than 3 seconds. Took %q ", lrr.Command(), lightElapsed)
}
})

t.Run("profile_json_output", func(t *testing.T) {
// Json output
rr, err := Run(t, exec.CommandContext(ctx, Target(), "profile", "list", "--output", "json"))
// helper function to run command then, return target profile object from json output.
extractProfileObjFunc := func(rr *RunResult) *config.Profile {
var jsonObject map[string][]config.Profile
err := json.Unmarshal(rr.Stdout.Bytes(), &jsonObject)
if err != nil {
t.Errorf("failed to decode json from profile list: args %q: %v", rr.Command(), err)
return nil
}

for _, profileObject := range jsonObject["valid"] {
if profileObject.Name == profile {
return &profileObject
}
}
return nil
}

start := time.Now()
rr, err := Run(t, exec.CommandContext(ctx, Target(), "profile", "list", "-o", "json"))
elapsed := time.Since(start)
if err != nil {
t.Errorf("failed to list profiles with json format. args %q: %v", rr.Command(), err)
}
var jsonObject map[string][]map[string]interface{}
err = json.Unmarshal(rr.Stdout.Bytes(), &jsonObject)
if err != nil {
t.Errorf("failed to decode json from profile list: args %q: %v", rr.Command(), err)
t.Logf("Took %q to run %q", elapsed, rr.Command())

pr := extractProfileObjFunc(rr)
if pr == nil {
t.Errorf("expected the json of 'profile list' to include %q but got *%q*. args: %q", profile, rr.Stdout.String(), rr.Command())
}
validProfiles := jsonObject["valid"]
profileExists := false
for _, profileObject := range validProfiles {
if profileObject["Name"] == profile {
profileExists = true
break
}

start = time.Now()
lrr, err := Run(t, exec.CommandContext(ctx, Target(), "profile", "list", "-o", "json", "--light"))
lightElapsed := time.Since(start)
if err != nil {
t.Errorf("failed to list profiles with json format. args %q: %v", lrr.Command(), err)
}
if !profileExists {
t.Errorf("expected the json of 'profile list' to include %q but got *%q*. args: %q", profile, rr.Stdout.String(), rr.Command())
t.Logf("Took %q to run %q", lightElapsed, lrr.Command())

pr = extractProfileObjFunc(lrr)
if pr == nil || pr.Status != "Skipped" {
t.Errorf("expected the json of 'profile list' to include 'Skipped' status for %q but got *%q*. args: %q", profile, lrr.Stdout.String(), lrr.Command())
}

if lightElapsed > 3*time.Second {
t.Errorf("expected running time of '%q' is less than 3 seconds. Took %q ", lrr.Command(), lightElapsed)
}
})
}

Expand Down

0 comments on commit a3609d3

Please sign in to comment.