Skip to content

Commit

Permalink
Added some tests for edge cases.
Browse files Browse the repository at this point in the history
  • Loading branch information
Stephen Asbury committed Aug 27, 2019
1 parent db5dd68 commit 533368e
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 65 deletions.
93 changes: 91 additions & 2 deletions server/core/handlers_pack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package core
import (
"bytes"
"fmt"
"github.com/nats-io/nats-account-server/server/store"
"io/ioutil"
"net/http"
"os"
Expand All @@ -32,7 +33,6 @@ import (
)

func TestPackJWTs(t *testing.T) {

testEnv, err := SetupTestServer(conf.DefaultServerConfig(), false, false)
defer testEnv.Cleanup()
require.NoError(t, err)
Expand Down Expand Up @@ -62,7 +62,11 @@ func TestPackJWTs(t *testing.T) {
require.True(t, resp.StatusCode == http.StatusOK)
}

resp, err := testEnv.HTTP.Get(testEnv.URLForPath("/jwt/v1/pack"))
resp, err := testEnv.HTTP.Get(testEnv.URLForPath("/jwt/v1/pack?max=foo"))
require.NoError(t, err)
require.True(t, resp.StatusCode == http.StatusBadRequest)

resp, err = testEnv.HTTP.Get(testEnv.URLForPath("/jwt/v1/pack"))
require.NoError(t, err)
require.True(t, resp.StatusCode == http.StatusOK)
body, err := ioutil.ReadAll(resp.Body)
Expand Down Expand Up @@ -320,3 +324,88 @@ func TestReplicatedInitWithMaxZero(t *testing.T) {

require.Equal(t, 0, count)
}

func TestPackFailsWithWrongStore(t *testing.T) {
_, _, kp := store.CreateOperatorKey(t)
_, apub, _ := store.CreateAccountKey(t)
s := store.CreateTestStoreForOperator(t, "x", kp)

c := jwt.NewAccountClaims(apub)
c.Name = "foo"
cd, err := c.Encode(kp)
require.NoError(t, err)
err = s.StoreClaim([]byte(cd))
require.NoError(t, err)

config := conf.DefaultServerConfig()
config.Store.Dir = ""
config.Store.NSC = s.Dir
testEnv, err := SetupTestServer(config, false, false)
defer testEnv.Cleanup()
require.NoError(t, err)

resp, err := testEnv.HTTP.Get(testEnv.URLForPath("/jwt/v1/pack"))
require.NoError(t, err)
require.True(t, resp.StatusCode == http.StatusNotFound)
}

func TestReplicatedInitPrimaryDown(t *testing.T) {
testEnv, err := SetupTestServer(conf.DefaultServerConfig(), false, true)
defer testEnv.Cleanup()
require.NoError(t, err)

operatorKey := testEnv.OperatorKey

pubKeys := map[string]string{}

for i := 0; i < 100; i++ {
accountKey, err := nkeys.CreateAccount()
require.NoError(t, err)

pubKey, err := accountKey.PublicKey()
require.NoError(t, err)

account := jwt.NewAccountClaims(pubKey)
acctJWT, err := account.Encode(operatorKey)
require.NoError(t, err)

pubKeys[pubKey] = acctJWT

path := fmt.Sprintf("/jwt/v1/accounts/%s", pubKey)
url := testEnv.URLForPath(path)

resp, err := testEnv.HTTP.Post(url, "application/json", bytes.NewBuffer([]byte(acctJWT)))
require.NoError(t, err)
require.True(t, resp.StatusCode == http.StatusOK)
}

// Now start up the replica
tempDir, err := ioutil.TempDir(os.TempDir(), "prefix")
require.NoError(t, err)

// Turn off the main server, so we only get local content from the replica
testEnv.Server.Stop()

replica, err := testEnv.CreateReplica(tempDir)
require.NoError(t, err)
defer replica.Stop()

count := 0

// Replica should have initialized
for pubkey, jwt := range pubKeys {
path := fmt.Sprintf("/jwt/v1/accounts/%s", pubkey)
url := fmt.Sprintf("%s://%s%s", replica.protocol, replica.hostPort, path)
resp, err := testEnv.HTTP.Get(url)

// only count the ones that we have
if err == nil && resp.StatusCode == http.StatusOK {
body, err := ioutil.ReadAll(resp.Body)
require.NoError(t, err)
require.Equal(t, jwt, string(body))
count++
}
}

require.Equal(t, 0, count)
}
9 changes: 9 additions & 0 deletions server/store/dirstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,15 @@ func TestShardedToUnsharedDirStorePackMerge(t *testing.T) {
got, err = inc.Load("random")
require.Error(t, err)
require.Equal(t, "", got)

err = packable.Merge("foo")
require.Error(t, err)

err = packable.Merge("") // will skip it
require.NoError(t, err)

err = packable.Merge("a|something") // should fail on a for sharding
require.Error(t, err)
}

func TestMergeOnlyOnNewer(t *testing.T) {
Expand Down
6 changes: 6 additions & 0 deletions server/store/memstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,4 +139,10 @@ func TestMemStorePackMerge(t *testing.T) {
got, err = inc.Load("random")
require.Error(t, err)
require.Equal(t, "", got)

err = limitedP.Merge("foo")
require.Error(t, err)

err = limitedP.Merge("") // will skip it
require.NoError(t, err)
}
10 changes: 6 additions & 4 deletions server/store/nscstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,13 @@ func NewNSCJWTStore(dirPath string, changeNotification JWTChanged, errorNotifica
errorOccurred: errorNotification,
}

err = theStore.startWatching()
if changeNotification != nil && errorNotification != nil {
err = theStore.startWatching()

if err != nil {
theStore.Close()
return nil, err
if err != nil {
theStore.Close()
return nil, err
}
}

return theStore, nil
Expand Down
59 changes: 0 additions & 59 deletions server/store/nscstore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,73 +17,14 @@
package store

import (
"fmt"
"io/ioutil"
"os"
"path/filepath"
"testing"
"time"

"github.com/nats-io/jwt"
"github.com/nats-io/nkeys"
nsc "github.com/nats-io/nsc/cmd/store"
"github.com/stretchr/testify/require"
)

type NKeyFactory func() (nkeys.KeyPair, error)

func CreateAccountKey(t *testing.T) (seed []byte, pub string, kp nkeys.KeyPair) {
return CreateTestNKey(t, nkeys.CreateAccount)
}

func CreateOperatorKey(t *testing.T) (seed []byte, pub string, kp nkeys.KeyPair) {
return CreateTestNKey(t, nkeys.CreateOperator)
}

func CreateTestNKey(t *testing.T, f NKeyFactory) ([]byte, string, nkeys.KeyPair) {
kp, err := f()
require.NoError(t, err)

seed, err := kp.Seed()
require.NoError(t, err)

pub, err := kp.PublicKey()
require.NoError(t, err)

return seed, pub, kp
}

func MakeTempStore(t *testing.T, name string, kp nkeys.KeyPair) *nsc.Store {
p, err := ioutil.TempDir("", "store_test")
require.NoError(t, err)

var nk *nsc.NamedKey
if kp != nil {
nk = &nsc.NamedKey{Name: name, KP: kp}
}

s, err := nsc.CreateStore(name, p, nk)
require.NoError(t, err)
require.NotNil(t, s)
return s
}

func CreateTestStoreForOperator(t *testing.T, name string, operator nkeys.KeyPair) *nsc.Store {
s := MakeTempStore(t, name, operator)

require.NotNil(t, s)
require.FileExists(t, filepath.Join(s.Dir, ".nsc"))
require.True(t, s.Has("", ".nsc"))

if operator != nil {
tokenName := fmt.Sprintf("%s.jwt", nsc.SafeName(name))
require.FileExists(t, filepath.Join(s.Dir, tokenName))
require.True(t, s.Has("", tokenName))
}

return s
}

func TestValidNSCStore(t *testing.T) {
_, _, kp := CreateOperatorKey(t)
_, apub, _ := CreateAccountKey(t)
Expand Down
88 changes: 88 additions & 0 deletions server/store/nscstore_test_utils.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* Copyright 2019 The NATS Authors
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package store

import (
"fmt"
"io/ioutil"
"path/filepath"
"testing"

"github.com/nats-io/nkeys"
nsc "github.com/nats-io/nsc/cmd/store"
"github.com/stretchr/testify/require"
)

// NKeyFactory is an extensible way to create a keypair
type NKeyFactory func() (nkeys.KeyPair, error)

// CreateAccountKey makes an account key pair
func CreateAccountKey(t *testing.T) (seed []byte, pub string, kp nkeys.KeyPair) {
return CreateTestNKey(t, nkeys.CreateAccount)
}

// CreateOperatorKey makes an operator key pair
func CreateOperatorKey(t *testing.T) (seed []byte, pub string, kp nkeys.KeyPair) {
return CreateTestNKey(t, nkeys.CreateOperator)
}

// CreateTestNKey makes a key pair from a factory
func CreateTestNKey(t *testing.T, f NKeyFactory) ([]byte, string, nkeys.KeyPair) {
kp, err := f()
require.NoError(t, err)

seed, err := kp.Seed()
require.NoError(t, err)

pub, err := kp.PublicKey()
require.NoError(t, err)

return seed, pub, kp
}

// MakeTempStore builds a temp dir with the store structure
func MakeTempStore(t *testing.T, name string, kp nkeys.KeyPair) *nsc.Store {
p, err := ioutil.TempDir("", "store_test")
require.NoError(t, err)

var nk *nsc.NamedKey
if kp != nil {
nk = &nsc.NamedKey{Name: name, KP: kp}
}

s, err := nsc.CreateStore(name, p, nk)
require.NoError(t, err)
require.NotNil(t, s)
return s
}

// CreateTestStoreForOperator creates a valid nsc folder for testing
func CreateTestStoreForOperator(t *testing.T, name string, operator nkeys.KeyPair) *nsc.Store {
s := MakeTempStore(t, name, operator)

require.NotNil(t, s)
require.FileExists(t, filepath.Join(s.Dir, ".nsc"))
require.True(t, s.Has("", ".nsc"))

if operator != nil {
tokenName := fmt.Sprintf("%s.jwt", nsc.SafeName(name))
require.FileExists(t, filepath.Join(s.Dir, tokenName))
require.True(t, s.Has("", tokenName))
}

return s
}

0 comments on commit 533368e

Please sign in to comment.