forked from TrueCloudLab/certificates
adding more acme nosql unit tests
This commit is contained in:
parent
88e6f00347
commit
7f9ffbd514
4 changed files with 730 additions and 45 deletions
|
@ -101,7 +101,7 @@ func TestDB_getDBChallenge(t *testing.T) {
|
||||||
assert.Equals(t, k.Type, tc.acmeErr.Type)
|
assert.Equals(t, k.Type, tc.acmeErr.Type)
|
||||||
assert.Equals(t, k.Detail, tc.acmeErr.Detail)
|
assert.Equals(t, k.Detail, tc.acmeErr.Detail)
|
||||||
assert.Equals(t, k.Status, tc.acmeErr.Status)
|
assert.Equals(t, k.Status, tc.acmeErr.Status)
|
||||||
assert.Equals(t, k.Err, tc.acmeErr.Err)
|
assert.Equals(t, k.Err.Error(), tc.acmeErr.Err.Error())
|
||||||
assert.Equals(t, k.Detail, tc.acmeErr.Detail)
|
assert.Equals(t, k.Detail, tc.acmeErr.Detail)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
126
acme/db/nosql/nosql_test.go
Normal file
126
acme/db/nosql/nosql_test.go
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
package nosql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/smallstep/assert"
|
||||||
|
"github.com/smallstep/certificates/db"
|
||||||
|
"github.com/smallstep/nosql"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNew(t *testing.T) {
|
||||||
|
type test struct {
|
||||||
|
db nosql.DB
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
var tests = map[string]test{
|
||||||
|
"fail/db.CreateTable-error": test{
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MCreateTable: func(bucket []byte) error {
|
||||||
|
assert.Equals(t, string(bucket), string(accountTable))
|
||||||
|
return errors.New("force")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
err: errors.Errorf("error creating table %s: force", string(accountTable)),
|
||||||
|
},
|
||||||
|
"ok": test{
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MCreateTable: func(bucket []byte) error {
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for name, tc := range tests {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
if _, err := New(tc.db); err != nil {
|
||||||
|
if assert.NotNil(t, tc.err) {
|
||||||
|
assert.HasPrefix(t, err.Error(), tc.err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert.Nil(t, tc.err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type errorThrower string
|
||||||
|
|
||||||
|
func (et errorThrower) MarshalJSON() ([]byte, error) {
|
||||||
|
return nil, errors.New("force")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDB_save(t *testing.T) {
|
||||||
|
type test struct {
|
||||||
|
db nosql.DB
|
||||||
|
nu interface{}
|
||||||
|
old interface{}
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
var tests = map[string]test{
|
||||||
|
"fail/error-marshaling-new": test{
|
||||||
|
nu: errorThrower("foo"),
|
||||||
|
err: errors.New("error marshaling acme type: challenge"),
|
||||||
|
},
|
||||||
|
"fail/error-marshaling-old": test{
|
||||||
|
nu: "new",
|
||||||
|
old: errorThrower("foo"),
|
||||||
|
err: errors.New("error marshaling acme type: challenge"),
|
||||||
|
},
|
||||||
|
"fail/db.CmpAndSwap-error": test{
|
||||||
|
nu: "new",
|
||||||
|
old: "old",
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MCmpAndSwap: func(bucket, key, old, nu []byte) ([]byte, bool, error) {
|
||||||
|
assert.Equals(t, bucket, challengeTable)
|
||||||
|
assert.Equals(t, string(key), "id")
|
||||||
|
assert.Equals(t, string(old), "\"old\"")
|
||||||
|
assert.Equals(t, string(nu), "\"new\"")
|
||||||
|
return nil, false, errors.New("force")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
err: errors.New("error saving acme challenge: force"),
|
||||||
|
},
|
||||||
|
"fail/db.CmpAndSwap-false-marshaling-old": test{
|
||||||
|
nu: "new",
|
||||||
|
old: "old",
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MCmpAndSwap: func(bucket, key, old, nu []byte) ([]byte, bool, error) {
|
||||||
|
assert.Equals(t, bucket, challengeTable)
|
||||||
|
assert.Equals(t, string(key), "id")
|
||||||
|
assert.Equals(t, string(old), "\"old\"")
|
||||||
|
assert.Equals(t, string(nu), "\"new\"")
|
||||||
|
return nil, false, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
err: errors.New("error saving acme challenge; changed since last read"),
|
||||||
|
},
|
||||||
|
"ok": test{
|
||||||
|
nu: "new",
|
||||||
|
old: "old",
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MCmpAndSwap: func(bucket, key, old, nu []byte) ([]byte, bool, error) {
|
||||||
|
assert.Equals(t, bucket, challengeTable)
|
||||||
|
assert.Equals(t, string(key), "id")
|
||||||
|
assert.Equals(t, string(old), "\"old\"")
|
||||||
|
assert.Equals(t, string(nu), "\"new\"")
|
||||||
|
return nu, true, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for name, tc := range tests {
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
db := &DB{db: tc.db}
|
||||||
|
if err := db.save(context.Background(), "id", tc.nu, tc.old, "challenge", challengeTable); err != nil {
|
||||||
|
if assert.NotNil(t, tc.err) {
|
||||||
|
assert.HasPrefix(t, err.Error(), tc.err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert.Nil(t, tc.err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,14 +18,14 @@ type dbOrder struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
AccountID string `json:"accountID"`
|
AccountID string `json:"accountID"`
|
||||||
ProvisionerID string `json:"provisionerID"`
|
ProvisionerID string `json:"provisionerID"`
|
||||||
Created time.Time `json:"created"`
|
CreatedAt time.Time `json:"createdAt"`
|
||||||
Expires time.Time `json:"expires,omitempty"`
|
ExpiresAt time.Time `json:"expiresAt,omitempty"`
|
||||||
Status acme.Status `json:"status"`
|
Status acme.Status `json:"status"`
|
||||||
Identifiers []acme.Identifier `json:"identifiers"`
|
Identifiers []acme.Identifier `json:"identifiers"`
|
||||||
NotBefore time.Time `json:"notBefore,omitempty"`
|
NotBefore time.Time `json:"notBefore,omitempty"`
|
||||||
NotAfter time.Time `json:"notAfter,omitempty"`
|
NotAfter time.Time `json:"notAfter,omitempty"`
|
||||||
Error *acme.Error `json:"error,omitempty"`
|
Error *acme.Error `json:"error,omitempty"`
|
||||||
Authorizations []string `json:"authorizations"`
|
AuthorizationIDs []string `json:"authorizationIDs"`
|
||||||
CertificateID string `json:"certificate,omitempty"`
|
CertificateID string `json:"certificate,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,13 +38,13 @@ func (a *dbOrder) clone() *dbOrder {
|
||||||
func (db *DB) getDBOrder(ctx context.Context, id string) (*dbOrder, error) {
|
func (db *DB) getDBOrder(ctx context.Context, id string) (*dbOrder, error) {
|
||||||
b, err := db.db.Get(orderTable, []byte(id))
|
b, err := db.db.Get(orderTable, []byte(id))
|
||||||
if nosql.IsErrNotFound(err) {
|
if nosql.IsErrNotFound(err) {
|
||||||
return nil, acme.WrapError(acme.ErrorMalformedType, err, "order %s not found", id)
|
return nil, acme.NewError(acme.ErrorMalformedType, "order %s not found", id)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return nil, errors.Wrapf(err, "error loading order %s", id)
|
return nil, errors.Wrapf(err, "error loading order %s", id)
|
||||||
}
|
}
|
||||||
o := new(dbOrder)
|
o := new(dbOrder)
|
||||||
if err := json.Unmarshal(b, &o); err != nil {
|
if err := json.Unmarshal(b, &o); err != nil {
|
||||||
return nil, errors.Wrap(err, "error unmarshaling order")
|
return nil, errors.Wrapf(err, "error unmarshaling order %s into dbOrder", id)
|
||||||
}
|
}
|
||||||
return o, nil
|
return o, nil
|
||||||
}
|
}
|
||||||
|
@ -57,15 +57,17 @@ func (db *DB) GetOrder(ctx context.Context, id string) (*acme.Order, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
o := &acme.Order{
|
o := &acme.Order{
|
||||||
|
ID: dbo.ID,
|
||||||
|
AccountID: dbo.AccountID,
|
||||||
|
ProvisionerID: dbo.ProvisionerID,
|
||||||
|
CertificateID: dbo.CertificateID,
|
||||||
Status: dbo.Status,
|
Status: dbo.Status,
|
||||||
ExpiresAt: dbo.Expires,
|
ExpiresAt: dbo.ExpiresAt,
|
||||||
Identifiers: dbo.Identifiers,
|
Identifiers: dbo.Identifiers,
|
||||||
NotBefore: dbo.NotBefore,
|
NotBefore: dbo.NotBefore,
|
||||||
NotAfter: dbo.NotAfter,
|
NotAfter: dbo.NotAfter,
|
||||||
AuthorizationIDs: dbo.Authorizations,
|
AuthorizationIDs: dbo.AuthorizationIDs,
|
||||||
ID: dbo.ID,
|
Error: dbo.Error,
|
||||||
ProvisionerID: dbo.ProvisionerID,
|
|
||||||
CertificateID: dbo.CertificateID,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return o, nil
|
return o, nil
|
||||||
|
@ -84,13 +86,13 @@ func (db *DB) CreateOrder(ctx context.Context, o *acme.Order) error {
|
||||||
ID: o.ID,
|
ID: o.ID,
|
||||||
AccountID: o.AccountID,
|
AccountID: o.AccountID,
|
||||||
ProvisionerID: o.ProvisionerID,
|
ProvisionerID: o.ProvisionerID,
|
||||||
Created: now,
|
Status: o.Status,
|
||||||
Status: acme.StatusPending,
|
CreatedAt: now,
|
||||||
Expires: o.ExpiresAt,
|
ExpiresAt: o.ExpiresAt,
|
||||||
Identifiers: o.Identifiers,
|
Identifiers: o.Identifiers,
|
||||||
NotBefore: o.NotBefore,
|
NotBefore: o.NotBefore,
|
||||||
NotAfter: o.NotBefore,
|
NotAfter: o.NotBefore,
|
||||||
Authorizations: o.AuthorizationIDs,
|
AuthorizationIDs: o.AuthorizationIDs,
|
||||||
}
|
}
|
||||||
if err := db.save(ctx, o.ID, dbo, nil, "order", orderTable); err != nil {
|
if err := db.save(ctx, o.ID, dbo, nil, "order", orderTable); err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -103,6 +105,21 @@ func (db *DB) CreateOrder(ctx context.Context, o *acme.Order) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateOrder saves an updated ACME Order to the database.
|
||||||
|
func (db *DB) UpdateOrder(ctx context.Context, o *acme.Order) error {
|
||||||
|
old, err := db.getDBOrder(ctx, o.ID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
nu := old.clone()
|
||||||
|
|
||||||
|
nu.Status = o.Status
|
||||||
|
nu.Error = o.Error
|
||||||
|
nu.CertificateID = o.CertificateID
|
||||||
|
return db.save(ctx, old.ID, nu, old, "order", orderTable)
|
||||||
|
}
|
||||||
|
|
||||||
type orderIDsByAccount struct{}
|
type orderIDsByAccount struct{}
|
||||||
|
|
||||||
func (db *DB) updateAddOrderIDs(ctx context.Context, accID string, addOids ...string) ([]string, error) {
|
func (db *DB) updateAddOrderIDs(ctx context.Context, accID string, addOids ...string) ([]string, error) {
|
||||||
|
@ -158,18 +175,3 @@ func (db *DB) updateAddOrderIDs(ctx context.Context, accID string, addOids ...st
|
||||||
func (db *DB) GetOrdersByAccountID(ctx context.Context, accID string) ([]string, error) {
|
func (db *DB) GetOrdersByAccountID(ctx context.Context, accID string) ([]string, error) {
|
||||||
return db.updateAddOrderIDs(ctx, accID)
|
return db.updateAddOrderIDs(ctx, accID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdateOrder saves an updated ACME Order to the database.
|
|
||||||
func (db *DB) UpdateOrder(ctx context.Context, o *acme.Order) error {
|
|
||||||
old, err := db.getDBOrder(ctx, o.ID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
nu := old.clone()
|
|
||||||
|
|
||||||
nu.Status = o.Status
|
|
||||||
nu.Error = o.Error
|
|
||||||
nu.CertificateID = o.CertificateID
|
|
||||||
return db.save(ctx, old.ID, nu, old, "order", orderTable)
|
|
||||||
}
|
|
||||||
|
|
557
acme/db/nosql/order_test.go
Normal file
557
acme/db/nosql/order_test.go
Normal file
|
@ -0,0 +1,557 @@
|
||||||
|
package nosql
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/smallstep/assert"
|
||||||
|
"github.com/smallstep/certificates/acme"
|
||||||
|
"github.com/smallstep/certificates/db"
|
||||||
|
"github.com/smallstep/nosql"
|
||||||
|
nosqldb "github.com/smallstep/nosql/database"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestDB_getDBOrder(t *testing.T) {
|
||||||
|
orderID := "orderID"
|
||||||
|
type test struct {
|
||||||
|
db nosql.DB
|
||||||
|
err error
|
||||||
|
acmeErr *acme.Error
|
||||||
|
dbo *dbOrder
|
||||||
|
}
|
||||||
|
var tests = map[string]func(t *testing.T) test{
|
||||||
|
"fail/not-found": func(t *testing.T) test {
|
||||||
|
return test{
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MGet: func(bucket, key []byte) ([]byte, error) {
|
||||||
|
assert.Equals(t, bucket, orderTable)
|
||||||
|
assert.Equals(t, string(key), orderID)
|
||||||
|
|
||||||
|
return nil, nosqldb.ErrNotFound
|
||||||
|
},
|
||||||
|
},
|
||||||
|
acmeErr: acme.NewError(acme.ErrorMalformedType, "order orderID not found"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fail/db.Get-error": func(t *testing.T) test {
|
||||||
|
return test{
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MGet: func(bucket, key []byte) ([]byte, error) {
|
||||||
|
assert.Equals(t, bucket, orderTable)
|
||||||
|
assert.Equals(t, string(key), orderID)
|
||||||
|
|
||||||
|
return nil, errors.New("force")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
err: errors.New("error loading order orderID: force"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fail/unmarshal-error": func(t *testing.T) test {
|
||||||
|
return test{
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MGet: func(bucket, key []byte) ([]byte, error) {
|
||||||
|
assert.Equals(t, bucket, orderTable)
|
||||||
|
assert.Equals(t, string(key), orderID)
|
||||||
|
|
||||||
|
return []byte("foo"), nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
err: errors.New("error unmarshaling order orderID into dbOrder"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ok": func(t *testing.T) test {
|
||||||
|
now := clock.Now()
|
||||||
|
dbo := &dbOrder{
|
||||||
|
ID: orderID,
|
||||||
|
AccountID: "accID",
|
||||||
|
ProvisionerID: "provID",
|
||||||
|
CertificateID: "certID",
|
||||||
|
Status: acme.StatusValid,
|
||||||
|
ExpiresAt: now,
|
||||||
|
CreatedAt: now,
|
||||||
|
NotBefore: now,
|
||||||
|
NotAfter: now,
|
||||||
|
Identifiers: []acme.Identifier{
|
||||||
|
{Type: "dns", Value: "test.ca.smallstep.com"},
|
||||||
|
{Type: "dns", Value: "example.foo.com"},
|
||||||
|
},
|
||||||
|
AuthorizationIDs: []string{"foo", "bar"},
|
||||||
|
Error: acme.NewError(acme.ErrorMalformedType, "force"),
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(dbo)
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
return test{
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MGet: func(bucket, key []byte) ([]byte, error) {
|
||||||
|
assert.Equals(t, bucket, orderTable)
|
||||||
|
assert.Equals(t, string(key), orderID)
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
dbo: dbo,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for name, run := range tests {
|
||||||
|
tc := run(t)
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
db := DB{db: tc.db}
|
||||||
|
if dbo, err := db.getDBOrder(context.Background(), orderID); err != nil {
|
||||||
|
switch k := err.(type) {
|
||||||
|
case *acme.Error:
|
||||||
|
if assert.NotNil(t, tc.acmeErr) {
|
||||||
|
assert.Equals(t, k.Type, tc.acmeErr.Type)
|
||||||
|
assert.Equals(t, k.Detail, tc.acmeErr.Detail)
|
||||||
|
assert.Equals(t, k.Status, tc.acmeErr.Status)
|
||||||
|
assert.Equals(t, k.Err.Error(), tc.acmeErr.Err.Error())
|
||||||
|
assert.Equals(t, k.Detail, tc.acmeErr.Detail)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if assert.NotNil(t, tc.err) {
|
||||||
|
assert.HasPrefix(t, err.Error(), tc.err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if assert.Nil(t, tc.err) {
|
||||||
|
assert.Equals(t, dbo.ID, tc.dbo.ID)
|
||||||
|
assert.Equals(t, dbo.ProvisionerID, tc.dbo.ProvisionerID)
|
||||||
|
assert.Equals(t, dbo.CertificateID, tc.dbo.CertificateID)
|
||||||
|
assert.Equals(t, dbo.Status, tc.dbo.Status)
|
||||||
|
assert.Equals(t, dbo.CreatedAt, tc.dbo.CreatedAt)
|
||||||
|
assert.Equals(t, dbo.ExpiresAt, tc.dbo.ExpiresAt)
|
||||||
|
assert.Equals(t, dbo.NotBefore, tc.dbo.NotBefore)
|
||||||
|
assert.Equals(t, dbo.NotAfter, tc.dbo.NotAfter)
|
||||||
|
assert.Equals(t, dbo.Identifiers, tc.dbo.Identifiers)
|
||||||
|
assert.Equals(t, dbo.AuthorizationIDs, tc.dbo.AuthorizationIDs)
|
||||||
|
assert.Equals(t, dbo.Error.Error(), tc.dbo.Error.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDB_GetOrder(t *testing.T) {
|
||||||
|
orderID := "orderID"
|
||||||
|
type test struct {
|
||||||
|
db nosql.DB
|
||||||
|
err error
|
||||||
|
acmeErr *acme.Error
|
||||||
|
dbo *dbOrder
|
||||||
|
}
|
||||||
|
var tests = map[string]func(t *testing.T) test{
|
||||||
|
"fail/db.Get-error": func(t *testing.T) test {
|
||||||
|
return test{
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MGet: func(bucket, key []byte) ([]byte, error) {
|
||||||
|
assert.Equals(t, bucket, orderTable)
|
||||||
|
assert.Equals(t, string(key), orderID)
|
||||||
|
|
||||||
|
return nil, errors.New("force")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
err: errors.New("error loading order orderID: force"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fail/forward-acme-error": func(t *testing.T) test {
|
||||||
|
return test{
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MGet: func(bucket, key []byte) ([]byte, error) {
|
||||||
|
assert.Equals(t, bucket, orderTable)
|
||||||
|
assert.Equals(t, string(key), orderID)
|
||||||
|
|
||||||
|
return nil, nosqldb.ErrNotFound
|
||||||
|
},
|
||||||
|
},
|
||||||
|
acmeErr: acme.NewError(acme.ErrorMalformedType, "order orderID not found"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ok": func(t *testing.T) test {
|
||||||
|
now := clock.Now()
|
||||||
|
dbo := &dbOrder{
|
||||||
|
ID: orderID,
|
||||||
|
AccountID: "accID",
|
||||||
|
ProvisionerID: "provID",
|
||||||
|
CertificateID: "certID",
|
||||||
|
Status: acme.StatusValid,
|
||||||
|
ExpiresAt: now,
|
||||||
|
CreatedAt: now,
|
||||||
|
NotBefore: now,
|
||||||
|
NotAfter: now,
|
||||||
|
Identifiers: []acme.Identifier{
|
||||||
|
{Type: "dns", Value: "test.ca.smallstep.com"},
|
||||||
|
{Type: "dns", Value: "example.foo.com"},
|
||||||
|
},
|
||||||
|
AuthorizationIDs: []string{"foo", "bar"},
|
||||||
|
Error: acme.NewError(acme.ErrorMalformedType, "force"),
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(dbo)
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
return test{
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MGet: func(bucket, key []byte) ([]byte, error) {
|
||||||
|
assert.Equals(t, bucket, orderTable)
|
||||||
|
assert.Equals(t, string(key), orderID)
|
||||||
|
return b, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
dbo: dbo,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for name, run := range tests {
|
||||||
|
tc := run(t)
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
db := DB{db: tc.db}
|
||||||
|
if o, err := db.GetOrder(context.Background(), orderID); err != nil {
|
||||||
|
switch k := err.(type) {
|
||||||
|
case *acme.Error:
|
||||||
|
if assert.NotNil(t, tc.acmeErr) {
|
||||||
|
assert.Equals(t, k.Type, tc.acmeErr.Type)
|
||||||
|
assert.Equals(t, k.Detail, tc.acmeErr.Detail)
|
||||||
|
assert.Equals(t, k.Status, tc.acmeErr.Status)
|
||||||
|
assert.Equals(t, k.Err.Error(), tc.acmeErr.Err.Error())
|
||||||
|
assert.Equals(t, k.Detail, tc.acmeErr.Detail)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
if assert.NotNil(t, tc.err) {
|
||||||
|
assert.HasPrefix(t, err.Error(), tc.err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if assert.Nil(t, tc.err) {
|
||||||
|
assert.Equals(t, o.ID, tc.dbo.ID)
|
||||||
|
assert.Equals(t, o.AccountID, tc.dbo.AccountID)
|
||||||
|
assert.Equals(t, o.ProvisionerID, tc.dbo.ProvisionerID)
|
||||||
|
assert.Equals(t, o.CertificateID, tc.dbo.CertificateID)
|
||||||
|
assert.Equals(t, o.Status, tc.dbo.Status)
|
||||||
|
assert.Equals(t, o.ExpiresAt, tc.dbo.ExpiresAt)
|
||||||
|
assert.Equals(t, o.NotBefore, tc.dbo.NotBefore)
|
||||||
|
assert.Equals(t, o.NotAfter, tc.dbo.NotAfter)
|
||||||
|
assert.Equals(t, o.Identifiers, tc.dbo.Identifiers)
|
||||||
|
assert.Equals(t, o.AuthorizationIDs, tc.dbo.AuthorizationIDs)
|
||||||
|
assert.Equals(t, o.Error.Error(), tc.dbo.Error.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDB_UpdateOrder(t *testing.T) {
|
||||||
|
orderID := "orderID"
|
||||||
|
now := clock.Now()
|
||||||
|
dbo := &dbOrder{
|
||||||
|
ID: orderID,
|
||||||
|
AccountID: "accID",
|
||||||
|
ProvisionerID: "provID",
|
||||||
|
Status: acme.StatusPending,
|
||||||
|
ExpiresAt: now,
|
||||||
|
CreatedAt: now,
|
||||||
|
NotBefore: now,
|
||||||
|
NotAfter: now,
|
||||||
|
Identifiers: []acme.Identifier{
|
||||||
|
{Type: "dns", Value: "test.ca.smallstep.com"},
|
||||||
|
{Type: "dns", Value: "example.foo.com"},
|
||||||
|
},
|
||||||
|
AuthorizationIDs: []string{"foo", "bar"},
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(dbo)
|
||||||
|
assert.FatalError(t, err)
|
||||||
|
type test struct {
|
||||||
|
db nosql.DB
|
||||||
|
o *acme.Order
|
||||||
|
err error
|
||||||
|
}
|
||||||
|
var tests = map[string]func(t *testing.T) test{
|
||||||
|
"fail/db.Get-error": func(t *testing.T) test {
|
||||||
|
return test{
|
||||||
|
o: &acme.Order{
|
||||||
|
ID: orderID,
|
||||||
|
},
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MGet: func(bucket, key []byte) ([]byte, error) {
|
||||||
|
assert.Equals(t, bucket, orderTable)
|
||||||
|
assert.Equals(t, string(key), orderID)
|
||||||
|
|
||||||
|
return nil, errors.New("force")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
err: errors.New("error loading order orderID: force"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fail/save-error": func(t *testing.T) test {
|
||||||
|
o := &acme.Order{
|
||||||
|
ID: orderID,
|
||||||
|
Status: acme.StatusValid,
|
||||||
|
CertificateID: "certID",
|
||||||
|
Error: acme.NewError(acme.ErrorMalformedType, "force"),
|
||||||
|
}
|
||||||
|
return test{
|
||||||
|
o: o,
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MGet: func(bucket, key []byte) ([]byte, error) {
|
||||||
|
assert.Equals(t, bucket, orderTable)
|
||||||
|
assert.Equals(t, string(key), orderID)
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
},
|
||||||
|
MCmpAndSwap: func(bucket, key, old, nu []byte) ([]byte, bool, error) {
|
||||||
|
assert.Equals(t, bucket, orderTable)
|
||||||
|
assert.Equals(t, old, b)
|
||||||
|
|
||||||
|
dbNew := new(dbOrder)
|
||||||
|
assert.FatalError(t, json.Unmarshal(nu, dbNew))
|
||||||
|
assert.Equals(t, dbNew.ID, dbo.ID)
|
||||||
|
assert.Equals(t, dbNew.AccountID, dbo.AccountID)
|
||||||
|
assert.Equals(t, dbNew.ProvisionerID, dbo.ProvisionerID)
|
||||||
|
assert.Equals(t, dbNew.CertificateID, o.CertificateID)
|
||||||
|
assert.Equals(t, dbNew.Status, o.Status)
|
||||||
|
assert.Equals(t, dbNew.CreatedAt, dbo.CreatedAt)
|
||||||
|
assert.Equals(t, dbNew.ExpiresAt, dbo.ExpiresAt)
|
||||||
|
assert.Equals(t, dbNew.NotBefore, dbo.NotBefore)
|
||||||
|
assert.Equals(t, dbNew.NotAfter, dbo.NotAfter)
|
||||||
|
assert.Equals(t, dbNew.AuthorizationIDs, dbo.AuthorizationIDs)
|
||||||
|
assert.Equals(t, dbNew.Identifiers, dbo.Identifiers)
|
||||||
|
assert.Equals(t, dbNew.Error.Error(), o.Error.Error())
|
||||||
|
return nil, false, errors.New("force")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
err: errors.New("error saving acme order: force"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ok": func(t *testing.T) test {
|
||||||
|
o := &acme.Order{
|
||||||
|
ID: orderID,
|
||||||
|
Status: acme.StatusValid,
|
||||||
|
CertificateID: "certID",
|
||||||
|
Error: acme.NewError(acme.ErrorMalformedType, "force"),
|
||||||
|
}
|
||||||
|
return test{
|
||||||
|
o: o,
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MGet: func(bucket, key []byte) ([]byte, error) {
|
||||||
|
assert.Equals(t, bucket, orderTable)
|
||||||
|
assert.Equals(t, string(key), orderID)
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
},
|
||||||
|
MCmpAndSwap: func(bucket, key, old, nu []byte) ([]byte, bool, error) {
|
||||||
|
assert.Equals(t, bucket, orderTable)
|
||||||
|
assert.Equals(t, old, b)
|
||||||
|
|
||||||
|
dbNew := new(dbOrder)
|
||||||
|
assert.FatalError(t, json.Unmarshal(nu, dbNew))
|
||||||
|
assert.Equals(t, dbNew.ID, dbo.ID)
|
||||||
|
assert.Equals(t, dbNew.AccountID, dbo.AccountID)
|
||||||
|
assert.Equals(t, dbNew.ProvisionerID, dbo.ProvisionerID)
|
||||||
|
assert.Equals(t, dbNew.CertificateID, o.CertificateID)
|
||||||
|
assert.Equals(t, dbNew.Status, o.Status)
|
||||||
|
assert.Equals(t, dbNew.CreatedAt, dbo.CreatedAt)
|
||||||
|
assert.Equals(t, dbNew.ExpiresAt, dbo.ExpiresAt)
|
||||||
|
assert.Equals(t, dbNew.NotBefore, dbo.NotBefore)
|
||||||
|
assert.Equals(t, dbNew.NotAfter, dbo.NotAfter)
|
||||||
|
assert.Equals(t, dbNew.AuthorizationIDs, dbo.AuthorizationIDs)
|
||||||
|
assert.Equals(t, dbNew.Identifiers, dbo.Identifiers)
|
||||||
|
assert.Equals(t, dbNew.Error.Error(), o.Error.Error())
|
||||||
|
return nu, true, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for name, run := range tests {
|
||||||
|
tc := run(t)
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
db := DB{db: tc.db}
|
||||||
|
if err := db.UpdateOrder(context.Background(), tc.o); err != nil {
|
||||||
|
if assert.NotNil(t, tc.err) {
|
||||||
|
assert.HasPrefix(t, err.Error(), tc.err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if assert.Nil(t, tc.err) {
|
||||||
|
assert.Equals(t, tc.o.ID, dbo.ID)
|
||||||
|
assert.Equals(t, tc.o.CertificateID, "certID")
|
||||||
|
assert.Equals(t, tc.o.Status, acme.StatusValid)
|
||||||
|
assert.Equals(t, tc.o.Error.Error(), acme.NewError(acme.ErrorMalformedType, "force").Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDB_CreateOrder(t *testing.T) {
|
||||||
|
now := clock.Now()
|
||||||
|
type test struct {
|
||||||
|
db nosql.DB
|
||||||
|
o *acme.Order
|
||||||
|
err error
|
||||||
|
_id *string
|
||||||
|
}
|
||||||
|
var tests = map[string]func(t *testing.T) test{
|
||||||
|
"fail/order-save-error": func(t *testing.T) test {
|
||||||
|
o := &acme.Order{
|
||||||
|
AccountID: "accID",
|
||||||
|
ProvisionerID: "provID",
|
||||||
|
CertificateID: "certID",
|
||||||
|
Status: acme.StatusValid,
|
||||||
|
ExpiresAt: now,
|
||||||
|
NotBefore: now,
|
||||||
|
NotAfter: now,
|
||||||
|
Identifiers: []acme.Identifier{
|
||||||
|
{Type: "dns", Value: "test.ca.smallstep.com"},
|
||||||
|
{Type: "dns", Value: "example.foo.com"},
|
||||||
|
},
|
||||||
|
AuthorizationIDs: []string{"foo", "bar"},
|
||||||
|
}
|
||||||
|
return test{
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MCmpAndSwap: func(bucket, key, old, nu []byte) ([]byte, bool, error) {
|
||||||
|
assert.Equals(t, string(bucket), string(orderTable))
|
||||||
|
assert.Equals(t, string(key), o.ID)
|
||||||
|
assert.Equals(t, old, nil)
|
||||||
|
|
||||||
|
dbo := new(dbOrder)
|
||||||
|
assert.FatalError(t, json.Unmarshal(nu, dbo))
|
||||||
|
assert.Equals(t, dbo.ID, o.ID)
|
||||||
|
assert.Equals(t, dbo.AccountID, o.AccountID)
|
||||||
|
assert.Equals(t, dbo.ProvisionerID, o.ProvisionerID)
|
||||||
|
assert.Equals(t, dbo.CertificateID, "")
|
||||||
|
assert.Equals(t, dbo.Status, o.Status)
|
||||||
|
assert.True(t, dbo.CreatedAt.Add(-time.Minute).Before(now))
|
||||||
|
assert.True(t, dbo.CreatedAt.Add(time.Minute).After(now))
|
||||||
|
assert.Equals(t, dbo.ExpiresAt, o.ExpiresAt)
|
||||||
|
assert.Equals(t, dbo.NotBefore, o.NotBefore)
|
||||||
|
assert.Equals(t, dbo.NotAfter, o.NotAfter)
|
||||||
|
assert.Equals(t, dbo.AuthorizationIDs, o.AuthorizationIDs)
|
||||||
|
assert.Equals(t, dbo.Identifiers, o.Identifiers)
|
||||||
|
assert.Equals(t, dbo.Error, nil)
|
||||||
|
return nil, false, errors.New("force")
|
||||||
|
},
|
||||||
|
},
|
||||||
|
o: o,
|
||||||
|
err: errors.New("error saving acme order: force"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fail/orderIDsByOrderUpdate-error": func(t *testing.T) test {
|
||||||
|
o := &acme.Order{
|
||||||
|
AccountID: "accID",
|
||||||
|
ProvisionerID: "provID",
|
||||||
|
CertificateID: "certID",
|
||||||
|
Status: acme.StatusValid,
|
||||||
|
ExpiresAt: now,
|
||||||
|
NotBefore: now,
|
||||||
|
NotAfter: now,
|
||||||
|
Identifiers: []acme.Identifier{
|
||||||
|
{Type: "dns", Value: "test.ca.smallstep.com"},
|
||||||
|
{Type: "dns", Value: "example.foo.com"},
|
||||||
|
},
|
||||||
|
AuthorizationIDs: []string{"foo", "bar"},
|
||||||
|
}
|
||||||
|
return test{
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MGet: func(bucket, key []byte) ([]byte, error) {
|
||||||
|
assert.Equals(t, string(bucket), string(ordersByAccountIDTable))
|
||||||
|
assert.Equals(t, string(key), o.AccountID)
|
||||||
|
return nil, errors.New("force")
|
||||||
|
},
|
||||||
|
MCmpAndSwap: func(bucket, key, old, nu []byte) ([]byte, bool, error) {
|
||||||
|
assert.Equals(t, string(bucket), string(orderTable))
|
||||||
|
assert.Equals(t, string(key), o.ID)
|
||||||
|
assert.Equals(t, old, nil)
|
||||||
|
|
||||||
|
dbo := new(dbOrder)
|
||||||
|
assert.FatalError(t, json.Unmarshal(nu, dbo))
|
||||||
|
assert.Equals(t, dbo.ID, o.ID)
|
||||||
|
assert.Equals(t, dbo.AccountID, o.AccountID)
|
||||||
|
assert.Equals(t, dbo.ProvisionerID, o.ProvisionerID)
|
||||||
|
assert.Equals(t, dbo.CertificateID, "")
|
||||||
|
assert.Equals(t, dbo.Status, o.Status)
|
||||||
|
assert.True(t, dbo.CreatedAt.Add(-time.Minute).Before(now))
|
||||||
|
assert.True(t, dbo.CreatedAt.Add(time.Minute).After(now))
|
||||||
|
assert.Equals(t, dbo.ExpiresAt, o.ExpiresAt)
|
||||||
|
assert.Equals(t, dbo.NotBefore, o.NotBefore)
|
||||||
|
assert.Equals(t, dbo.NotAfter, o.NotAfter)
|
||||||
|
assert.Equals(t, dbo.AuthorizationIDs, o.AuthorizationIDs)
|
||||||
|
assert.Equals(t, dbo.Identifiers, o.Identifiers)
|
||||||
|
assert.Equals(t, dbo.Error, nil)
|
||||||
|
return nu, true, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
o: o,
|
||||||
|
err: errors.New("error loading orderIDs for account accID: force"),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ok": func(t *testing.T) test {
|
||||||
|
var (
|
||||||
|
id string
|
||||||
|
idptr = &id
|
||||||
|
)
|
||||||
|
|
||||||
|
o := &acme.Order{
|
||||||
|
AccountID: "accID",
|
||||||
|
ProvisionerID: "provID",
|
||||||
|
Status: acme.StatusValid,
|
||||||
|
ExpiresAt: now,
|
||||||
|
NotBefore: now,
|
||||||
|
NotAfter: now,
|
||||||
|
Identifiers: []acme.Identifier{
|
||||||
|
{Type: "dns", Value: "test.ca.smallstep.com"},
|
||||||
|
{Type: "dns", Value: "example.foo.com"},
|
||||||
|
},
|
||||||
|
AuthorizationIDs: []string{"foo", "bar"},
|
||||||
|
}
|
||||||
|
return test{
|
||||||
|
db: &db.MockNoSQLDB{
|
||||||
|
MGet: func(bucket, key []byte) ([]byte, error) {
|
||||||
|
assert.Equals(t, string(bucket), string(ordersByAccountIDTable))
|
||||||
|
assert.Equals(t, string(key), o.AccountID)
|
||||||
|
return nil, nosqldb.ErrNotFound
|
||||||
|
},
|
||||||
|
MCmpAndSwap: func(bucket, key, old, nu []byte) ([]byte, bool, error) {
|
||||||
|
*idptr = string(key)
|
||||||
|
assert.Equals(t, string(bucket), string(orderTable))
|
||||||
|
assert.Equals(t, string(key), o.ID)
|
||||||
|
assert.Equals(t, old, nil)
|
||||||
|
|
||||||
|
dbo := new(dbOrder)
|
||||||
|
assert.FatalError(t, json.Unmarshal(nu, dbo))
|
||||||
|
assert.Equals(t, dbo.ID, o.ID)
|
||||||
|
assert.Equals(t, dbo.AccountID, o.AccountID)
|
||||||
|
assert.Equals(t, dbo.ProvisionerID, o.ProvisionerID)
|
||||||
|
assert.Equals(t, dbo.CertificateID, "")
|
||||||
|
assert.Equals(t, dbo.Status, o.Status)
|
||||||
|
assert.True(t, dbo.CreatedAt.Add(-time.Minute).Before(now))
|
||||||
|
assert.True(t, dbo.CreatedAt.Add(time.Minute).After(now))
|
||||||
|
assert.Equals(t, dbo.ExpiresAt, o.ExpiresAt)
|
||||||
|
assert.Equals(t, dbo.NotBefore, o.NotBefore)
|
||||||
|
assert.Equals(t, dbo.NotAfter, o.NotAfter)
|
||||||
|
assert.Equals(t, dbo.AuthorizationIDs, o.AuthorizationIDs)
|
||||||
|
assert.Equals(t, dbo.Identifiers, o.Identifiers)
|
||||||
|
assert.Equals(t, dbo.Error, nil)
|
||||||
|
return nu, true, nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
o: o,
|
||||||
|
_id: idptr,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for name, run := range tests {
|
||||||
|
tc := run(t)
|
||||||
|
t.Run(name, func(t *testing.T) {
|
||||||
|
db := DB{db: tc.db}
|
||||||
|
if err := db.CreateOrder(context.Background(), tc.o); err != nil {
|
||||||
|
if assert.NotNil(t, tc.err) {
|
||||||
|
assert.HasPrefix(t, err.Error(), tc.err.Error())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if assert.Nil(t, tc.err) {
|
||||||
|
assert.Equals(t, tc.o.ID, *tc._id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue