From 546a5849f3b20797c7fab981a93ade287950889c Mon Sep 17 00:00:00 2001 From: 9seconds Date: Fri, 12 Mar 2021 20:07:18 +0300 Subject: [PATCH] Add test for generate-secret command --- cli/base_internal_test.go | 31 ++++++++++ cli/generate_secret_test.go | 50 ++++++++++++++++ cli/init_test.go | 112 ++++++++++++++++++++++++++++++++++++ cli/testdata/minimal.toml | 2 + go.mod | 1 + go.sum | 2 + mtglib/network/init.go | 1 + mtglib/network/network.go | 12 ++-- 8 files changed, 207 insertions(+), 4 deletions(-) create mode 100644 cli/base_internal_test.go create mode 100644 cli/generate_secret_test.go create mode 100644 cli/init_test.go create mode 100644 cli/testdata/minimal.toml diff --git a/cli/base_internal_test.go b/cli/base_internal_test.go new file mode 100644 index 0000000..1cd0b97 --- /dev/null +++ b/cli/base_internal_test.go @@ -0,0 +1,31 @@ +package cli + +import ( + "path/filepath" + "testing" + + "github.com/stretchr/testify/suite" +) + +type BaseTestSuite struct { + suite.Suite + + b base +} + +func (suite *BaseTestSuite) SetupTest() { + suite.b = base{} +} + +func (suite *BaseTestSuite) TestReadConfigNok() { + suite.Error(suite.b.ReadConfig(filepath.Join("testdata", "unknown"), "dev")) +} + +func (suite *BaseTestSuite) TestReadConfig() { + suite.NoError(suite.b.ReadConfig(filepath.Join("testdata", "minimal.toml"), "dev")) +} + +func TestBase(t *testing.T) { + t.Parallel() + suite.Run(t, &BaseTestSuite{}) +} diff --git a/cli/generate_secret_test.go b/cli/generate_secret_test.go new file mode 100644 index 0000000..7e32775 --- /dev/null +++ b/cli/generate_secret_test.go @@ -0,0 +1,50 @@ +package cli_test + +import ( + "strings" + "testing" + + "github.com/9seconds/mtg/v2/mtglib" + "github.com/stretchr/testify/suite" +) + +type GenerateSecretTestSuite struct { + CommonTestSuite +} + +func (suite *GenerateSecretTestSuite) SetupTest() { + suite.CommonTestSuite.SetupTest() + + suite.cli.GenerateSecret.HostName = "google.com" +} + +func (suite *GenerateSecretTestSuite) TestDefault() { + output := suite.CaptureStdout(func() { + suite.NoError(suite.cli.GenerateSecret.Run(suite.cli, "dev")) + }) + suite.True(strings.HasPrefix(output, "7")) + + secret, err := mtglib.ParseSecret(output) + suite.NoError(err) + suite.True(secret.Valid()) + suite.Equal("google.com", secret.Host) +} + +func (suite *GenerateSecretTestSuite) TestHex() { + suite.cli.GenerateSecret.Hex = true + + output := suite.CaptureStdout(func() { + suite.NoError(suite.cli.GenerateSecret.Run(suite.cli, "dev")) + }) + suite.True(strings.HasPrefix(output, "ee")) + + secret, err := mtglib.ParseSecret(output) + suite.NoError(err) + suite.True(secret.Valid()) + suite.Equal("google.com", secret.Host) +} + +func TestGenerateSecret(t *testing.T) { + t.Parallel() + suite.Run(t, &GenerateSecretTestSuite{}) +} diff --git a/cli/init_test.go b/cli/init_test.go new file mode 100644 index 0000000..a1894b6 --- /dev/null +++ b/cli/init_test.go @@ -0,0 +1,112 @@ +package cli_test + +import ( + "bytes" + "context" + "io" + "net" + "net/http" + "os" + "strings" + "time" + + "github.com/9seconds/mtg/v2/cli" + "github.com/9seconds/mtg/v2/mtglib/network" + "github.com/jarcoal/httpmock" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/suite" +) + +type NetworkMock struct { + mock.Mock +} + +func (n *NetworkMock) Dial(network, address string) (net.Conn, error) { + args := n.Called(network, address) + + return args.Get(0).(net.Conn), args.Error(1) +} + +func (n *NetworkMock) DialContext(ctx context.Context, network, address string) (net.Conn, error) { + args := n.Called(ctx, network, address) + + return args.Get(0).(net.Conn), args.Error(1) +} + +func (n *NetworkMock) DNSResolve(network, hostname string) ([]string, error) { + args := n.Called(network, hostname) + + return args.Get(0).([]string), args.Error(1) +} + +func (n *NetworkMock) MakeHTTPClient(dialFunc network.DialFunc) *http.Client { + return n.Called(dialFunc).Get(0).(*http.Client) +} + +func (n *NetworkMock) IdleTimeout() time.Duration { + return n.Called().Get(0).(time.Duration) +} + +func (n *NetworkMock) HTTPTimeout() time.Duration { + return n.Called().Get(0).(time.Duration) +} + +type CommonTestSuite struct { + suite.Suite + + cli *cli.CLI + networkMock *NetworkMock + httpClient *http.Client +} + +func (suite *CommonTestSuite) SetupTest() { + suite.networkMock = &NetworkMock{} + suite.httpClient = &http.Client{} + suite.cli = &cli.CLI{} + + httpmock.ActivateNonDefault(suite.httpClient) + + suite.networkMock. + On("MakeHTTPClient", mock.Anything). + Maybe(). + Return(suite.httpClient) +} + +func (suite *CommonTestSuite) TearDownTest() { + suite.networkMock.AssertExpectations(suite.T()) + httpmock.DeactivateAndReset() +} + +func (suite *CommonTestSuite) CaptureStdout(callback func()) string { + return suite.captureOutput(&os.Stdout, callback) +} + +func (suite *CommonTestSuite) CaptureStderr(callback func()) string { + return suite.captureOutput(&os.Stderr, callback) +} + +func (suite *CommonTestSuite) captureOutput(filefp **os.File, callback func()) string { + oldFp := *filefp + + defer func() { + *filefp = oldFp + }() + + reader, writer, _ := os.Pipe() + buf := &bytes.Buffer{} + closeChan := make(chan bool) + + go func() { + io.Copy(buf, reader) // nolint: errcheck + close(closeChan) + }() + + *filefp = writer + + callback() + + writer.Close() + <-closeChan + + return strings.TrimSpace(buf.String()) +} diff --git a/cli/testdata/minimal.toml b/cli/testdata/minimal.toml new file mode 100644 index 0000000..ea35f78 --- /dev/null +++ b/cli/testdata/minimal.toml @@ -0,0 +1,2 @@ +secret = "7mqFMMq3P2Tvvt_rPx5qhmFnb29nbGUuY29t" +bind-to = "0.0.0.0:80" diff --git a/go.mod b/go.mod index 20cbeb9..6486b6b 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ require ( github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6 + github.com/jarcoal/httpmock v1.0.8 // indirect github.com/kr/pretty v0.1.0 // indirect github.com/libp2p/go-reuseport v0.0.2 github.com/mccutchen/go-httpbin v1.1.1 diff --git a/go.sum b/go.sum index 73e7830..17aca99 100644 --- a/go.sum +++ b/go.sum @@ -9,6 +9,8 @@ github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6/go.mod h1 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/jarcoal/httpmock v1.0.8 h1:8kI16SoO6LQKgPE7PvQuV+YuD/inwHd7fOOe2zMbo4k= +github.com/jarcoal/httpmock v1.0.8/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= diff --git a/mtglib/network/init.go b/mtglib/network/init.go index 9378435..82416af 100644 --- a/mtglib/network/init.go +++ b/mtglib/network/init.go @@ -40,4 +40,5 @@ type Network interface { DNSResolve(network, hostname string) (ips []string, err error) MakeHTTPClient(DialFunc) *http.Client IdleTimeout() time.Duration + HTTPTimeout() time.Duration } diff --git a/mtglib/network/network.go b/mtglib/network/network.go index f5fc8ed..1835eb0 100644 --- a/mtglib/network/network.go +++ b/mtglib/network/network.go @@ -115,10 +115,6 @@ func (n *network) DNSResolve(protocol, address string) ([]string, error) { return ips, nil } -func (n *network) IdleTimeout() time.Duration { - return n.idleTimeout -} - func (n *network) MakeHTTPClient(dialFunc DialFunc) *http.Client { if dialFunc == nil { dialFunc = n.DialContext @@ -127,6 +123,14 @@ func (n *network) MakeHTTPClient(dialFunc DialFunc) *http.Client { return makeHTTPClient(n.userAgent, n.httpTimeout, dialFunc) } +func (n *network) IdleTimeout() time.Duration { + return n.idleTimeout +} + +func (n *network) HTTPTimeout() time.Duration { + return n.httpTimeout +} + func NewNetwork(dialer Dialer, userAgent, dohHostname string, httpTimeout, idleTimeout time.Duration) (Network, error) {