kubecfg: improve tests around authentication
This change adds additional test coverage for the kubecfg command. There is now a test for the case when the auth info file does not exist. LoadAuthInfo tests have been refactored to use table testing.
This commit is contained in:
		| @@ -130,7 +130,7 @@ func main() { | ||||
|  | ||||
| 	var auth *kube_client.AuthInfo | ||||
| 	if secure { | ||||
| 		auth, err = kubecfg.LoadAuthInfo(*authConfig) | ||||
| 		auth, err = kubecfg.LoadAuthInfo(*authConfig, os.Stdin) | ||||
| 		if err != nil { | ||||
| 			glog.Fatalf("Error loading auth: %v", err) | ||||
| 		} | ||||
|   | ||||
| @@ -19,6 +19,7 @@ package kubecfg | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"strconv" | ||||
| @@ -32,19 +33,19 @@ import ( | ||||
| 	"gopkg.in/v1/yaml" | ||||
| ) | ||||
|  | ||||
| func promptForString(field string) string { | ||||
| func promptForString(field string, r io.Reader) string { | ||||
| 	fmt.Printf("Please enter %s: ", field) | ||||
| 	var result string | ||||
| 	fmt.Scan(&result) | ||||
| 	fmt.Fscan(r, &result) | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| // LoadAuthInfo parses an AuthInfo object from a file path. It prompts user and creates file if it doesn't exist. | ||||
| func LoadAuthInfo(path string) (*client.AuthInfo, error) { | ||||
| func LoadAuthInfo(path string, r io.Reader) (*client.AuthInfo, error) { | ||||
| 	var auth client.AuthInfo | ||||
| 	if _, err := os.Stat(path); os.IsNotExist(err) { | ||||
| 		auth.User = promptForString("Username") | ||||
| 		auth.Password = promptForString("Password") | ||||
| 		auth.User = promptForString("Username", r) | ||||
| 		auth.Password = promptForString("Password", r) | ||||
| 		data, err := json.Marshal(auth) | ||||
| 		if err != nil { | ||||
| 			return &auth, err | ||||
|   | ||||
| @@ -17,7 +17,8 @@ limitations under the License. | ||||
| package kubecfg | ||||
|  | ||||
| import ( | ||||
| 	"encoding/json" | ||||
| 	"bytes" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"reflect" | ||||
| @@ -256,35 +257,55 @@ func TestCloudCfgDeleteControllerWithReplicas(t *testing.T) { | ||||
| } | ||||
|  | ||||
| func TestLoadAuthInfo(t *testing.T) { | ||||
| 	testAuthInfo := &client.AuthInfo{ | ||||
| 		User:     "TestUser", | ||||
| 		Password: "TestPassword", | ||||
| 	loadAuthInfoTests := []struct { | ||||
| 		authData string | ||||
| 		authInfo *client.AuthInfo | ||||
| 		r        io.Reader | ||||
| 	}{ | ||||
| 		{ | ||||
| 			`{"user": "user", "password": "pass"}`, | ||||
| 			&client.AuthInfo{User: "user", Password: "pass"}, | ||||
| 			nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			"", nil, nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			"missing", | ||||
| 			&client.AuthInfo{User: "user", Password: "pass"}, | ||||
| 			bytes.NewBufferString("user\npass"), | ||||
| 		}, | ||||
| 	} | ||||
| 	aifile, err := ioutil.TempFile("", "testAuthInfo") | ||||
| 	if err != nil { | ||||
| 		t.Error("Could not open temp file") | ||||
| 	} | ||||
| 	defer os.Remove(aifile.Name()) | ||||
| 	defer aifile.Close() | ||||
|  | ||||
| 	ai, err := LoadAuthInfo(aifile.Name()) | ||||
| 	if err == nil { | ||||
| 		t.Error("LoadAuthInfo didn't fail on empty file") | ||||
| 	} | ||||
| 	data, err := json.Marshal(testAuthInfo) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Unexpected JSON marshal error") | ||||
| 	} | ||||
| 	_, err = aifile.Write(data) | ||||
| 	if err != nil { | ||||
| 		t.Fatal("Unexpected error in writing test file") | ||||
| 	} | ||||
| 	ai, err = LoadAuthInfo(aifile.Name()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	if *testAuthInfo != *ai { | ||||
| 		t.Error("Test data and loaded data are not equal") | ||||
| 	for _, loadAuthInfoTest := range loadAuthInfoTests { | ||||
| 		tt := loadAuthInfoTest | ||||
| 		aifile, err := ioutil.TempFile("", "testAuthInfo") | ||||
| 		if err != nil { | ||||
| 			t.Errorf("Unexpected error: %v", err) | ||||
| 		} | ||||
| 		if tt.authData != "missing" { | ||||
| 			defer os.Remove(aifile.Name()) | ||||
| 			defer aifile.Close() | ||||
| 			_, err = aifile.WriteString(tt.authData) | ||||
| 			if err != nil { | ||||
| 				t.Errorf("Unexpected error: %v", err) | ||||
| 			} | ||||
| 		} else { | ||||
| 			aifile.Close() | ||||
| 			os.Remove(aifile.Name()) | ||||
| 		} | ||||
| 		authInfo, err := LoadAuthInfo(aifile.Name(), tt.r) | ||||
| 		if len(tt.authData) == 0 && tt.authData != "missing" { | ||||
| 			if err == nil { | ||||
| 				t.Error("LoadAuthInfo didn't fail on empty file") | ||||
| 			} | ||||
| 			continue | ||||
| 		} | ||||
| 		if err != nil { | ||||
| 			t.Errorf("Unexpected error: %v", err) | ||||
| 		} | ||||
| 		if !reflect.DeepEqual(authInfo, tt.authInfo) { | ||||
| 			t.Errorf("Expected %v, got %v", tt.authInfo, authInfo) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Kelsey Hightower
					Kelsey Hightower