Created
May 10, 2020 13:30
-
-
Save eyJhb/f0e913588803d3190e624682220eecf7 to your computer and use it in GitHub Desktop.
inequality
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package memory | |
import ( | |
"reflect" | |
"testing" | |
"gitlab.com/deviosec/octp/server/pkgs/store/models" | |
"golang.org/x/exp/errors/fmt" | |
) | |
func DeepInequal(a, b reflect.Value) []string { | |
fmt.Println("Called!") | |
var errors []string | |
if a.Type() != b.Type() || a.Kind() != b.Kind() { | |
errors = append(errors, "Types or kind do not match") | |
return errors | |
} | |
switch k := a.Kind(); { | |
case k == reflect.Struct: | |
for i := 0; i < a.NumField(); i++ { | |
errors = append(errors, DeepInequal(a.Field(i), b.Field(i))...) | |
} | |
case k == reflect.Slice: | |
if a.IsNil() == true || b.IsNil() == true { | |
errors = append(errors, "A slice is nil, cannot be") | |
return errors | |
} | |
if a.Len() != b.Len() || a.Cap() != b.Cap() { | |
errors = append(errors, "Slices not same length/cap") | |
return errors | |
} | |
for i := 0; i < a.Cap(); i++ { | |
errors = append(errors, DeepInequal(a.Index(i), b.Index(i))...) | |
} | |
case k == reflect.Map: | |
if a.IsNil() == true || b.IsNil() == true { | |
errors = append(errors, "A map is nil, cannot be") | |
return errors | |
} | |
if a.Len() != b.Len() { | |
errors = append(errors, "Maps not same length/cap") | |
return errors | |
} | |
for _, k := range a.MapKeys() { | |
errors = append(errors, DeepInequal(a.MapIndex(k), b.MapIndex(k))...) | |
} | |
case k >= reflect.Array && k <= reflect.Interface: | |
panic("Not imlemented for reflect.Array > k < reflect.Interface") | |
case (k >= reflect.Bool && k <= reflect.Complex128) || k == reflect.String: | |
fmt.Println(a.String(), b.String()) | |
if a == b { | |
fmt.Println("Same") | |
errors = append(errors, fmt.Sprintf("Values of type %s match, '%v' and '%v'", a.Type(), a.String(), b.String())) | |
} | |
default: | |
panic("No clue what to do with this") | |
fmt.Println("No clue what to do with:", k) | |
} | |
return errors | |
} | |
func Fuzz2(v reflect.Value) reflect.Value { | |
if v.Kind() == reflect.Ptr { | |
v = v.Elem() | |
} | |
switch k := v.Kind(); { | |
case k == reflect.Struct: | |
newStruct := reflect.New(v.Type()).Elem() | |
for i := 0; i < v.NumField(); i++ { | |
fieldOriginal := v.Field(i) | |
fieldNew := newStruct.Field(i) | |
fieldNew.Set(Fuzz2(fieldOriginal)) | |
} | |
v = newStruct | |
case k == reflect.Slice: | |
for i := 0; i < v.Cap(); i++ { | |
Fuzz2(v.Index(i)) | |
} | |
case k == reflect.Map: | |
iter := v.MapRange() | |
for iter.Next() { | |
v.SetMapIndex(iter.Key(), Fuzz2(iter.Value())) | |
} | |
case k >= reflect.Array && k <= reflect.Interface: | |
panic("Not imlemented for reflect.Array > k < reflect.Interface") | |
case (k >= reflect.Bool && k <= reflect.Complex128) || k == reflect.String: | |
// this will only be the case for maps... | |
if !v.CanSet() { | |
vt := reflect.New(v.Type()).Elem() | |
vt.Set(v) | |
v = vt | |
} | |
if found, fieldValue := changeValue(v); found { | |
v.Set(fieldValue) | |
} else { | |
fmt.Println("Could not find vaule for", v.Kind()) | |
} | |
default: | |
panic("No clue what to do with this") | |
fmt.Println("No clue what to do with:", k) | |
} | |
return v | |
} | |
func changeValue(v reflect.Value) (bool, reflect.Value) { | |
kind := v.Kind() | |
switch kind { | |
case reflect.Bool: | |
return true, reflect.ValueOf(!v.Interface().(bool)) | |
case reflect.Int: | |
return true, reflect.ValueOf(v.Interface().(int) + 1) | |
case reflect.Int8: | |
return true, reflect.ValueOf(v.Interface().(int8) + 1) | |
case reflect.Int16: | |
return true, reflect.ValueOf(v.Interface().(int16) + 1) | |
case reflect.Int32: | |
return true, reflect.ValueOf(v.Interface().(int32) + 1) | |
case reflect.Int64: | |
return true, reflect.ValueOf(v.Interface().(int64) + 1) | |
case reflect.Uint: | |
return true, reflect.ValueOf(v.Interface().(uint) + 1) | |
case reflect.Uint8: | |
return true, reflect.ValueOf(v.Interface().(uint8) + 1) | |
case reflect.Uint16: | |
return true, reflect.ValueOf(v.Interface().(uint16) + 1) | |
case reflect.Uint32: | |
return true, reflect.ValueOf(v.Interface().(uint32) + 1) | |
case reflect.Uint64: | |
return true, reflect.ValueOf(v.Interface().(int64) + 1) | |
case reflect.Float32: | |
return true, reflect.ValueOf(v.Interface().(float32) + 1) | |
case reflect.Float64: | |
return true, reflect.ValueOf(v.Interface().(float64) + 1) | |
case reflect.Complex64: | |
return true, reflect.ValueOf(v.Interface().(complex64) + 1) | |
case reflect.Complex128: | |
return true, reflect.ValueOf(v.Interface().(complex128) + 1) | |
case reflect.String: | |
return true, reflect.ValueOf(v.Interface().(string) + "a") | |
} | |
return false, reflect.Value{} | |
} | |
func TestFuzz(t *testing.T) { | |
// struct we can use to test | |
type smallStruct struct { | |
FieldSimple string | |
FieldSlice []string | |
FieldMap map[string]string | |
} | |
copySmallStruct := func(c smallStruct) smallStruct { | |
cc := c | |
cc.FieldSlice = make([]string, len(c.FieldSlice)) | |
copy(cc.FieldSlice, c.FieldSlice) | |
cc.FieldMap = make(map[string]string) | |
for k, v := range c.FieldMap { | |
cc.FieldMap[k] = v | |
} | |
return cc | |
} | |
type bigStruct struct { | |
FieldString string | |
FieldBool bool | |
FieldInt int | |
FieldSliceString []string | |
FieldSliceStruct []smallStruct | |
FieldMapString map[string]string | |
FieldMapStruct map[string]smallStruct | |
} | |
copyBigStruct := func(c bigStruct) bigStruct { | |
cc := c | |
cc.FieldSliceString = make([]string, len(c.FieldSliceString)) | |
copy(cc.FieldSliceString, c.FieldSliceString) | |
cc.FieldSliceStruct = []smallStruct{} | |
for _, v := range c.FieldSliceStruct { | |
cc.FieldSliceStruct = append(cc.FieldSliceStruct, copySmallStruct(v)) | |
} | |
cc.FieldMapString = make(map[string]string) | |
for k, v := range c.FieldMapString { | |
cc.FieldMapString[k] = v | |
} | |
cc.FieldMapStruct = make(map[string]smallStruct) | |
for k, v := range c.FieldMapStruct { | |
cc.FieldMapStruct[k] = copySmallStruct(v) | |
} | |
return cc | |
} | |
_ = copyBigStruct | |
// declare the struct | |
ts := bigStruct{ | |
FieldString: "", | |
FieldBool: false, | |
FieldInt: 10, | |
FieldSliceString: []string{"element1"}, | |
FieldSliceStruct: []smallStruct{ | |
smallStruct{ | |
FieldSimple: "", | |
FieldSlice: []string{"element1"}, | |
FieldMap: map[string]string{ | |
"key1": "value1", | |
}, | |
}, | |
}, | |
FieldMapString: map[string]string{ | |
"key1": "value1", | |
}, | |
FieldMapStruct: map[string]smallStruct{ | |
"key1": { | |
FieldSimple: "", | |
FieldSlice: []string{"element1"}, | |
FieldMap: map[string]string{ | |
"key1": "value1", | |
}, | |
}, | |
}, | |
} | |
// copy it | |
// tsc := copyBigStruct(ts) | |
tsc := ts | |
// fuzz it | |
fmt.Println(ts) | |
Fuzz2(reflect.ValueOf(&tsc)) | |
fmt.Println(ts) | |
fmt.Println(tsc) | |
} | |
func TestCopy(t *testing.T) { | |
c1 := models.Container{ | |
Id: 120, | |
Image: "image", | |
Sha256: "sha256", | |
Envs: []string{"someenv"}, | |
Ports: map[string]models.Port{ | |
"PORTA": { | |
HostIP: "127.0.0.1", | |
Host: 8080, | |
Guest: 8008, | |
Protocol: "TCP", | |
}, | |
}, | |
Privileged: false, | |
Action: "NONE", | |
} | |
// test := 1 | |
// changeInput(test) | |
// changeInput(c) | |
// c2 := copyContainer(c1) | |
c2 := c1 | |
fmt.Println(c1) | |
Fuzz2(reflect.ValueOf(&c2)) | |
fmt.Println(c1) | |
fmt.Println(c2) | |
fmt.Println(DeepInequal(reflect.ValueOf(c1), reflect.ValueOf(c2))) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment