Always convert empty list to nil when saving orderIDs index.

This commit is contained in:
max furman 2020-06-01 18:04:51 -07:00
parent 619f6f6ce0
commit 41a1a053d8
3 changed files with 72 additions and 4 deletions

View file

@ -524,6 +524,43 @@ func Test_getOrderIDsByAccount(t *testing.T) {
res: []string{"o2", "o4"}, res: []string{"o2", "o4"},
} }
}, },
"ok/no-pending-orders": func(t *testing.T) test {
oids := []string{"o1"}
boids, err := json.Marshal(oids)
assert.FatalError(t, err)
invalidOrder, err := newO()
assert.FatalError(t, err)
invalidOrder.Status = StatusInvalid
binvalidOrder, err := json.Marshal(invalidOrder)
assert.FatalError(t, err)
return test{
id: "foo",
db: &db.MockNoSQLDB{
MGet: func(bucket, key []byte) ([]byte, error) {
switch string(bucket) {
case string(ordersByAccountIDTable):
assert.Equals(t, key, []byte("foo"))
return boids, nil
case string(orderTable):
return binvalidOrder, nil
default:
assert.FatalError(t, errors.Errorf("did not expect query to table %s", bucket))
return nil, nil
}
},
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
assert.Equals(t, bucket, ordersByAccountIDTable)
assert.Equals(t, key, []byte("foo"))
assert.Equals(t, old, boids)
assert.Nil(t, newval)
return nil, true, nil
},
},
res: []string{},
}
},
} }
for name, run := range tests { for name, run := range tests {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {

View file

@ -125,10 +125,17 @@ func newOrder(db nosql.DB, ops OrderOptions) (*order, error) {
type orderIDs []string type orderIDs []string
// save is used to update the list of orderIDs keyed by ACME account ID
// stored in the database.
//
// This method always converts empty lists to 'nil' when storing to the DB. We
// do this to avoid any confusion between an empty list and a nil value in the
// db.
func (oids orderIDs) save(db nosql.DB, old orderIDs, accID string) error { func (oids orderIDs) save(db nosql.DB, old orderIDs, accID string) error {
var ( var (
err error err error
oldb []byte oldb []byte
newb []byte
) )
if len(old) == 0 { if len(old) == 0 {
oldb = nil oldb = nil
@ -138,9 +145,13 @@ func (oids orderIDs) save(db nosql.DB, old orderIDs, accID string) error {
return ServerInternalErr(errors.Wrap(err, "error marshaling old order IDs slice")) return ServerInternalErr(errors.Wrap(err, "error marshaling old order IDs slice"))
} }
} }
newb, err := json.Marshal(oids) if len(oids) == 0 {
if err != nil { newb = nil
return ServerInternalErr(errors.Wrap(err, "error marshaling new order IDs slice")) } else {
newb, err = json.Marshal(oids)
if err != nil {
return ServerInternalErr(errors.Wrap(err, "error marshaling new order IDs slice"))
}
} }
_, swapped, err := db.CmpAndSwap(ordersByAccountIDTable, []byte(accID), oldb, newb) _, swapped, err := db.CmpAndSwap(ordersByAccountIDTable, []byte(accID), oldb, newb)
switch { switch {

View file

@ -516,7 +516,7 @@ func Test_newOrder(t *testing.T) {
} }
} }
func TestOrderIDsSave(t *testing.T) { func TestOrderIDs_save(t *testing.T) {
accID := "acc-id" accID := "acc-id"
newOids := func() orderIDs { newOids := func() orderIDs {
return []string{"1", "2"} return []string{"1", "2"}
@ -591,6 +591,26 @@ func TestOrderIDsSave(t *testing.T) {
}, },
} }
}, },
"ok/new-empty-saved-as-nil": func(t *testing.T) test {
oldOids := newOids()
oids := []string{}
oldb, err := json.Marshal(oldOids)
assert.FatalError(t, err)
return test{
oids: oids,
old: oldOids,
db: &db.MockNoSQLDB{
MCmpAndSwap: func(bucket, key, old, newval []byte) ([]byte, bool, error) {
assert.Equals(t, old, oldb)
assert.Equals(t, newval, nil)
assert.Equals(t, bucket, ordersByAccountIDTable)
assert.Equals(t, key, []byte(accID))
return nil, true, nil
},
},
}
},
} }
for name, run := range tests { for name, run := range tests {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {