Skip to content

Commit

Permalink
Merge pull request #51 from statsig-io/localmode
Browse files Browse the repository at this point in the history
Add localmode for dummy client that doesnt access network
  • Loading branch information
tore-statsig authored Nov 9, 2021
2 parents 284f9e1 + fc3ee86 commit 308f05d
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 9 deletions.
4 changes: 2 additions & 2 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ func NewClientWithOptions(sdkKey string, options *Options) *Client {
if len(options.API) == 0 {
options.API = "https://api.statsig.com/v1"
}
transport := newTransport(sdkKey, options.API)
transport := newTransport(sdkKey, options)
logger := newLogger(transport)
evaluator := newEvaluator(transport)
if !strings.HasPrefix(sdkKey, "secret") {
if !options.LocalMode && !strings.HasPrefix(sdkKey, "secret") {
panic("Must provide a valid SDK key.")
}
return &Client{
Expand Down
27 changes: 27 additions & 0 deletions evaluation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,33 @@ func test_helper(apiOverride string, t *testing.T) {
}
}

func TestStatsigLocalMode(t *testing.T) {
user := &User{UserID: "test"}
local := &Options{
LocalMode: true,
}
local_c := NewClientWithOptions("", local)
network := &Options{}
net_c := NewClientWithOptions(secret, network)
local_gate := local_c.CheckGate(*user, "test_public")
if local_gate {
t.Errorf("Local mode should always return false for gate checks")
}
net_gate := net_c.CheckGate(*user, "test_public")
if !net_gate {
t.Errorf("Network mode should work")
}

local_config := local_c.GetConfig(*user, "test_custom_config")
net_config := net_c.GetConfig(*user, "test_custom_config")
if len(local_config.Value) != 0 {
t.Errorf("Local mode should always return false for gate checks")
}
if len(net_config.Value) == 0 {
t.Errorf("Network mode should fetch configs")
}
}

func compare_exposures(v1 []map[string]string, v2 []map[string]string) bool {
if v1 == nil {
v1 = []map[string]string{}
Expand Down
6 changes: 4 additions & 2 deletions logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ func TestLog(t *testing.T) {
return
}))
defer testServer.Close()

transport := newTransport("secret", testServer.URL)
opt := &Options{
API: testServer.URL,
}
transport := newTransport("secret", opt)
logger := newLogger(transport)

user := User{
Expand Down
1 change: 1 addition & 0 deletions statsig.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ func Initialize(sdkKey string) {
type Options struct {
API string `json:"api"`
Environment Environment `json:"environment"`
LocalMode bool `json:"localMode"`
}

// See https://docs.statsig.com/guides/usingEnvironments
Expand Down
11 changes: 8 additions & 3 deletions transport.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,17 +25,19 @@ type transport struct {
sdkKey string
metadata statsigMetadata
client *http.Client
options *Options
}

func newTransport(secret string, api string) *transport {
api = defaultString(api, DefaultEndpoint)
func newTransport(secret string, options *Options) *transport {
api := defaultString(options.API, DefaultEndpoint)
api = strings.TrimSuffix(api, "/")

return &transport{
api: api,
metadata: statsigMetadata{SDKType: "go-sdk", SDKVersion: "v1.0.1"},
metadata: statsigMetadata{SDKType: "go-sdk", SDKVersion: "1.1.0"},
sdkKey: secret,
client: &http.Client{},
options: options,
}
}

Expand Down Expand Up @@ -63,6 +65,9 @@ func (transport *transport) postRequestInternal(
retries int,
backoff time.Duration,
) error {
if transport.options.LocalMode {
return nil
}
body, err := json.Marshal(in)
if err != nil {
return err
Expand Down
33 changes: 31 additions & 2 deletions transport_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,39 @@ func TestNonRetryable(t *testing.T) {
defer testServer.Close()
in := Empty{}
var out ServerResponse
n := newTransport("secret-123", testServer.URL)
opt := &Options{
API: testServer.URL,
}
n := newTransport("secret-123", opt)
err := n.retryablePostRequest("/123", in, &out, 2)
if err == nil {
t.Errorf("Expected error for network request but got nil")
}
}

func TestLocalMode(t *testing.T) {
hit := false
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
hit = true
res.WriteHeader(http.StatusNotFound)
}))
defer testServer.Close()
in := Empty{}
var out ServerResponse
opt := &Options{
API: testServer.URL,
LocalMode: true,
}
n := newTransport("secret-123", opt)
err := n.retryablePostRequest("/123", in, &out, 2)
if err != nil {
t.Errorf("Expected no error for network request")
}
if hit {
t.Errorf("Expected transport class not to hit the server")
}
}

func TestRetries(t *testing.T) {
tries := 0
testServer := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
Expand All @@ -50,7 +76,10 @@ func TestRetries(t *testing.T) {
defer func() { testServer.Close() }()
in := Empty{}
var out ServerResponse
n := newTransport("secret-123", testServer.URL)
opt := &Options{
API: testServer.URL,
}
n := newTransport("secret-123", opt)
err := n.retryablePostRequest("/123", in, out, 2)
if err != nil {
t.Errorf("Expected successful request but got error")
Expand Down

0 comments on commit 308f05d

Please sign in to comment.