From f5b84c24523af2093bedc353c844f98ff94c6157 Mon Sep 17 00:00:00 2001 From: michaeldiamant Date: Wed, 26 Oct 2022 13:22:27 -0400 Subject: [PATCH 1/2] Fix handling of empty local state in TestResourcesDataApp --- ledger/accountdb_test.go | 406 ++++++++++++++++++++------------------- 1 file changed, 211 insertions(+), 195 deletions(-) diff --git a/ledger/accountdb_test.go b/ledger/accountdb_test.go index 5491cb21d4..172a82f6d1 100644 --- a/ledger/accountdb_test.go +++ b/ledger/accountdb_test.go @@ -1282,205 +1282,221 @@ func TestCompactResourceDeltas(t *testing.T) { func TestResourcesDataApp(t *testing.T) { partitiontest.PartitionTest(t) + t.Parallel() a := require.New(t) - rd := resourcesData{} - a.False(rd.IsApp()) - a.True(rd.IsEmpty()) - - rd = makeResourcesData(1) - a.False(rd.IsApp()) - a.False(rd.IsHolding()) - a.False(rd.IsOwning()) - a.True(rd.IsEmpty()) - - // check empty - appParamsEmpty := basics.AppParams{} - rd = resourcesData{} - rd.SetAppParams(appParamsEmpty, false) - a.True(rd.IsApp()) - a.True(rd.IsOwning()) - a.True(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - a.Equal(appParamsEmpty, rd.GetAppParams()) - - appLocalEmpty := basics.AppLocalState{} - rd = resourcesData{} - rd.SetAppLocalState(appLocalEmpty) - a.True(rd.IsApp()) - a.True(rd.IsHolding()) - a.True(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - a.Equal(appLocalEmpty, rd.GetAppLocalState()) - - // check both empty - rd = resourcesData{} - rd.SetAppLocalState(appLocalEmpty) - rd.SetAppParams(appParamsEmpty, true) - a.True(rd.IsApp()) - a.True(rd.IsOwning()) - a.True(rd.IsHolding()) - a.True(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - a.Equal(appParamsEmpty, rd.GetAppParams()) - a.Equal(appLocalEmpty, rd.GetAppLocalState()) - - // check empty states + non-empty params - appParams := ledgertesting.RandomAppParams() - rd = resourcesData{} - rd.SetAppLocalState(appLocalEmpty) - rd.SetAppParams(appParams, true) - a.True(rd.IsApp()) - a.True(rd.IsOwning()) - a.True(rd.IsHolding()) - a.False(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - a.Equal(appParams, rd.GetAppParams()) - a.Equal(appLocalEmpty, rd.GetAppLocalState()) - - appState := ledgertesting.RandomAppLocalState() - rd.SetAppLocalState(appState) - a.True(rd.IsApp()) - a.True(rd.IsOwning()) - a.True(rd.IsHolding()) - a.False(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - a.Equal(appParams, rd.GetAppParams()) - a.Equal(appState, rd.GetAppLocalState()) - - // check ClearAppLocalState - rd.ClearAppLocalState() - a.True(rd.IsApp()) - a.True(rd.IsOwning()) - a.False(rd.IsHolding()) - a.False(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - a.Equal(appParams, rd.GetAppParams()) - a.Equal(appLocalEmpty, rd.GetAppLocalState()) - - // check ClearAppParams - rd.SetAppLocalState(appState) - rd.ClearAppParams() - a.True(rd.IsApp()) - a.False(rd.IsOwning()) - a.True(rd.IsHolding()) - a.False(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - a.Equal(appParamsEmpty, rd.GetAppParams()) - a.Equal(appState, rd.GetAppLocalState()) - - // check both clear - rd.ClearAppLocalState() - a.False(rd.IsApp()) - a.False(rd.IsOwning()) - a.False(rd.IsHolding()) - a.True(rd.IsEmptyAppFields()) - a.True(rd.IsEmpty()) - a.Equal(appParamsEmpty, rd.GetAppParams()) - a.Equal(appLocalEmpty, rd.GetAppLocalState()) - - // check params clear when non-empty params and empty holding - rd = resourcesData{} - rd.SetAppLocalState(appLocalEmpty) - rd.SetAppParams(appParams, true) - rd.ClearAppParams() - a.True(rd.IsApp()) - a.False(rd.IsOwning()) - a.True(rd.IsHolding()) - a.True(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - a.Equal(appParamsEmpty, rd.GetAppParams()) - a.Equal(appLocalEmpty, rd.GetAppLocalState()) - - rd = resourcesData{} - rd.SetAppLocalState(appLocalEmpty) - a.True(rd.IsEmptyAppFields()) - a.True(rd.IsApp()) - a.False(rd.IsEmpty()) - a.Equal(rd.ResourceFlags, resourceFlagsEmptyApp) - rd.ClearAppLocalState() - a.False(rd.IsApp()) - a.True(rd.IsEmptyAppFields()) - a.True(rd.IsEmpty()) - a.Equal(rd.ResourceFlags, resourceFlagsNotHolding) - - // check migration flow (accountDataResources) - // 1. both exist and empty - rd = makeResourcesData(0) - rd.SetAppLocalState(appLocalEmpty) - rd.SetAppParams(appParamsEmpty, true) - a.True(rd.IsApp()) - a.True(rd.IsOwning()) - a.True(rd.IsHolding()) - a.True(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - - // 2. both exist and not empty - rd = makeResourcesData(0) - rd.SetAppLocalState(appState) - rd.SetAppParams(appParams, true) - a.True(rd.IsApp()) - a.True(rd.IsOwning()) - a.True(rd.IsHolding()) - a.False(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - - // 3. both exist: holding not empty, param is empty - rd = makeResourcesData(0) - rd.SetAppLocalState(appState) - rd.SetAppParams(appParamsEmpty, true) - a.True(rd.IsApp()) - a.True(rd.IsOwning()) - a.True(rd.IsHolding()) - a.False(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - - // 4. both exist: holding empty, param is not empty - rd = makeResourcesData(0) - rd.SetAppLocalState(appLocalEmpty) - rd.SetAppParams(appParams, true) - a.True(rd.IsApp()) - a.True(rd.IsOwning()) - a.True(rd.IsHolding()) - a.False(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - - // 5. holding does not exist and params is empty - rd = makeResourcesData(0) - rd.SetAppParams(appParamsEmpty, false) - a.True(rd.IsApp()) - a.True(rd.IsOwning()) - a.False(rd.IsHolding()) - a.True(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - - // 6. holding does not exist and params is not empty - rd = makeResourcesData(0) - rd.SetAppParams(appParams, false) - a.True(rd.IsApp()) - a.True(rd.IsOwning()) - a.False(rd.IsHolding()) - a.False(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - - // 7. holding exist and not empty and params does not exist - rd = makeResourcesData(0) - rd.SetAppLocalState(appState) - a.True(rd.IsApp()) - a.False(rd.IsOwning()) - a.True(rd.IsHolding()) - a.False(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - - // 8. both do not exist - rd = makeResourcesData(0) - a.False(rd.IsApp()) - a.False(rd.IsOwning()) - a.False(rd.IsHolding()) - a.True(rd.IsEmptyAppFields()) - a.True(rd.IsEmpty()) + // Since some steps use randomly generated input, the test is run N times + // to cover a larger search space of inputs. + for i := 0; i < 1000; i++ { + rd := resourcesData{} + a.False(rd.IsApp()) + a.True(rd.IsEmpty()) + + rd = makeResourcesData(1) + a.False(rd.IsApp()) + a.False(rd.IsHolding()) + a.False(rd.IsOwning()) + a.True(rd.IsEmpty()) + + // check empty + appParamsEmpty := basics.AppParams{} + rd = resourcesData{} + rd.SetAppParams(appParamsEmpty, false) + a.True(rd.IsApp()) + a.True(rd.IsOwning()) + a.True(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + a.Equal(appParamsEmpty, rd.GetAppParams()) + + appLocalEmpty := basics.AppLocalState{} + rd = resourcesData{} + rd.SetAppLocalState(appLocalEmpty) + a.True(rd.IsApp()) + a.True(rd.IsHolding()) + a.True(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + a.Equal(appLocalEmpty, rd.GetAppLocalState()) + + // check both empty + rd = resourcesData{} + rd.SetAppLocalState(appLocalEmpty) + rd.SetAppParams(appParamsEmpty, true) + a.True(rd.IsApp()) + a.True(rd.IsOwning()) + a.True(rd.IsHolding()) + a.True(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + a.Equal(appParamsEmpty, rd.GetAppParams()) + a.Equal(appLocalEmpty, rd.GetAppLocalState()) + + // check empty states + non-empty params + appParams := ledgertesting.RandomAppParams() + rd = resourcesData{} + rd.SetAppLocalState(appLocalEmpty) + rd.SetAppParams(appParams, true) + a.True(rd.IsApp()) + a.True(rd.IsOwning()) + a.True(rd.IsHolding()) + a.False(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + a.Equal(appParams, rd.GetAppParams()) + a.Equal(appLocalEmpty, rd.GetAppLocalState()) + + appState := ledgertesting.RandomAppLocalState() + rd.SetAppLocalState(appState) + a.True(rd.IsApp()) + a.True(rd.IsOwning()) + a.True(rd.IsHolding()) + a.False(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + a.Equal(appParams, rd.GetAppParams()) + a.Equal(appState, rd.GetAppLocalState()) + + // check ClearAppLocalState + rd.ClearAppLocalState() + a.True(rd.IsApp()) + a.True(rd.IsOwning()) + a.False(rd.IsHolding()) + a.False(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + a.Equal(appParams, rd.GetAppParams()) + a.Equal(appLocalEmpty, rd.GetAppLocalState()) + + // check ClearAppParams + rd.SetAppLocalState(appState) + rd.ClearAppParams() + a.True(rd.IsApp()) + a.False(rd.IsOwning()) + a.True(rd.IsHolding()) + if appState.Schema.NumEntries() == 0 { + a.True(rd.IsEmptyAppFields()) + } else { + a.False(rd.IsEmptyAppFields()) + } + a.False(rd.IsEmpty()) + a.Equal(appParamsEmpty, rd.GetAppParams()) + a.Equal(appState, rd.GetAppLocalState()) + + // check both clear + rd.ClearAppLocalState() + a.False(rd.IsApp()) + a.False(rd.IsOwning()) + a.False(rd.IsHolding()) + a.True(rd.IsEmptyAppFields()) + a.True(rd.IsEmpty()) + a.Equal(appParamsEmpty, rd.GetAppParams()) + a.Equal(appLocalEmpty, rd.GetAppLocalState()) + + // check params clear when non-empty params and empty holding + rd = resourcesData{} + rd.SetAppLocalState(appLocalEmpty) + rd.SetAppParams(appParams, true) + rd.ClearAppParams() + a.True(rd.IsApp()) + a.False(rd.IsOwning()) + a.True(rd.IsHolding()) + a.True(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + a.Equal(appParamsEmpty, rd.GetAppParams()) + a.Equal(appLocalEmpty, rd.GetAppLocalState()) + + rd = resourcesData{} + rd.SetAppLocalState(appLocalEmpty) + a.True(rd.IsEmptyAppFields()) + a.True(rd.IsApp()) + a.False(rd.IsEmpty()) + a.Equal(rd.ResourceFlags, resourceFlagsEmptyApp) + rd.ClearAppLocalState() + a.False(rd.IsApp()) + a.True(rd.IsEmptyAppFields()) + a.True(rd.IsEmpty()) + a.Equal(rd.ResourceFlags, resourceFlagsNotHolding) + + // check migration flow (accountDataResources) + // 1. both exist and empty + rd = makeResourcesData(0) + rd.SetAppLocalState(appLocalEmpty) + rd.SetAppParams(appParamsEmpty, true) + a.True(rd.IsApp()) + a.True(rd.IsOwning()) + a.True(rd.IsHolding()) + a.True(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + + // 2. both exist and not empty + rd = makeResourcesData(0) + rd.SetAppLocalState(appState) + rd.SetAppParams(appParams, true) + a.True(rd.IsApp()) + a.True(rd.IsOwning()) + a.True(rd.IsHolding()) + a.False(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + + // 3. both exist: holding not empty, param is empty + rd = makeResourcesData(0) + rd.SetAppLocalState(appState) + rd.SetAppParams(appParamsEmpty, true) + a.True(rd.IsApp()) + a.True(rd.IsOwning()) + a.True(rd.IsHolding()) + if appState.Schema.NumEntries() == 0 { + a.True(rd.IsEmptyAppFields()) + } else { + a.False(rd.IsEmptyAppFields()) + } + a.False(rd.IsEmpty()) + + // 4. both exist: holding empty, param is not empty + rd = makeResourcesData(0) + rd.SetAppLocalState(appLocalEmpty) + rd.SetAppParams(appParams, true) + a.True(rd.IsApp()) + a.True(rd.IsOwning()) + a.True(rd.IsHolding()) + a.False(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + + // 5. holding does not exist and params is empty + rd = makeResourcesData(0) + rd.SetAppParams(appParamsEmpty, false) + a.True(rd.IsApp()) + a.True(rd.IsOwning()) + a.False(rd.IsHolding()) + a.True(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + + // 6. holding does not exist and params is not empty + rd = makeResourcesData(0) + rd.SetAppParams(appParams, false) + a.True(rd.IsApp()) + a.True(rd.IsOwning()) + a.False(rd.IsHolding()) + a.False(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + + // 7. holding exist and not empty and params does not exist + rd = makeResourcesData(0) + rd.SetAppLocalState(appState) + a.True(rd.IsApp()) + a.False(rd.IsOwning()) + a.True(rd.IsHolding()) + if appState.Schema.NumEntries() == 0 { + a.True(rd.IsEmptyAppFields()) + } else { + a.False(rd.IsEmptyAppFields()) + } + a.False(rd.IsEmpty()) + // 8. both do not exist + rd = makeResourcesData(0) + a.False(rd.IsApp()) + a.False(rd.IsOwning()) + a.False(rd.IsHolding()) + a.True(rd.IsEmptyAppFields()) + a.True(rd.IsEmpty()) + } } func TestResourcesDataAsset(t *testing.T) { From 18f34b5f7d9886329033440f978497d988b9928a Mon Sep 17 00:00:00 2001 From: michaeldiamant Date: Wed, 26 Oct 2022 14:24:20 -0400 Subject: [PATCH 2/2] Move for loop per PR feedback --- ledger/accountdb_test.go | 78 ++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/ledger/accountdb_test.go b/ledger/accountdb_test.go index 172a82f6d1..73a95ab200 100644 --- a/ledger/accountdb_test.go +++ b/ledger/accountdb_test.go @@ -1286,50 +1286,50 @@ func TestResourcesDataApp(t *testing.T) { a := require.New(t) - // Since some steps use randomly generated input, the test is run N times - // to cover a larger search space of inputs. - for i := 0; i < 1000; i++ { - rd := resourcesData{} - a.False(rd.IsApp()) - a.True(rd.IsEmpty()) + rd := resourcesData{} + a.False(rd.IsApp()) + a.True(rd.IsEmpty()) - rd = makeResourcesData(1) - a.False(rd.IsApp()) - a.False(rd.IsHolding()) - a.False(rd.IsOwning()) - a.True(rd.IsEmpty()) + rd = makeResourcesData(1) + a.False(rd.IsApp()) + a.False(rd.IsHolding()) + a.False(rd.IsOwning()) + a.True(rd.IsEmpty()) - // check empty - appParamsEmpty := basics.AppParams{} - rd = resourcesData{} - rd.SetAppParams(appParamsEmpty, false) - a.True(rd.IsApp()) - a.True(rd.IsOwning()) - a.True(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - a.Equal(appParamsEmpty, rd.GetAppParams()) + // check empty + appParamsEmpty := basics.AppParams{} + rd = resourcesData{} + rd.SetAppParams(appParamsEmpty, false) + a.True(rd.IsApp()) + a.True(rd.IsOwning()) + a.True(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + a.Equal(appParamsEmpty, rd.GetAppParams()) - appLocalEmpty := basics.AppLocalState{} - rd = resourcesData{} - rd.SetAppLocalState(appLocalEmpty) - a.True(rd.IsApp()) - a.True(rd.IsHolding()) - a.True(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - a.Equal(appLocalEmpty, rd.GetAppLocalState()) + appLocalEmpty := basics.AppLocalState{} + rd = resourcesData{} + rd.SetAppLocalState(appLocalEmpty) + a.True(rd.IsApp()) + a.True(rd.IsHolding()) + a.True(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + a.Equal(appLocalEmpty, rd.GetAppLocalState()) - // check both empty - rd = resourcesData{} - rd.SetAppLocalState(appLocalEmpty) - rd.SetAppParams(appParamsEmpty, true) - a.True(rd.IsApp()) - a.True(rd.IsOwning()) - a.True(rd.IsHolding()) - a.True(rd.IsEmptyAppFields()) - a.False(rd.IsEmpty()) - a.Equal(appParamsEmpty, rd.GetAppParams()) - a.Equal(appLocalEmpty, rd.GetAppLocalState()) + // check both empty + rd = resourcesData{} + rd.SetAppLocalState(appLocalEmpty) + rd.SetAppParams(appParamsEmpty, true) + a.True(rd.IsApp()) + a.True(rd.IsOwning()) + a.True(rd.IsHolding()) + a.True(rd.IsEmptyAppFields()) + a.False(rd.IsEmpty()) + a.Equal(appParamsEmpty, rd.GetAppParams()) + a.Equal(appLocalEmpty, rd.GetAppLocalState()) + // Since some steps use randomly generated input, the test is run N times + // to cover a larger search space of inputs. + for i := 0; i < 1000; i++ { // check empty states + non-empty params appParams := ledgertesting.RandomAppParams() rd = resourcesData{}