Skip to content

Commit

Permalink
Add -l/--light option for profile list command.
Browse files Browse the repository at this point in the history
If option is true, Doens't try to get profiles from container and read
current status.
  • Loading branch information
daehyeok committed Feb 9, 2021
1 parent b414901 commit ce4e61d
Show file tree
Hide file tree
Showing 3 changed files with 87 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, only display vaild profiles and do not check status.
-o, --output string The output format. One of 'json', 'table' (default "table")
```

Expand Down
91 changes: 65 additions & 26 deletions test/integration/functional_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -768,50 +768,89 @@ 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 and running time.
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)
}
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())
}

// 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
}
// 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)
}
if !profileExists {
t.Errorf("expected 'profile list' output to include %q but got *%q*. args: %q", profile, rr.Stdout.String(), rr.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 elapsed < (lightElapsed * 2) {
t.Errorf("expected running time of '%q' is less than half of '%q'.", lrr.Command(), rr.Command())
}
})

t.Run("profile_json_output", func(t *testing.T) {
// Json output
rr, err := Run(t, exec.CommandContext(ctx, Target(), "profile", "list", "--output", "json"))
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)
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())
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 elapsed < (lightElapsed * 2) {
t.Errorf("expected running time of '%q' is less than half of '%q'.", lrr.Command(), rr.Command())
}
})
}

Expand Down

0 comments on commit ce4e61d

Please sign in to comment.