Skip to content

Commit

Permalink
Add tests for userparser and groupparser
Browse files Browse the repository at this point in the history
Refactor the parsers so you can pass a file to parse,
instead of always using the hardcoded values (/etc/passwd and /etc/group)
This is done for testing purposes, functionality remains the same
  • Loading branch information
ariasmn committed Jul 20, 2023
1 parent f87e82b commit 407ad16
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 12 deletions.
6 changes: 3 additions & 3 deletions groupparser/groupparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ var parsedGroups []Group

func GetGroups() (groups []Group) {
if len(parsedGroups) == 0 {
parseGroups()
ParseGroups("/etc/group")
}

return parsedGroups
}

func parseGroups() {
func ParseGroups(path string) {
parsedGroups = nil

f, err := os.Open("/etc/group")
f, err := os.Open(path)
if err != nil {
log.Fatal(err)
}
Expand Down
44 changes: 41 additions & 3 deletions groupparser/groupparser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,53 @@
package groupparser

import (
"os"
"os/user"
"reflect"
"testing"
)

const mockGroup = `test:x:0:
mock:x:65537:
`

func TestGetGroups(t *testing.T) {
var want []Group
tempDir, _ := os.CreateTemp("", "group")
err := os.WriteFile(tempDir.Name(), []byte(mockGroup), 0644)
if err != nil {
t.Fatalf("Should not have failed: %s", err)
}
defer os.Remove(tempDir.Name())

ParseGroups(tempDir.Name())
got := GetGroups()
want := getWanted()

if reflect.TypeOf(got) != reflect.TypeOf(want) {
t.Errorf("got %q, wanted %q", reflect.TypeOf(got), reflect.TypeOf(want))
for groupIndex, _ := range got {
if got[groupIndex].Details.Gid != want[groupIndex].Details.Gid {
t.Errorf("Got GID %s, wanted %s", got[groupIndex].Details.Gid, want[groupIndex].Details.Gid)
}
if got[groupIndex].Details.Name != want[groupIndex].Details.Name {
t.Errorf("Got name %s, wanted %s", got[groupIndex].Details.Name, want[groupIndex].Details.Name)
}
if !reflect.DeepEqual(got[groupIndex].Users, want[groupIndex].Users) {
t.Errorf("Got users %v, wanted %v", got[groupIndex].Users, want[groupIndex].Users)
}
}
}

func getWanted() []Group {
testGroup := Group{}
testGroup.Details.Gid = "0"
testGroup.Details.Name = "test"
testGroup.Users = []*user.User{nil}

mockGroup := Group{}
mockGroup.Details.Gid = "65537"
mockGroup.Details.Name = "mock"
mockGroup.Users = []*user.User{nil}

// Hard to test the users inside the group, since we use the Golang's lookup method
// This method tries to find an user within the system, so is quite hard to mock and not worth the hassle
return []Group{testGroup, mockGroup}
}
6 changes: 3 additions & 3 deletions userparser/userparser.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ var parsedUsers []User

func GetUsers() (users []User) {
if len(parsedUsers) == 0 {
ParseUsers()
ParseUsers("/etc/passwd")
}

return parsedUsers
}

func ParseUsers() {
func ParseUsers(path string) {
parsedUsers = nil

f, err := os.Open("/etc/passwd")
f, err := os.Open(path)
if err != nil {
log.Fatal(err)
}
Expand Down
59 changes: 56 additions & 3 deletions userparser/userparser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,68 @@
package userparser

import (
"os"
"os/user"
"reflect"
"testing"
)

const mockPwd = `test:x:0:0:test:/test:/bin/test
mock:x:1:65537:mock:/mock:/sbin/mock
`

func TestGetUsers(t *testing.T) {
var want []User
tempDir, _ := os.CreateTemp("", "passwd")
err := os.WriteFile(tempDir.Name(), []byte(mockPwd), 0644)
if err != nil {
t.Fatalf("Should not have failed: %s", err)
}
defer os.Remove(tempDir.Name())

ParseUsers(tempDir.Name()) // We parse the temp file before getting the users
got := GetUsers()
want := getWanted()

if reflect.TypeOf(got) != reflect.TypeOf(want) {
t.Errorf("got %q, wanted %q", reflect.TypeOf(got), reflect.TypeOf(want))
for userIndex, _ := range got {
if got[userIndex].Details.Uid != want[userIndex].Details.Uid {
t.Errorf("Got UID %s, wanted %s", got[userIndex].Details.Uid, want[userIndex].Details.Uid)
}
if got[userIndex].Details.Gid != want[userIndex].Details.Gid {
t.Errorf("Got GID %s, wanted %s", got[userIndex].Details.Gid, want[userIndex].Details.Gid)
}
if got[userIndex].Details.Username != want[userIndex].Details.Username {
t.Errorf("Got username %s, wanted %s", got[userIndex].Details.Username, want[userIndex].Details.Username)
}
if got[userIndex].Details.Name != want[userIndex].Details.Name {
t.Errorf("Got name %s, wanted %s", got[userIndex].Details.Name, want[userIndex].Details.Name)
}
if got[userIndex].Details.HomeDir != want[userIndex].Details.HomeDir {
t.Errorf("Got homedir %s, wanted %s", got[userIndex].Details.HomeDir, want[userIndex].Details.HomeDir)
}
if !reflect.DeepEqual(got[userIndex].Groups, want[userIndex].Groups) {
t.Errorf("Got group %v, wanted %v", got[userIndex].Groups, want[userIndex].Groups)
}
}
}

func getWanted() []User {
userTest := User{}
rootGroup, _ := user.LookupGroupId("0")

userTest.Details.Uid = "0"
userTest.Details.Gid = "0"
userTest.Details.Username = "test"
userTest.Details.Name = "test"
userTest.Details.HomeDir = "/test"
userTest.Groups = append(userTest.Groups, rootGroup)

userMock := User{}
userMock.Details.Uid = "1"
userMock.Details.Gid = "65537"
userMock.Details.Username = "mock"
userMock.Details.Name = "mock"
userMock.Details.HomeDir = "/mock"
userMock.Groups = []*user.Group{nil}

return []User{userTest, userMock}
}

0 comments on commit 407ad16

Please sign in to comment.