github.com/geofffranks/garden-linux@v0.0.0-20160715111146-26c893169cfa/system/user_execer_linux_test.go (about)

     1  package system_test
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  	"os/exec"
     7  	"path/filepath"
     8  	"syscall"
     9  
    10  	"fmt"
    11  
    12  	. "github.com/onsi/ginkgo"
    13  	. "github.com/onsi/gomega"
    14  	"github.com/onsi/gomega/gbytes"
    15  	"github.com/onsi/gomega/gexec"
    16  )
    17  
    18  var _ = Describe("UserExecer", func() {
    19  	var id uint32
    20  
    21  	BeforeEach(func() {
    22  		id = uint32(100000 + GinkgoParallelNode())
    23  		groupAddCmd := exec.Command("groupadd", "-g", fmt.Sprintf("%d", id), "banana")
    24  		groupAddCmd.Stdout = GinkgoWriter
    25  		groupAddCmd.Stderr = GinkgoWriter
    26  		groupAddCmd.Run()
    27  
    28  		userAddCmd := exec.Command("useradd", "-g", fmt.Sprintf("%d", id), "-u", fmt.Sprintf("%d", id), "banana")
    29  		userAddCmd.Stdout = GinkgoWriter
    30  		userAddCmd.Stderr = GinkgoWriter
    31  		userAddCmd.Run()
    32  	})
    33  
    34  	AfterEach(func() {
    35  		exec.Command("userdel", "banana").Run()
    36  	})
    37  
    38  	It("execs a process as specified user", func() {
    39  		out := gbytes.NewBuffer()
    40  		runningTest, err := gexec.Start(
    41  			exec.Command(testUserExecerPath,
    42  				fmt.Sprintf("-uid=%d", id),
    43  				fmt.Sprintf("-gid=%d", id),
    44  				fmt.Sprintf("-workDir=%s", "/tmp")),
    45  			io.MultiWriter(GinkgoWriter, out),
    46  			io.MultiWriter(GinkgoWriter, out),
    47  		)
    48  		Expect(err).NotTo(HaveOccurred())
    49  		runningTest.Wait()
    50  
    51  		Expect(runningTest.ExitCode()).To(Equal(0))
    52  		Expect(string(out.Contents())).To(Equal(fmt.Sprintf("%d\n%d\n", id, id)))
    53  	})
    54  
    55  	Describe("Working directory", func() {
    56  		var workDir string
    57  
    58  		Context("when working directory does not exist", func() {
    59  			BeforeEach(func() {
    60  				workDir = filepath.Join("/tmp", fmt.Sprintf("user-execer-%d", GinkgoParallelNode()))
    61  				_, err := os.Stat(workDir)
    62  				Expect(err).To(HaveOccurred())
    63  				Expect(os.IsNotExist(err)).To(BeTrue())
    64  			})
    65  
    66  			AfterEach(func() {
    67  				os.RemoveAll(workDir)
    68  			})
    69  
    70  			It("creates working directory", func() {
    71  				runningTest, err := gexec.Start(
    72  					exec.Command(testUserExecerPath,
    73  						fmt.Sprintf("-uid=%d", id),
    74  						fmt.Sprintf("-gid=%d", id),
    75  						fmt.Sprintf("-workDir=%s", workDir)),
    76  					GinkgoWriter,
    77  					GinkgoWriter,
    78  				)
    79  				Expect(err).NotTo(HaveOccurred())
    80  				runningTest.Wait()
    81  				Expect(runningTest.ExitCode()).To(Equal(0))
    82  
    83  				info, err := os.Stat(workDir)
    84  				Expect(err).ToNot(HaveOccurred())
    85  				Expect(info.IsDir()).To(BeTrue())
    86  
    87  				stats := info.Sys().(*syscall.Stat_t)
    88  				Expect(stats.Uid).To(Equal(id))
    89  				Expect(stats.Gid).To(Equal(id))
    90  			})
    91  
    92  			Context("when the user has NOT permissiongs", func() {
    93  				BeforeEach(func() {
    94  					workDir = "/root/nonexist"
    95  				})
    96  
    97  				It("failes to create working directory because of permissions", func() {
    98  					out := gbytes.NewBuffer()
    99  					cmd := exec.Command(testUserExecerPath,
   100  						fmt.Sprintf("-uid=%d", id),
   101  						fmt.Sprintf("-gid=%d", id),
   102  						fmt.Sprintf("-workDir=%s", workDir))
   103  
   104  					runningTest, _ := gexec.Start(cmd, GinkgoWriter, out)
   105  					runningTest.Wait()
   106  					Expect(runningTest.ExitCode()).ToNot(Equal(0))
   107  					Expect(out).To(gbytes.Say(fmt.Sprintf("system: mkdir %s: permission denied", workDir)))
   108  				})
   109  			})
   110  		})
   111  
   112  		Context("when working directory is not provided", func() {
   113  			JustBeforeEach(func() {
   114  				workDir = ""
   115  			})
   116  
   117  			It("fails to execute", func() {
   118  				out := gbytes.NewBuffer()
   119  				cmd := exec.Command(testUserExecerPath,
   120  					fmt.Sprintf("-uid=%d", id),
   121  					fmt.Sprintf("-gid=%d", id),
   122  					fmt.Sprintf("-workDir=%s", workDir))
   123  
   124  				runningTest, _ := gexec.Start(cmd, GinkgoWriter, out)
   125  				runningTest.Wait()
   126  				Expect(runningTest.ExitCode()).ToNot(Equal(0))
   127  				Expect(out).To(gbytes.Say("system: working directory is not provided"))
   128  			})
   129  		})
   130  
   131  		Context("when working directory does exist", func() {
   132  			JustBeforeEach(func() {
   133  				workDir = "/tmp"
   134  			})
   135  
   136  			Context("when the user has permissions to run in working directory", func() {
   137  				It("returns exit status 0 (succeeds)", func() {
   138  					runningTest, err := gexec.Start(
   139  						exec.Command(testUserExecerPath,
   140  							fmt.Sprintf("-uid=%d", id),
   141  							fmt.Sprintf("-gid=%d", id),
   142  							fmt.Sprintf("-workDir=%s", workDir)),
   143  						GinkgoWriter,
   144  						GinkgoWriter,
   145  					)
   146  					Expect(err).NotTo(HaveOccurred())
   147  					runningTest.Wait()
   148  					Expect(runningTest.ExitCode()).To(Equal(0))
   149  				})
   150  			})
   151  
   152  			Context("when the user has NOT permissions to run in working directory", func() {
   153  				JustBeforeEach(func() {
   154  					workDir = "/root"
   155  				})
   156  
   157  				It("fails to execute", func() {
   158  					out := gbytes.NewBuffer()
   159  					cmd := exec.Command(testUserExecerPath,
   160  						fmt.Sprintf("-uid=%d", id),
   161  						fmt.Sprintf("-gid=%d", id),
   162  						fmt.Sprintf("-workDir=%s", workDir))
   163  
   164  					runningTest, _ := gexec.Start(cmd, GinkgoWriter, out)
   165  					runningTest.Wait()
   166  					Expect(runningTest.ExitCode()).ToNot(Equal(0))
   167  					Expect(out).To(gbytes.Say(fmt.Sprintf("system: invalid working directory: %s", workDir)))
   168  				})
   169  			})
   170  		})
   171  	})
   172  })