func TestClient(t *testing.T) {
	client, err := New(target, grpc.WithInsecure())
	helpers.CheckError(t, err)

	req := &pb.AllowRequest{
		Namespace:             "Doesn't exist",
		BucketName:            "Doesn't exist",
		TokensRequested:       1,
		MaxWaitMillisOverride: math.MaxInt64}
	resp, err := client.Allow(req)
	helpers.CheckError(t, err)
	if resp.Status != pb.AllowResponse_OK {
		t.Fatalf("Expected OK. Was %v", pb.AllowResponse_Status_name[int32(resp.Status)])
	}
}
func TestDiskPersistence(t *testing.T) {
	persister, e := NewDiskConfigPersister("/tmp/qs_test_persistence")
	helpers.CheckError(t, e)

	select {
	case <-persister.ConfigChangedWatcher():
		// This is good.
	default:
		t.Fatal("Config channel should not be empty!")
	}

	s := &pbconfig.ServiceConfig{
		GlobalDefaultBucket: &pbconfig.BucketConfig{Size: 300, FillRate: 400, WaitTimeoutMillis: 123456},
		Namespaces:          make(map[string]*pbconfig.NamespaceConfig, 1),
		Version:             92}

	nc := &pbconfig.NamespaceConfig{
		Name:              "xyz",
		MaxDynamicBuckets: 123}

	SetDynamicBucketTemplate(nc, &pbconfig.BucketConfig{})
	AddNamespace(s, nc)

	// Store s.
	r, e := Marshal(s)
	helpers.CheckError(t, e)
	e = persister.PersistAndNotify(r)
	helpers.CheckError(t, e)

	// Test notification
	select {
	case <-persister.ConfigChangedWatcher():
	// This is good.
	default:
		t.Fatal("Config channel should not be empty!")
	}

	r, e = persister.ReadPersistedConfig()
	helpers.CheckError(t, e)
	unmarshalled, e := Unmarshal(r)
	helpers.CheckError(t, e)

	if !reflect.DeepEqual(s, unmarshalled) {
		t.Fatalf("Configs should be equal! %+v != %+v", s, unmarshalled)
	}

	cfgs, e := persister.ReadHistoricalConfigs()
	helpers.CheckError(t, e)

	if len(cfgs) != 1 {
		t.Fatalf("Historical configs is not correct! %+v", cfgs)
	}

	unmarshalled, e = Unmarshal(cfgs[0])
	helpers.CheckError(t, e)

	if !reflect.DeepEqual(s, unmarshalled) {
		t.Fatalf("Configs should be equal! %+v != %+v", s, unmarshalled)
	}
}
func TestSetExisting(t *testing.T) {
	p, err := NewZkConfigPersister("/existing", servers)
	helpers.CheckError(t, err)

	defer p.(*ZkConfigPersister).Close()

	select {
	case <-p.ConfigChangedWatcher():
	// this is good
	default:
		t.Fatal("Config channel should not be empty!")
	}

	cfg, err := p.ReadPersistedConfig()
	helpers.CheckError(t, err)

	err = p.PersistAndNotify(cfg)
	helpers.CheckError(t, err)
}
func TestSetAndNotify(t *testing.T) {
	p, err := NewZkConfigPersister("/existing", servers)
	helpers.CheckError(t, err)

	defer p.(*ZkConfigPersister).Close()

	<-p.ConfigChangedWatcher()

	cfg := NewDefaultServiceConfig()
	cfg.Namespaces["foo"] = NewDefaultNamespaceConfig("foo")

	r, err := Marshal(cfg)
	helpers.CheckError(t, err)

	p.PersistAndNotify(r)

	select {
	case <-p.ConfigChangedWatcher():
	case <-time.After(time.Second * 1):
		t.Fatalf("Did not receive notification!")
	}

	ioCfg, err := p.ReadPersistedConfig()
	helpers.CheckError(t, err)

	newConfig, err := Unmarshal(ioCfg)
	helpers.CheckError(t, err)

	if newConfig.Namespaces["foo"] == nil {
		t.Errorf("Config is not valid: %+v", newConfig)
	}

	cfg.Namespaces["bar"] = NewDefaultNamespaceConfig("bar")

	r, err = Marshal(cfg)
	helpers.CheckError(t, err)

	p.PersistAndNotify(r)

	select {
	case <-p.ConfigChangedWatcher():
	case <-time.After(time.Second * 1):
		t.Fatalf("Did not receive notification!")
	}

	ioCfg, err = p.ReadPersistedConfig()
	helpers.CheckError(t, err)

	newConfig, err = Unmarshal(ioCfg)
	helpers.CheckError(t, err)

	if newConfig.Namespaces["bar"] == nil {
		t.Errorf("Config is not valid: %+v", newConfig)
	}
}
func TestHistoricalConfigs(t *testing.T) {
	p, err := NewZkConfigPersister("/historic", servers)
	helpers.CheckError(t, err)

	defer p.(*ZkConfigPersister).Close()

	<-p.ConfigChangedWatcher()

	cfgs, err := p.ReadHistoricalConfigs()
	helpers.CheckError(t, err)

	if len(cfgs) != 1 {
		t.Fatalf("Historical configs are not correct: %+v", cfgs)
	}

	newConfig, err := Unmarshal(cfgs[0])
	helpers.CheckError(t, err)

	if newConfig.Namespaces["test"] == nil {
		t.Errorf("Config is not valid: %+v", newConfig)
	}
}
func TestNewExisting(t *testing.T) {
	p, err := NewZkConfigPersister("/existing", servers)
	helpers.CheckError(t, err)

	defer p.(*ZkConfigPersister).Close()

	select {
	case <-p.ConfigChangedWatcher():
	// this is good
	default:
		t.Fatal("Config channel should not be empty!")
	}

	cfg, err := p.ReadPersistedConfig()
	helpers.CheckError(t, err)

	newConfig, err := Unmarshal(cfg)
	helpers.CheckError(t, err)

	if newConfig.Namespaces["test"] == nil {
		t.Errorf("Config is not valid: %+v", newConfig)
	}
}
func TestNew(t *testing.T) {
	p, err := NewZkConfigPersister("/quotaservice", servers)
	helpers.CheckError(t, err)

	defer p.(*ZkConfigPersister).Close()

	select {
	case <-p.ConfigChangedWatcher():
	// this is good
	default:
		t.Error("Config channel should not be empty!")
	}

	cfg, err := p.ReadPersistedConfig()
	helpers.CheckError(t, err)

	cfgArray, err := ioutil.ReadAll(cfg)
	helpers.CheckError(t, err)

	if len(cfgArray) > 0 {
		t.Errorf("Received non-empty cfg on new node: %+v", cfgArray)
	}
}
func TestBlockingClient(t *testing.T) {
	// Claim tokens
	client, err := New(target, grpc.WithInsecure())
	helpers.CheckError(t, err)

	waitTime := 0
	n := 0
	req := &pb.AllowRequest{
		Namespace:             "delaying",
		BucketName:            "delaying",
		TokensRequested:       1,
		MaxWaitMillisOverride: math.MaxInt64}

	// Consume all readily available tokens
	for waitTime == 0 {
		resp, err := client.Allow(req)
		helpers.CheckError(t, err)
		if resp.Status != pb.AllowResponse_OK {
			t.Fatalf("Expected OK. Was %v\n", pb.AllowResponse_Status_name[int32(resp.Status)])
		}
		waitTime = int(resp.WaitMillis)
		n++
	}

	// Next attempt should block at least waitTime millis.
	start := time.Now()
	e := client.AllowBlocking(req)
	elapsed := time.Since(start)
	helpers.CheckError(t, e)
	expected := time.Duration(waitTime) * time.Millisecond

	if elapsed < expected {
		t.Fatalf("Expected to block for at least %v but was just %v", expected, elapsed)
	}

}