From 73533878c5c6cdf50f3c952994be0243235baa7b Mon Sep 17 00:00:00 2001 From: Conor McNamara Date: Mon, 4 May 2015 20:49:44 -0400 Subject: [PATCH] More test coverage --- main.go | 30 ++++++++++++-------- main_test.go | 59 ++++++++++++++++++++++++++++++++++++++-- testdata/authorized_keys | 3 ++ testdata/config.test.yml | 18 ++++++++++++ 4 files changed, 97 insertions(+), 13 deletions(-) create mode 100644 testdata/authorized_keys create mode 100644 testdata/config.test.yml diff --git a/main.go b/main.go index 2f27485..b0576a3 100644 --- a/main.go +++ b/main.go @@ -8,7 +8,7 @@ import ( "strings" ) -const usageMessage = "" + ` +const usageMessage = ` 'ghkeys' uses the GitHub API to get the SSH keys of individual users and/or members of teams and either print them or write them to authorized_keys files. @@ -21,10 +21,8 @@ var ( ) func usage() { - fmt.Println(usageMessage) - fmt.Println("Flags:") + fmt.Println(usageMessage + "\nFlags:") flag.PrintDefaults() - os.Exit(2) } func check(err error) { @@ -58,6 +56,21 @@ func getUsernamesKeys(config config, client *githubClient, singleUsername string return usernamesKeys } +func getKeysOutput(keys []string) string { + return strings.Join(keys, "\n") +} + +func writeKeysToFile(keys []string, filename string) error { + authorizedKeysFile, err := os.Create(filename) + if err != nil { + return err + } + defer authorizedKeysFile.Close() + keysOutput := getKeysOutput(keys) + "\n" + _, err = authorizedKeysFile.WriteString(keysOutput) + return err +} + func main() { flag.Usage = usage flag.Parse() @@ -71,17 +84,12 @@ func main() { usernamesKeys := getUsernamesKeys(config, client, flag.Arg(0)) for username, keys := range usernamesKeys { - keysOutput := strings.Join(keys, "\n") if *writeToFile { // TODO: Is this always the path? - authorizedKeysFilename := fmt.Sprintf("/home/%s/.ssh/authorized_keys", username) - authorizedKeysFile, err := os.Open(authorizedKeysFilename) - check(err) - defer authorizedKeysFile.Close() - _, err = authorizedKeysFile.WriteString(keysOutput) + err := writeKeysToFile(keys, fmt.Sprintf("/home/%s/.ssh/authorized_keys", username)) check(err) } else { - fmt.Println(keysOutput) + fmt.Println(getKeysOutput(keys)) } } } diff --git a/main_test.go b/main_test.go index b82a430..4fb6b24 100644 --- a/main_test.go +++ b/main_test.go @@ -2,14 +2,21 @@ package main import ( "fmt" + "io/ioutil" "net/http" "net/http/httptest" "net/url" + "os" "testing" "github.com/stretchr/testify/assert" ) +const ( + testdataConfigFilename = "testdata/config.test.yml" + testAuthorizedKeysFilename = "testdata/authorized_keys" +) + var ( server *httptest.Server client *githubClient @@ -50,7 +57,8 @@ func teardown() { } func TestConfig(t *testing.T) { - testConfig, err := newConfig("config.example.yml") + // Test that testdata/config.yml jives with config struct + testConfig, err := newConfig(testdataConfigFilename) assert.Nil(t, err) assert.Equal(t, "my_github_token", testConfig.GithubToken) @@ -60,27 +68,49 @@ func TestConfig(t *testing.T) { assert.Equal(t, "github_user_1", testConfig.Users[0].GithubUsers[0]) assert.Len(t, testConfig.Users[0].GithubTeams, 2) assert.Equal(t, "MyOrg/Team 1", testConfig.Users[0].GithubTeams[0]) + + // Test nonexistent config file error + _, err = newConfig("thisfileshouldnotexist.yml") + assert.Error(t, err) + + // Test malformed yaml error + configFile, _ := ioutil.TempFile("", "ghkeys-config") + defer os.RemoveAll(configFile.Name()) + configContent := "invalid config yml" + ioutil.WriteFile(configFile.Name(), []byte(configContent), os.ModePerm) + _, err = newConfig(configFile.Name()) + assert.Error(t, err) } func TestGetTeamID(t *testing.T) { setup() defer teardown() + // Test valid Team ID teamID, err := client.getTeamID("MyOrg/Team 2") assert.Nil(t, err) assert.Equal(t, 2, teamID) + + // Test invalid Team ID + _, err = client.getTeamID("MyOrg/Invalid Team") + assert.Error(t, err) } func TestGetMembersOfTeam(t *testing.T) { setup() defer teardown() + // Test getting members of valid Team membersOfTeam, err := client.getMembersOfTeam("MyOrg/Team 2") assert.Nil(t, err) assert.Len(t, membersOfTeam, 1) assert.Equal(t, "github_user_3", membersOfTeam[0]) + + // Test getting members of invalid Team + _, err = client.getMembersOfTeam("MyOrg/Invalid Team") + assert.Error(t, err) } func TestGetKeysOfUser(t *testing.T) { @@ -125,7 +155,7 @@ func TestGetUsernamesKeys(t *testing.T) { setup() defer teardown() - config, err := newConfig("config.example.yml") + config, err := newConfig(testdataConfigFilename) assert.Nil(t, err) // Test for single username @@ -152,3 +182,28 @@ func TestGetUsernamesKeys(t *testing.T) { testUsernamesKeys(t, expectedUsernamesKeys, actualUsernamesKeys) } + +func TestGetKeysOutput(t *testing.T) { + expected := `github_user_1_key_1 +github_user_1_key_2 +github_user_1_key_3` + keys := []string{"github_user_1_key_1", "github_user_1_key_2", "github_user_1_key_3"} + actual := getKeysOutput(keys) + + assert.Equal(t, expected, actual) +} + +func TestWriteKeysToFile(t *testing.T) { + keys := []string{"github_user_1_key_1", "github_user_1_key_2", "github_user_1_key_3"} + + authorizedKeysFile, _ := ioutil.TempFile("", "ghkeys-authorized_keys") + authorizedKeysFilename := authorizedKeysFile.Name() + defer os.RemoveAll(authorizedKeysFilename) + err := writeKeysToFile(keys, authorizedKeysFilename) + + assert.Nil(t, err) + + expectedKeysFileContent, _ := ioutil.ReadFile(testAuthorizedKeysFilename) + actualKeysFileContent, _ := ioutil.ReadFile(authorizedKeysFilename) + assert.Equal(t, expectedKeysFileContent, actualKeysFileContent) +} diff --git a/testdata/authorized_keys b/testdata/authorized_keys new file mode 100644 index 0000000..b7a6918 --- /dev/null +++ b/testdata/authorized_keys @@ -0,0 +1,3 @@ +github_user_1_key_1 +github_user_1_key_2 +github_user_1_key_3 diff --git a/testdata/config.test.yml b/testdata/config.test.yml new file mode 100644 index 0000000..f0e35bb --- /dev/null +++ b/testdata/config.test.yml @@ -0,0 +1,18 @@ +--- +# Replace with your own GitHub token: +github_token: my_github_token +# Array of server usernames and the GitHub source(s) of their authorized keys: +users: + - username: superadmin + github_users: + - github_user_1 + github_teams: + # Specify teams by Org name and team name, separated by a / + - MyOrg/Team 1 + - MyOrg/Team 2 + - username: admin + github_users: + - github_user_1 + - github_user_2 + github_teams: + - MyOtherOrg/Team 3