Skip to content

Commit bb4fc64

Browse files
committed
adsfasdf
1 parent 0c672cf commit bb4fc64

File tree

9 files changed

+198
-80
lines changed

9 files changed

+198
-80
lines changed

mapper/info.go

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,11 @@ func (i *Info) SetField(column string, value interface{}) error {
7171
if colSchema == nil {
7272
return fmt.Errorf("SetField: column %s schema not found", column)
7373
}
74-
75-
// Validate set length requirements
76-
newVal := reflect.ValueOf(value)
77-
if colSchema.Type == ovsdb.TypeSet || colSchema.Type == ovsdb.TypeEnum {
78-
maxVal := colSchema.TypeObj.Max()
79-
minVal := colSchema.TypeObj.Min()
80-
if maxVal > 1 && newVal.Len() > maxVal {
81-
return fmt.Errorf("SetField: column %s overflow: %d new elements but max is %d", column, newVal.Len(), maxVal)
82-
} else if minVal > 0 && newVal.Len() < minVal {
83-
return fmt.Errorf("SetField: column %s underflow: %d new elements but min is %d", column, newVal.Len(), minVal)
84-
}
74+
if err := ovsdb.ValidateColumnConstraints(colSchema, value); err != nil {
75+
return fmt.Errorf("SetField: column %s failed validation: %v", column, err)
8576
}
8677

87-
fieldValue.Set(newVal)
78+
fieldValue.Set(reflect.ValueOf(value))
8879
return nil
8980
}
9081

mapper/mapper.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ func (m Mapper) NewRow(data *Info, fields ...interface{}) (ovsdb.Row, error) {
118118
if len(fields) == 0 && ovsdb.IsDefaultValue(column, nativeElem) {
119119
continue
120120
}
121+
if err := ovsdb.ValidateColumnConstraints(column, nativeElem); err != nil {
122+
return nil, fmt.Errorf("column %s assignment failed: %w", column, err)
123+
}
121124
ovsElem, err := ovsdb.NativeToOvs(column, nativeElem)
122125
if err != nil {
123126
return nil, fmt.Errorf("table %s, column %s: failed to generate ovs element. %s", data.Metadata.TableName, name, err.Error())

mapper/mapper_test.go

Lines changed: 46 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ var (
4040
42.0,
4141
}
4242

43+
aFloatSetTooBig = []float64{1.0, 2.0, 3.0, 4.0, 5.0, 6.0}
44+
4345
aMap = map[string]string{
4446
"key1": "value1",
4547
"key2": "value2",
@@ -115,7 +117,7 @@ var testSchema = []byte(`{
115117
"type": "real"
116118
},
117119
"min": 0,
118-
"max": 10
120+
"max": 5
119121
}
120122
},
121123
"aEmptySet": {
@@ -216,28 +218,49 @@ func TestMapperGetData(t *testing.T) {
216218
NonTagged: "something",
217219
}
218220

219-
ovsRow := getOvsTestRow(t)
220221
/* Code under test */
221222
var schema ovsdb.DatabaseSchema
222223
if err := json.Unmarshal(testSchema, &schema); err != nil {
223224
t.Error(err)
224225
}
225226

226-
mapper := NewMapper(schema)
227-
test := ormTestType{
228-
NonTagged: "something",
229-
}
230-
testInfo, err := NewInfo("TestTable", schema.Table("TestTable"), &test)
231-
assert.NoError(t, err)
232-
233-
err = mapper.GetRowData(&ovsRow, testInfo)
234-
assert.NoError(t, err)
235-
/*End code under test*/
227+
tests := []struct {
228+
name string
229+
setup func() ovsdb.Row
230+
expectErr bool
231+
}{{
232+
name: "basic",
233+
setup: func() ovsdb.Row {
234+
return getOvsTestRow(t)
235+
},
236+
}, {
237+
name: "too big array",
238+
setup: func() ovsdb.Row {
239+
testRow := getOvsTestRow(t)
240+
testRow["aFloatSet"] = test.MakeOvsSet(t, ovsdb.TypeReal, aFloatSetTooBig)
241+
return testRow
242+
},
243+
expectErr: true,
244+
}}
245+
for _, test := range tests {
246+
t.Run(fmt.Sprintf("GetData: %s", test.name), func(t *testing.T) {
247+
mapper := NewMapper(schema)
248+
tt := ormTestType{
249+
NonTagged: "something",
250+
}
251+
testInfo, err := NewInfo("TestTable", schema.Table("TestTable"), &tt)
252+
assert.NoError(t, err)
236253

237-
if err != nil {
238-
t.Error(err)
254+
ovsRow := test.setup()
255+
err = mapper.GetRowData(&ovsRow, testInfo)
256+
if test.expectErr {
257+
assert.Error(t, err)
258+
} else {
259+
assert.NoError(t, err)
260+
assert.Equal(t, expected, tt)
261+
}
262+
})
239263
}
240-
assert.Equal(t, expected, test)
241264
}
242265

243266
func TestMapperNewRow(t *testing.T) {
@@ -315,6 +338,14 @@ func TestMapperNewRow(t *testing.T) {
315338
MyFloatSet: aFloatSet,
316339
},
317340
expectedRow: ovsdb.Row(map[string]interface{}{"aFloatSet": test.MakeOvsSet(t, ovsdb.TypeReal, aFloatSet)}),
341+
}, {
342+
name: "aFloatSet too big",
343+
objInput: &struct {
344+
MyFloatSet []float64 `ovsdb:"aFloatSet"`
345+
}{
346+
MyFloatSet: aFloatSetTooBig,
347+
},
348+
shoulderr: true,
318349
}, {
319350
name: "Enum",
320351
objInput: &struct {

ovsdb/bindings.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,3 +399,21 @@ func isDefaultBaseValue(elem interface{}, etype ExtendedType) bool {
399399
return false
400400
}
401401
}
402+
403+
// ValidateColumnConstraints validates the native value against any constraints
404+
// of a given column.
405+
func ValidateColumnConstraints(column *ColumnSchema, nativeValue interface{}) error {
406+
switch column.Type {
407+
case TypeSet, TypeEnum:
408+
// Validate set length requirements
409+
newVal := reflect.ValueOf(nativeValue)
410+
maxVal := column.TypeObj.Max()
411+
minVal := column.TypeObj.Min()
412+
if maxVal > 1 && newVal.Len() > maxVal {
413+
return fmt.Errorf("slice would overflow (%d elements but %d allowed)", newVal.Len(), maxVal)
414+
} else if minVal > 0 && newVal.Len() < minVal {
415+
return fmt.Errorf("slice would underflow (%d elements but %d required)", newVal.Len(), minVal)
416+
}
417+
}
418+
return nil
419+
}

ovsdb/error.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ type ConstraintViolation struct {
117117
}
118118

119119
// Error implements the error interface
120-
func (e *ConstraintViolation) Error() string {
120+
func (e ConstraintViolation) Error() string {
121121
msg := constraintViolation
122122
if e.details != "" {
123123
msg += ": " + e.details

server/server_integration_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type bridgeType struct {
2929
ExternalIds map[string]string `ovsdb:"external_ids"`
3030
Ports []string `ovsdb:"ports"`
3131
Status map[string]string `ovsdb:"status"`
32+
FloodVLANs []int `ovsdb:"flood_vlans"`
3233
}
3334

3435
// ovsType is the simplified ORM model of the Bridge table

server/testdata/ovslite.json

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@
6969
"min": 0,
7070
"max": "unlimited"
7171
}
72+
},
73+
"flood_vlans": {
74+
"type": {
75+
"key": {
76+
"type": "integer",
77+
"minInteger": 0,
78+
"maxInteger": 4095
79+
},
80+
"min": 0,
81+
"max": 3
82+
}
7283
}
7384
},
7485
"indexes": [
@@ -78,4 +89,4 @@
7889
]
7990
}
8091
}
81-
}
92+
}

server/transact.go

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,10 @@ func (o *OvsdbServer) transact(name string, operations []ovsdb.Operation) ([]ovs
4848
r := transaction.Select(op.Table, op.Where, op.Columns)
4949
results = append(results, r)
5050
case ovsdb.OperationUpdate:
51-
r, tu := transaction.Update(name, op.Table, op.Where, op.Row)
51+
r, tu, err := transaction.Update(name, op.Table, op.Where, op.Row)
52+
if err != nil {
53+
panic(err)
54+
}
5255
results = append(results, r)
5356
if tu != nil {
5457
if err := updates.Merge(tu); err != nil {
@@ -241,68 +244,70 @@ func (t *Transaction) Select(table string, where []ovsdb.Condition, columns []st
241244
}
242245
}
243246

244-
func (t *Transaction) Update(database, table string, where []ovsdb.Condition, row ovsdb.Row) (ovsdb.OperationResult, ovsdb.TableUpdates2) {
247+
func opResultError(err error, table, detailFmt string, args ...interface{}) ovsdb.OperationResult {
248+
detail := fmt.Sprintf(detailFmt, args...)
249+
return ovsdb.OperationResult{
250+
Error: err.Error(),
251+
Details: fmt.Sprintf("table %q: %s", table, detail),
252+
}
253+
}
254+
255+
// Update updates the cache with the new row and returns the result of the operation
256+
// and the updates, or an error
257+
func (t *Transaction) Update(database, table string, where []ovsdb.Condition, row ovsdb.Row) (ovsdb.OperationResult, ovsdb.TableUpdates2, error) {
245258
dbModel := t.Model
246259
m := dbModel.Mapper
247260
schema := dbModel.Schema.Table(table)
248261
tableUpdate := make(ovsdb.TableUpdate2)
249262

250263
rows, err := t.rowsFromTransactionCacheAndDatabase(table, where)
251264
if err != nil {
252-
return ovsdb.OperationResult{
253-
Error: err.Error(),
254-
}, nil
265+
return opResultError(err, table, "failed to get rows from database"), nil, nil
255266
}
256267

257268
for uuid, old := range rows {
258269
oldInfo, _ := dbModel.NewModelInfo(old)
259270

260271
oldRow, err := m.NewRow(oldInfo)
261272
if err != nil {
262-
panic(err)
273+
return ovsdb.OperationResult{}, nil, err
263274
}
264275
new, err := dbModel.NewModel(table)
265276
if err != nil {
266-
panic(err)
277+
return ovsdb.OperationResult{}, nil, err
267278
}
268279
newInfo, err := dbModel.NewModelInfo(new)
269280
if err != nil {
270-
panic(err)
281+
return ovsdb.OperationResult{}, nil, err
271282
}
272283
err = m.GetRowData(&oldRow, newInfo)
273284
if err != nil {
274-
panic(err)
285+
return ovsdb.OperationResult{}, nil, err
275286
}
276287
err = newInfo.SetField("_uuid", uuid)
277288
if err != nil {
278-
panic(err)
289+
return ovsdb.OperationResult{}, nil, err
279290
}
280291

281292
rowDelta := ovsdb.NewRow()
282293
for column, value := range row {
283294
colSchema := schema.Column(column)
284295
if colSchema == nil {
285296
e := ovsdb.ConstraintViolation{}
286-
return ovsdb.OperationResult{
287-
Error: e.Error(),
288-
Details: fmt.Sprintf("%s is not a valid column in the %s table", column, table),
289-
}, nil
297+
return opResultError(e, table, "%q is not a valid column", column), nil, nil
290298
}
291299
if !colSchema.Mutable() {
292300
e := ovsdb.ConstraintViolation{}
293-
return ovsdb.OperationResult{
294-
Error: e.Error(),
295-
Details: fmt.Sprintf("column %s is of table %s not mutable", column, table),
296-
}, nil
301+
return opResultError(e, table, "column %q is not mutable", column), nil, nil
297302
}
298303
old, err := newInfo.FieldByColumn(column)
299304
if err != nil {
300-
panic(err)
305+
return ovsdb.OperationResult{}, nil, err
301306
}
302307

303308
native, err := ovsdb.OvsToNative(colSchema, value)
304309
if err != nil {
305-
panic(err)
310+
return ovsdb.OperationResult{}, nil, err
306311
}
307312

308313
if reflect.DeepEqual(old, native) {
@@ -316,17 +321,17 @@ func (t *Transaction) Update(database, table string, where []ovsdb.Condition, ro
316321

317322
err = newInfo.SetField(column, native)
318323
if err != nil {
319-
panic(err)
324+
return ovsdb.OperationResult{}, nil, err
320325
}
321326
// convert the native to an ovs value
322327
// since the value in the RowUpdate hasn't been normalized
323328
newValue, err := ovsdb.NativeToOvs(colSchema, native)
324329
if err != nil {
325-
panic(err)
330+
return ovsdb.OperationResult{}, nil, err
326331
}
327332
diff, err := diff(colSchema, oldValue, newValue)
328333
if err != nil {
329-
panic(err)
334+
return ovsdb.OperationResult{}, nil, err
330335
}
331336
if diff != nil {
332337
rowDelta[column] = diff
@@ -335,7 +340,7 @@ func (t *Transaction) Update(database, table string, where []ovsdb.Condition, ro
335340

336341
newRow, err := m.NewRow(newInfo)
337342
if err != nil {
338-
panic(err)
343+
return ovsdb.OperationResult{}, nil, err
339344
}
340345

341346
// check for index conflicts
@@ -345,11 +350,11 @@ func (t *Transaction) Update(database, table string, where []ovsdb.Condition, ro
345350
return ovsdb.OperationResult{
346351
Error: e.Error(),
347352
Details: newIndexExistsDetails(*indexExists),
348-
}, nil
353+
}, nil, nil
349354
}
350355
return ovsdb.OperationResult{
351356
Error: err.Error(),
352-
}, nil
357+
}, nil, nil
353358
}
354359

355360
err = tableUpdate.AddRowUpdate(uuid, &ovsdb.RowUpdate2{
@@ -358,15 +363,15 @@ func (t *Transaction) Update(database, table string, where []ovsdb.Condition, ro
358363
New: &newRow,
359364
})
360365
if err != nil {
361-
panic(err)
366+
return ovsdb.OperationResult{}, nil, err
362367
}
363368
}
364369
// FIXME: We need to filter the returned columns
365370
return ovsdb.OperationResult{
366371
Count: len(rows),
367372
}, ovsdb.TableUpdates2{
368373
table: tableUpdate,
369-
}
374+
}, nil
370375
}
371376

372377
func (t *Transaction) Mutate(database, table string, where []ovsdb.Condition, mutations []ovsdb.Mutation) (ovsdb.OperationResult, ovsdb.TableUpdates2) {

0 commit comments

Comments
 (0)