2020-12-09 15:31:34 +00:00
|
|
|
package output
|
|
|
|
|
|
|
|
import (
|
2021-03-03 16:20:25 +00:00
|
|
|
"bytes"
|
|
|
|
"io"
|
2020-12-09 15:31:34 +00:00
|
|
|
"io/ioutil"
|
2021-03-03 16:20:25 +00:00
|
|
|
"os"
|
2020-12-09 15:31:34 +00:00
|
|
|
"path"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
|
|
|
|
"github.com/cloudskiff/driftctl/pkg/analyser"
|
2021-03-03 16:20:25 +00:00
|
|
|
"github.com/cloudskiff/driftctl/test/goldenfile"
|
2020-12-09 15:31:34 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestJSON_Write(t *testing.T) {
|
|
|
|
type args struct {
|
|
|
|
analysis *analyser.Analysis
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
goldenfile string
|
|
|
|
args args
|
|
|
|
wantErr bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "test json output",
|
|
|
|
goldenfile: "output.json",
|
|
|
|
args: args{
|
|
|
|
analysis: fakeAnalysis(),
|
|
|
|
},
|
|
|
|
wantErr: false,
|
|
|
|
},
|
2020-12-16 12:02:02 +00:00
|
|
|
{
|
|
|
|
name: "test json output with drift on computed fields",
|
|
|
|
goldenfile: "output_computed_fields.json",
|
|
|
|
args: args{
|
|
|
|
analysis: fakeAnalysisWithComputedFields(),
|
|
|
|
},
|
|
|
|
wantErr: false,
|
|
|
|
},
|
2021-02-12 21:38:23 +00:00
|
|
|
{
|
2021-03-02 10:39:14 +00:00
|
|
|
name: "test json output with AWS enumeration alerts",
|
|
|
|
goldenfile: "output_access_denied_alert_aws.json",
|
2021-02-12 21:38:23 +00:00
|
|
|
args: args{
|
2021-03-02 10:39:14 +00:00
|
|
|
analysis: fakeAnalysisWithAWSEnumerationError(),
|
|
|
|
},
|
|
|
|
wantErr: false,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: "test json output with Github enumeration alerts",
|
|
|
|
goldenfile: "output_access_denied_alert_github.json",
|
|
|
|
args: args{
|
|
|
|
analysis: fakeAnalysisWithGithubEnumerationError(),
|
2021-02-12 21:38:23 +00:00
|
|
|
},
|
|
|
|
wantErr: false,
|
|
|
|
},
|
2020-12-09 15:31:34 +00:00
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
tempDir := t.TempDir()
|
|
|
|
tempFile, err := ioutil.TempFile(tempDir, "result")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
c := NewJSON(tempFile.Name())
|
|
|
|
if err := c.Write(tt.args.analysis); (err != nil) != tt.wantErr {
|
|
|
|
t.Errorf("Write() error = %v, wantErr %v", err, tt.wantErr)
|
|
|
|
}
|
|
|
|
result, err := ioutil.ReadFile(tempFile.Name())
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
expectedFilePath := path.Join("./testdata/", tt.goldenfile)
|
|
|
|
if *goldenfile.Update == tt.goldenfile {
|
|
|
|
if err := ioutil.WriteFile(expectedFilePath, result, 0600); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
expected, err := ioutil.ReadFile(expectedFilePath)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
assert.Equal(t, string(expected), string(result))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2021-03-03 16:20:25 +00:00
|
|
|
|
|
|
|
func TestJSON_Write_stdout(t *testing.T) {
|
|
|
|
type args struct {
|
|
|
|
analysis *analyser.Analysis
|
|
|
|
}
|
|
|
|
tests := []struct {
|
|
|
|
name string
|
|
|
|
path string
|
|
|
|
goldenfile string
|
|
|
|
args args
|
|
|
|
wantErr bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
name: "test json output stdout",
|
|
|
|
goldenfile: "output.json",
|
|
|
|
path: "stdout",
|
|
|
|
args: args{
|
|
|
|
analysis: fakeAnalysis(),
|
|
|
|
},
|
|
|
|
wantErr: false,
|
|
|
|
},
|
|
|
|
|
|
|
|
{
|
|
|
|
name: "test json output /dev/stdout",
|
|
|
|
goldenfile: "output.json",
|
|
|
|
path: "/dev/stdout",
|
|
|
|
args: args{
|
|
|
|
analysis: fakeAnalysis(),
|
|
|
|
},
|
|
|
|
wantErr: false,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
|
|
|
|
|
|
stdout := os.Stdout // keep backup of the real stdout
|
|
|
|
r, w, _ := os.Pipe()
|
|
|
|
os.Stdout = w
|
|
|
|
|
|
|
|
c := NewJSON(tt.path)
|
|
|
|
if err := c.Write(tt.args.analysis); (err != nil) != tt.wantErr {
|
|
|
|
t.Errorf("Write() error = %v, wantErr %v", err, tt.wantErr)
|
|
|
|
}
|
|
|
|
|
|
|
|
outC := make(chan []byte)
|
|
|
|
// copy the output in a separate goroutine so printing can't block indefinitely
|
|
|
|
go func() {
|
|
|
|
var buf bytes.Buffer
|
|
|
|
_, _ = io.Copy(&buf, r)
|
|
|
|
outC <- buf.Bytes()
|
|
|
|
}()
|
|
|
|
|
|
|
|
// back to normal state
|
|
|
|
w.Close()
|
|
|
|
os.Stdout = stdout // restoring the real stdout
|
|
|
|
result := <-outC
|
|
|
|
|
|
|
|
expectedFilePath := path.Join("./testdata/", tt.goldenfile)
|
|
|
|
if *goldenfile.Update == tt.goldenfile {
|
|
|
|
if err := ioutil.WriteFile(expectedFilePath, result, 0600); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
expected, err := ioutil.ReadFile(expectedFilePath)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
assert.Equal(t, string(expected), string(result))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2021-03-30 15:43:21 +00:00
|
|
|
|
|
|
|
func TestJSON_WriteMultiplesTimesInSameFile(t *testing.T) {
|
|
|
|
emptyAnalysis := &analyser.Analysis{}
|
|
|
|
longerAnalysis := fakeAnalysis()
|
|
|
|
tempDir := t.TempDir()
|
|
|
|
tempFile, err := ioutil.TempFile(tempDir, "result")
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
c := NewJSON(tempFile.Name())
|
|
|
|
|
|
|
|
if err := c.Write(longerAnalysis); err != nil {
|
|
|
|
t.Errorf("First write error = %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := c.Write(emptyAnalysis); err != nil {
|
|
|
|
t.Errorf("Second write error = %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
result, err := ioutil.ReadFile(tempFile.Name())
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
goldenFileName := "output_multiples_times.json"
|
|
|
|
expectedFilePath := path.Join("./testdata/", goldenFileName)
|
|
|
|
if *goldenfile.Update == goldenFileName {
|
|
|
|
if err := ioutil.WriteFile(expectedFilePath, result, 0600); err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
expected, err := ioutil.ReadFile(expectedFilePath)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
assert.Equal(t, string(expected), string(result))
|
|
|
|
}
|