func TestScriptExecution(t *testing.T) { Convey("Using a temporary file", t, func() { scriptPermissions := os.FileMode(0700) outChan := make(chan string, 1) executeScript := func(script *os.File) error { script.Close() out, err := sys.DefaultExecutor.Execute(script.Name()) outChan <- out return err } Convey("Given a script file", func() { scriptContent := "#! /usr/bin/env bash\n" scriptContent += "echo -n Yeehaw\n" scriptContent += "\n" tmpFile := &context.TempFile{ Permissions: scriptPermissions, Content: scriptContent, } Convey("It should execute the script and return its output", func() { err := <-context.Using(tmpFile, executeScript) So(err, ShouldBeNil) So(<-outChan, ShouldEqual, "Yeehaw") }) }) }) }
func TestSSHKeyAuthorization(t *testing.T) { Convey("Given an SSH authorized keys file and public keys", t, func() { rsa_key, err := ioutil.ReadFile("test_keys/test_rsa.pub") So(err, ShouldBeNil) dsa_key, err := ioutil.ReadFile("test_keys/test_dsa.pub") So(err, ShouldBeNil) tmpAuthKeysFile := &context.TempFile{ Content: "", Permissions: os.FileMode(0600), } Convey("It should append the SSH keys to the authorized keys file", func() { authorizeKey := func(f *os.File) error { err := ssh.AuthorizeKeys(f, []byte(rsa_key), []byte(dsa_key)) if err != nil { return err } f.Close() // Checks whether the keys are authorized. _, err = sys.DefaultExecutor.Execute("ssh-keygen", "-l", "-f", f.Name()) return err } err := <-context.Using(tmpAuthKeysFile, authorizeKey) So(err, ShouldBeNil) }) }) }
func TestUsingContexts(t *testing.T) { Convey("Given a context and a context use function", t, func() { NotEvenErr := errors.New("not a good number") checkIfEven := func(no int) error { if no%2 == 1 { return NotEvenErr } return nil } Convey("It should use the context in the order, Enter -> Use -> Exit", func() { ch := make(chan Signal) randomNumber := &RandomNumberContext{ seed: 2, EventChannel: ch, } errch := context.Using(randomNumber, checkIfEven) event1, event2, event3 := <-ch, <-ch, <-ch So(event1, ShouldEqual, Enter) So(event2, ShouldEqual, Use) So(event3, ShouldEqual, Exit) err := <-errch So(err, ShouldBeNil) }) Convey("It should propagate the errors encountered during use", func() { ch := make(chan Signal, 3) randomNumber := &RandomNumberContext{ seed: 3, EventChannel: ch, } errch := context.Using(randomNumber, checkIfEven) err := <-errch So(err, ShouldEqual, NotEvenErr) }) }) }
// executeScript writes the given contents to a temporary file and executes the file. func (imp *Implementation) executeScript(c string) error { tempFile := &context.TempFile{ Content: c, Permissions: 0600, } return <-context.Using(tempFile, func(f *os.File) error { f.Close() _, err := imp.Execute("sh", f.Name()) return err }) }
// Verify uses 'ssh-keygen' utility to verify an SSH key. // It returns an error if a problem occurs or the key is invalid. // The caller should diagnose the error for more information. func Verify(key Key) error { tmpFile := &context.TempFile{ Content: string(key), } var checkSSHValidity = func(f *os.File) error { _, err := sys.DefaultExecutor.Execute("ssh-keygen", "-l", "-f", f.Name()) return err } errch := context.Using(tmpFile, checkSSHValidity) return <-errch }
// AuthorizeKeysFor initializes the SSH directory structure for the user and // appends the given public keys to user's authorized keys file. func AuthorizeKeysFor(usr *user.User, publicKeys []Key) error { err := InitializeFor(usr) if err != nil { return err } authorizationFile := &context.File{ Path: filepath.Join(usr.HomeDir, AuthorizedKeysPath), Permissions: os.FileMode(0600), } // TODO(tmrts): Check for duplicate keys. // TODO(tmrts): Add keys to /etc/ssh if keys exist. return <-context.Using(authorizationFile, func(f *os.File) error { return AuthorizeKeys(f, publicKeys...) }) }
func (sysd *Implementation) CreateComponent(name, contents string) (initd.Component, error) { newUnit := &Unit{ name: name, path: filepath.Join(sysd.UnitDir, name), } newFile := &context.NewFile{ Path: newUnit.Path(), Permissions: 0644, } errch := context.Using(newFile, func(f *os.File) error { _, err := f.WriteString(contents) return err }) return newUnit, <-errch }
func TestDependencyInjection(t *testing.T) { Convey("Given a dependency and a replacement for that dependency with the same type", t, func() { So(ToLower("HELLO"), ShouldEqual, "hello") fakeToLower := func(string) string { return "This function has been hijacked." } Convey("It should inject the replacement to the dependency", func() { restoreDependency := ToLower.Inject(fakeToLower) So(ToLower("HELLO"), ShouldEqual, "This function has been hijacked.") So(ToLower("WORLD"), ShouldEqual, "This function has been hijacked.") restoreDependency() So(ToLower("HELLO"), ShouldEqual, "hello") }) Convey("Within an injection context", func() { mockToLower := &injection.ContextManager{ Dependency: &ToLower, Replacement: fakeToLower, } Convey("It should use the injected function within the context", func() { outch := make(chan string) context.Using(mockToLower, func() error { outch <- ToLower("HELLO") return nil }) So(<-outch, ShouldEqual, "This function has been hijacked.") }) Convey("It should restore the injected function after the context is exited", func() { So(ToLower("HELLO"), ShouldEqual, "hello") }) }) }) }
func TestScriptValidation(t *testing.T) { Convey("Using a temporary file", t, func() { scriptPermissions := os.FileMode(0600) isScript := make(chan bool, 1) performScriptValidation := func(script *os.File) error { script.Close() hasShabang, err := sys.FileHasShabang(script.Name()) isScript <- hasShabang return err } Convey("Given a file without Shabang", func() { tmpFile := &context.TempFile{ Permissions: scriptPermissions, Content: "Some stuff\n", } Convey("It should return false", func() { err := <-context.Using(tmpFile, performScriptValidation) So(err, ShouldBeNil) So(<-isScript, ShouldBeFalse) }) }) Convey("Given a file with malformed Shabang", func() { tmpFile := &context.TempFile{ Permissions: scriptPermissions, Content: "# ! /bin/bash\nSome command\n", } Convey("It should return false", func() { err := <-context.Using(tmpFile, performScriptValidation) So(err, ShouldBeNil) So(<-isScript, ShouldBeFalse) }) }) Convey("Given an empty file with Shabang", func() { tmpFile := &context.TempFile{ Permissions: scriptPermissions, Content: "#! /bin/bash\n\n", } Convey("It should return true", func() { err := <-context.Using(tmpFile, performScriptValidation) So(err, ShouldBeNil) So(<-isScript, ShouldBeTrue) }) }) Convey("Given a script file with Shabang", func() { tmpFile := &context.TempFile{ Permissions: scriptPermissions, Content: "#! /bin/bash\nprintf ${PWD}\n", } Convey("It should return true", func() { err := <-context.Using(tmpFile, performScriptValidation) So(err, ShouldBeNil) So(<-isScript, ShouldBeTrue) }) }) }) }