Skip to content

Commit

Permalink
add configservice tests
Browse files Browse the repository at this point in the history
  • Loading branch information
garmr-ulfr committed Aug 14, 2024
1 parent bcb1004 commit 43d7a49
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 6 deletions.
8 changes: 3 additions & 5 deletions services/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,7 @@ type ConfigHandler interface {
SetConfig(new *apipb.ConfigResponse)
}

var (
_configService = &configService{sender: &sender{}}
)
var _configService = &configService{sender: &sender{}}

// StartConfigService starts a new config service with the given options and returns a func to stop
// it. It will return an error if opts.OriginURL, opts.Rt, or opts.OnConfig are nil.
Expand Down Expand Up @@ -199,7 +197,7 @@ func (cs *configService) fetch() (*apipb.ConfigResponse, int64, error) {
return nil, 0, fmt.Errorf("config request failed: %w", err)
}

if resp.StatusCode != http.StatusNoContent {
if resp.StatusCode == http.StatusNoContent {
return nil, 0, nil // no config changes
}

Expand All @@ -214,7 +212,7 @@ func (cs *configService) fetch() (*apipb.ConfigResponse, int64, error) {
return nil, 0, fmt.Errorf("unable to unmarshal config: %w", err)
}

return newConf, sleep, err
return newConf, sleep, nil
}

// newRequest returns a new ConfigRequest with the current client info, proxy ids, and the last
Expand Down
79 changes: 79 additions & 0 deletions services/config_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package services

import (
"fmt"
"net/http"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/getlantern/flashlight/v7/apipb"
"github.com/getlantern/flashlight/v7/common"
)

func TestFetchConfig(t *testing.T) {
t.Run("no change", func(t *testing.T) {
cs := newTestConfigService()
want := fmt.Sprintf("%v", cs.configHandler.GetConfig())
cs.opts.RoundTripper.(*mockRoundTripper).status = http.StatusNoContent

_, err := cs.fetchConfig()
require.NoError(t, err)

got := fmt.Sprintf("%v", cs.configHandler.GetConfig())
assert.Equal(t, want, got, "config should not have changed")
})

t.Run("new config", func(t *testing.T) {
cs := newTestConfigService()
_, err := cs.fetchConfig()
require.NoError(t, err)

rt := cs.opts.RoundTripper.(*mockRoundTripper)
want := fmt.Sprintf("%v", rt.config)
got := fmt.Sprintf("%v", cs.configHandler.GetConfig())
assert.Equal(t, want, got, "new config not set")
})
}

type mockConfigHandler struct {
config *apipb.ConfigResponse
}

func (m *mockConfigHandler) GetConfig() *apipb.ConfigResponse { return m.config }
func (m *mockConfigHandler) SetConfig(new *apipb.ConfigResponse) { m.config = new }

func newTestConfigService() *configService {
clientInfo := &apipb.ConfigRequest_ClientInfo{
ProToken: "the gray",
Country: "shire",
}
return &configService{
opts: &ConfigOptions{
OriginURL: "http://middle.earth",
UserConfig: common.NullUserConfig{},
RoundTripper: &mockRoundTripper{
config: &apipb.ConfigResponse{
ProToken: "the white",
Country: "shire",
Proxy: &apipb.ConfigResponse_Proxy{
Proxies: []*apipb.ProxyConnectConfig{{Name: "mines of moria"}},
},
},
},
},
clientInfo: clientInfo,
configHandler: &mockConfigHandler{
config: &apipb.ConfigResponse{
ProToken: clientInfo.ProToken,
Country: clientInfo.Country,
Proxy: &apipb.ConfigResponse_Proxy{
Proxies: []*apipb.ProxyConnectConfig{{Name: "misty mountain"}},
},
},
},
sender: &sender{},
done: make(chan struct{}),
}
}
16 changes: 15 additions & 1 deletion services/http_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package services

import (
"bytes"
"io"
"math"
mrand "math/rand/v2"
"net/http"
Expand All @@ -10,6 +12,9 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/protobuf/proto"

"github.com/getlantern/flashlight/v7/apipb"

"github.com/getlantern/flashlight/v7/common"
)
Expand Down Expand Up @@ -49,7 +54,7 @@ func TestPost(t *testing.T) {

func TestDoPost(t *testing.T) {
sdr := &sender{}
rt := &mockRoundTripper{status: http.StatusOK}
rt := &mockRoundTripper{}
_, err := sdr.doPost("http://example.com", nil, rt, common.NullUserConfig{})
assert.NoError(t, err)
assert.True(t, rt.req.Close, "request.Close should be set to true before calling RoundTrip")
Expand All @@ -59,6 +64,7 @@ type mockRoundTripper struct {
req *http.Request
status int
sleep int
config *apipb.ConfigResponse
shouldErr bool
}

Expand All @@ -68,10 +74,18 @@ func (m *mockRoundTripper) RoundTrip(req *http.Request) (*http.Response, error)
return nil, assert.AnError
}

buf, _ := proto.Marshal(m.config)
body := io.NopCloser(bytes.NewReader(buf))

header := http.Header{}
header.Add(common.SleepHeader, strconv.Itoa(m.sleep))
if m.status == 0 {
m.status = http.StatusOK
}

return &http.Response{
StatusCode: m.status,
Header: header,
Body: body,
}, nil
}

0 comments on commit 43d7a49

Please sign in to comment.