Skip to content

Commit

Permalink
test(app): add application tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Icikowski committed Nov 14, 2022
1 parent 325863d commit 04ee39b
Show file tree
Hide file tree
Showing 10 changed files with 801 additions and 0 deletions.
264 changes: 264 additions & 0 deletions src/config/service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
package config_test

import (
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"net"
"os"
"testing"
"time"

"github.com/Icikowski/GoosyMock/config"
"github.com/stretchr/testify/require"
)

func noopCertGen(t *testing.T) (caCert string, tlsCert string, tlsKey string) {
t.Helper()
return
}

func missingCACertGen(t *testing.T) (caCert string, tlsCert string, tlsKey string) {
t.Helper()
caCert = "/tmp/thereIsNoSpoon"
return
}

func malformedCaCertGen(t *testing.T) (caCert string, tlsCert string, tlsKey string) {
t.Helper()

caCertFile, err := os.CreateTemp(os.TempDir(), "ca-*.crt")
if err != nil {
t.Fatal(err.Error())
return
}
t.Cleanup(func() {
os.Remove(caCertFile.Name())
})

if _, err := caCertFile.WriteString("malformed"); err != nil {
t.Fatal(err.Error())
return
}
caCert = caCertFile.Name()

return
}

func allOkCertGen(t *testing.T) (caCert string, tlsCert string, tlsKey string) {
t.Helper()

ca := &x509.Certificate{
SerialNumber: big.NewInt(123456789),
Subject: pkix.Name{
Country: []string{"PL"},
Province: []string{"mazowieckie"},
Locality: []string{"Warszawa"},
PostalCode: []string{"00-000"},
StreetAddress: []string{"Testowa 13"},
Organization: []string{"Firma"},
OrganizationalUnit: []string{"Certificate Authority"},
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
IsCA: true,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
BasicConstraintsValid: true,
}

caPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
t.Fatal(err.Error())
return
}

caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey)
if err != nil {
t.Fatal(err.Error())
return
}

caCertFile, err := os.CreateTemp(os.TempDir(), "ca-*.crt")
if err != nil {
t.Fatal(err.Error())
return
}
t.Cleanup(func() {
os.Remove(caCertFile.Name())
})

if err := pem.Encode(caCertFile, &pem.Block{
Type: "CERTIFICATE",
Bytes: caBytes,
}); err != nil {
t.Fatal(err.Error())
return
}
caCert = caCertFile.Name()

cert := &x509.Certificate{
SerialNumber: big.NewInt(1658),
Subject: pkix.Name{
Country: []string{"PL"},
Province: []string{"mazowieckie"},
Locality: []string{"Warszawa"},
PostalCode: []string{"00-000"},
StreetAddress: []string{"Testowa 13"},
Organization: []string{"Firma"},
OrganizationalUnit: []string{"Server"},
},
IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(5, 0, 0),
SubjectKeyId: []byte{1, 2, 3, 4, 6},
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageDigitalSignature,
}

certPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
if err != nil {
t.Fatal(err.Error())
return
}

certBytes, err := x509.CreateCertificate(rand.Reader, cert, ca, &certPrivKey.PublicKey, caPrivKey)
if err != nil {
t.Fatal(err.Error())
return
}

certFile, err := os.CreateTemp(os.TempDir(), "tls-*.crt")
if err != nil {
t.Fatal(err.Error())
return
}
t.Cleanup(func() {
os.Remove(certFile.Name())
})

if err := pem.Encode(certFile, &pem.Block{
Type: "CERTIFICATE",
Bytes: certBytes,
}); err != nil {
t.Fatal(err.Error())
return
}
tlsCert = certFile.Name()

keyFile, err := os.CreateTemp(os.TempDir(), "tls-*.key")
if err != nil {
t.Fatal(err.Error())
return
}
t.Cleanup(func() {
os.Remove(keyFile.Name())
})

if err := pem.Encode(keyFile, &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(certPrivKey),
}); err != nil {
t.Fatal(err.Error())
return
}
tlsKey = keyFile.Name()

return
}

func missingTLSCertGen(t *testing.T) (caCert string, tlsCert string, tlsKey string) {
t.Helper()
caCert, _, _ = allOkCertGen(t)
tlsCert, tlsKey = "", ""
return
}

func TestLoadCerts(t *testing.T) {
tests := map[string]struct {
sslEnabled bool
genFunc func(*testing.T) (string, string, string)
errorExpected bool
}{
"SSL disabled": {
sslEnabled: false,
genFunc: noopCertGen,
errorExpected: false,
},
"missing CA certificate": {
sslEnabled: true,
genFunc: missingCACertGen,
errorExpected: true,
},
"malformed CA certificate": {
sslEnabled: true,
genFunc: malformedCaCertGen,
errorExpected: true,
},
"missing TLS certificate": {
sslEnabled: true,
genFunc: missingTLSCertGen,
errorExpected: true,
},
"all OK": {
sslEnabled: true,
genFunc: allOkCertGen,
errorExpected: false,
},
}

for name, tc := range tests {
name, tc := name, tc
t.Run(name, func(t *testing.T) {
conf := &config.ServiceConfig{
SSLEnabled: tc.sslEnabled,
}
conf.CACertPath, conf.TLSCertPath, conf.TLSKeyPath = tc.genFunc(t)

err := conf.LoadCerts()
if tc.errorExpected {
require.Error(t, err)
return
}
require.NoError(t, err)
})
}
}

func TestGetTLSConfig(t *testing.T) {
tests := map[string]struct {
sslEnabled bool
}{
"SSL disabled": {sslEnabled: false},
"SSL enabled": {sslEnabled: true},
}

for name, tc := range tests {
name, tc := name, tc
t.Run(name, func(t *testing.T) {
conf := &config.ServiceConfig{
SSLEnabled: tc.sslEnabled,
}
actual := conf.GetTLSConfig()

if !tc.sslEnabled {
require.Nil(t, actual)
return
}
require.NotNil(t, actual)
require.EqualValues(t, tls.VersionTLS12, actual.MinVersion)
require.ElementsMatch(t, []uint16{
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
}, actual.CipherSuites)
})
}
}
27 changes: 27 additions & 0 deletions src/logs/emergency_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package logs_test

import (
"bytes"
"testing"

"github.com/Icikowski/GoosyMock/constants"
"github.com/Icikowski/GoosyMock/logs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestEmergencyLogger(t *testing.T) {
shouldContain := []string{constants.ComponentInit, "emergency log"}

dst := bytes.NewBuffer([]byte{})
log := logs.GetEmergencyLogger(dst)

log.Warn().Msg("emergency log")

output := dst.String()
hasAll := true
for _, phrase := range shouldContain {
hasAll = hasAll && assert.Contains(t, output, phrase)
}
require.True(t, hasAll, "some of expected phrases were not found")
}
83 changes: 83 additions & 0 deletions src/logs/factory_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package logs_test

import (
"bytes"
"testing"

"github.com/Icikowski/GoosyMock/config"
"github.com/Icikowski/GoosyMock/logs"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestLoggerFactory(t *testing.T) {
const (
warnLevelMsg string = "warn level"
infoLevelMsg string = "info level"
debugLevelMsg string = "debug level"
traceLevelMsg string = "trace level"
)

tests := map[string]struct {
cfg config.LoggingConfig
shouldContain []string
}{
"unknown log level": {
cfg: config.LoggingConfig{
Level: "foo",
},
shouldContain: []string{
"unknown log level, falling back to 'info'",
warnLevelMsg, infoLevelMsg,
},
},
"pretty log": {
cfg: config.LoggingConfig{
Pretty: true,
Level: "info",
},
shouldContain: []string{
"WRN", "INF",
warnLevelMsg, infoLevelMsg,
},
},
"standard log level": {
cfg: config.LoggingConfig{
Level: "info",
},
shouldContain: []string{
warnLevelMsg, infoLevelMsg,
},
},
"custom log level": {
cfg: config.LoggingConfig{
Level: "trace",
},
shouldContain: []string{
warnLevelMsg, infoLevelMsg,
debugLevelMsg, traceLevelMsg,
},
},
}

for name, tc := range tests {
name, tc := name, tc
t.Run(name, func(t *testing.T) {
dst := bytes.NewBuffer([]byte{})

log := logs.NewLoggerFactory(tc.cfg, dst).InstanceFor("test")
log.Warn().Msg(warnLevelMsg)
log.Info().Msg(infoLevelMsg)
log.Debug().Msg(debugLevelMsg)
log.Trace().Msg(traceLevelMsg)

output := dst.String()
hasAll := true
for _, phrase := range tc.shouldContain {
hasAll = hasAll && assert.Contains(t, output, phrase)
}

require.True(t, hasAll, "some of expected phrases were not found")
})
}
}
13 changes: 13 additions & 0 deletions src/meta/build_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package meta_test

import (
"testing"

"github.com/Icikowski/GoosyMock/meta"
"github.com/stretchr/testify/require"
)

func TestGetSentByHeader(t *testing.T) {
// Let's increase code coverage ¯\_(ツ)_/¯
require.Equal(t, "GoosyMock/unknown", meta.GetSentByHeader())
}
Loading

0 comments on commit 04ee39b

Please sign in to comment.