Skip to content

Commit

Permalink
Merge pull request #228 from opencontrol/add-plugin-example
Browse files Browse the repository at this point in the history
Add plugin example
  • Loading branch information
afeld committed Oct 4, 2016
2 parents e885314 + ee6b64c commit 837cf8e
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 1 deletion.
32 changes: 32 additions & 0 deletions exampleplugin/example.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package main

import (
"fmt"
"github.com/opencontrol/compliance-masonry/lib"
"github.com/opencontrol/compliance-masonry/lib/common"
"io"
"os"
)

type plugin struct {
common.Workspace
}

func simpleDataExtract(p plugin) string {
selectJustifications := p.GetAllVerificationsWith("NIST-800-53", "CM-2")
if len(selectJustifications) == 0 {
return "no data"
}
return selectJustifications[0].SatisfiesData.GetImplementationStatus()
}

func run(workspacePath, certPath string, writer io.Writer) {
workspace, _ := lib.LoadData(workspacePath, certPath)
sampleData := simpleDataExtract(plugin{workspace})
fmt.Fprint(writer, sampleData)
}

func main() {
// in reality you would check the number of args.
run(os.Args[1], os.Args[2], os.Stdout)
}
103 changes: 103 additions & 0 deletions exampleplugin/example_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package main

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gbytes"
. "github.com/onsi/gomega/gexec"
"github.com/opencontrol/compliance-masonry/lib/common"
"github.com/opencontrol/compliance-masonry/lib/common/mocks"
"github.com/stretchr/testify/assert"
"os"
"os/exec"
"path/filepath"
"time"
)

var _ = Describe("Exampleplugin", func() {
// example of unit test with mocks.
Describe("simpleDataExtract", func() {
Context("When there is no data for the standard-control combo", func() {
It("should print 'no data'", func() {
// create mock workspace
ws := new(mocks.Workspace)
ws.On("GetAllVerificationsWith", "NIST-800-53", "CM-2").Return(common.Verifications{})
// test function expecting "no data"
p := plugin{ws}
data := simpleDataExtract(p)
Expect(data).To(Equal("no data"))
})
})
Context("When there is data for the standard-control combo", func() {
It("should print the 'IMPLEMENTED', given that's expected", func() {
// create mock workspace
ws := new(mocks.Workspace)
satisfies := new(mocks.Satisfies)
satisfies.On("GetImplementationStatus").Return("IMPLEMENTED")
ws.On("GetAllVerificationsWith", "NIST-800-53", "CM-2").Return(
common.Verifications{common.Verification{SatisfiesData: satisfies}})
// test function expecting "IMPLEMENTED"
p := plugin{ws}
data := simpleDataExtract(p)
Expect(data).To(Equal("IMPLEMENTED"))
assert.Equal(GinkgoT(), data, "IMPLEMENTED")
})
})
})
// Example of reading the standard output.
Describe("run", func() {
Context("When running it on data in a workspace", func() {
It("should find the data and print it out to standard out", func() {
wsPath := filepath.Join("..", "fixtures", "opencontrol_fixtures")
certPath := filepath.Join("..", "..", "fixtures", "opencontrol_fixtures", "certifications", "LATO.yaml")
buffer := NewBuffer()
run(wsPath, certPath, buffer)
Expect(buffer).To(Say("partial"))
})
})
})
// Example of Running Masonry (with "get") and then the Plugin executables.
Describe("running the executable", func() {
BeforeEach(func() {
cleanupOpencontrolWorkspace()
})
Context("when running the executable", func() {
It("should build and run with two arguments", func() {
masonry := Masonry("--verbose", "get")
Eventually(masonry).Should(Exit(0))
p := Plugin(filepath.Join("opencontrols"), filepath.Join("opencontrols", "certifications"))
Eventually(p).Should(Exit(0))
// Should match the implementation status of CloudFormation in aws-compliance, which is
// "none"
Eventually(p.Out.Contents()).Should(ContainSubstring("none"))
})
})
AfterEach(func() {
cleanupOpencontrolWorkspace()
CleanupBuildArtifacts()
})
})
})

func cleanupOpencontrolWorkspace() {
os.RemoveAll("opencontrols")
}

func Masonry(args ...string) *Session {
path, err := Build("github.com/opencontrol/compliance-masonry")
Expect(err).NotTo(HaveOccurred())
return createCommand(path, args...)
}
func Plugin(args ...string) *Session {
path, err := Build("github.com/opencontrol/compliance-masonry/exampleplugin")
Expect(err).NotTo(HaveOccurred())
return createCommand(path, args...)
}

func createCommand(cmdPath string, args ...string) *Session {
cmd := exec.Command(cmdPath, args...)
session, err := Start(cmd, GinkgoWriter, GinkgoWriter)
session.Wait(20 * time.Second)
Expect(err).NotTo(HaveOccurred())
return session
}
13 changes: 13 additions & 0 deletions exampleplugin/exampleplugin_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package main_test

import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

"testing"
)

func TestExampleplugin(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Exampleplugin Suite")
}
14 changes: 14 additions & 0 deletions exampleplugin/opencontrol.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
schema_version: "1.0.0"
name: test-opencontrol-yaml
metadata:
description: "This opencontrol YAML is just used for showing various levels of testing. For more details refer to example_test.go"
dependencies:
standards:
- url: https://github.com/opencontrol/NIST-800-53-Standards
revision: master
certifications:
- url: https://github.com/opencontrol/FedRAMP-Certifications
revision: master
systems:
- url: https://github.com/opencontrol/aws-compliance
revision: master
10 changes: 9 additions & 1 deletion lib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,12 @@ mockery -name NameOfInterface
# Example:
mockery -name Workspace
```



## Plugin Developer Guide
Developers should not have to worry about loading real data / workspaces
for their unit tests (they should for integration tests).

There is an example of developing your Go plugin and tests in
`exampleplugin/example.go` and `exampleplugin/example_test.go`
respectively.

0 comments on commit 837cf8e

Please sign in to comment.