@@ -3,11 +3,17 @@ package balances
3
3
import (
4
4
"bufio"
5
5
"context"
6
+ "crypto/md5"
7
+ "fmt"
8
+ "io"
9
+ "os"
10
+ "path/filepath"
6
11
"testing"
7
12
8
13
"github.com/gnolang/contribs/gnogenesis/internal/common"
9
14
"github.com/gnolang/gno/gno.land/pkg/gnoland"
10
15
"github.com/gnolang/gno/gno.land/pkg/gnoland/ugnot"
16
+ bft "github.com/gnolang/gno/tm2/pkg/bft/types"
11
17
"github.com/gnolang/gno/tm2/pkg/commands"
12
18
"github.com/gnolang/gno/tm2/pkg/std"
13
19
"github.com/gnolang/gno/tm2/pkg/testutils"
@@ -105,35 +111,45 @@ func TestGenesis_Balances_Export(t *testing.T) {
105
111
t .Parallel ()
106
112
107
113
// Generate dummy balances
108
- balances := getDummyBalances (t , 10 )
114
+ balances := getDummyBalances (t , 100 )
109
115
110
116
tempGenesis , cleanup := testutils .NewTestFile (t )
111
117
t .Cleanup (cleanup )
112
118
113
- genesis := common .GetDefaultGenesis ()
114
- genesis .AppState = gnoland.GnoGenesisState {
115
- Balances : balances ,
116
- }
117
- require .NoError (t , genesis .SaveAs (tempGenesis .Name ()))
118
-
119
119
// Prepare the output file
120
120
outputFile , outputCleanup := testutils .NewTestFile (t )
121
121
t .Cleanup (outputCleanup )
122
122
123
- // Create the command
124
- cmd := NewBalancesCmd (commands .NewTestIO ())
125
- args := []string {
126
- "export" ,
127
- "--genesis-path" ,
128
- tempGenesis .Name (),
129
- outputFile .Name (),
123
+ saveGenesisFile := func (outputPath string ) {
124
+ genesis := common .GetDefaultGenesis ()
125
+ genesis .AppState = gnoland.GnoGenesisState {
126
+ Balances : balances ,
127
+ }
128
+ require .NoError (t , genesis .SaveAs (tempGenesis .Name ()))
129
+
130
+ // Create the command
131
+ cmd := NewBalancesCmd (commands .NewTestIO ())
132
+ args := []string {
133
+ "export" ,
134
+ "--genesis-path" ,
135
+ tempGenesis .Name (),
136
+ outputPath ,
137
+ }
138
+
139
+ // Run the command
140
+ cmdErr := cmd .ParseAndRun (context .Background (), args )
141
+ require .NoError (t , cmdErr )
130
142
}
131
143
132
- // Run the command
133
- cmdErr := cmd .ParseAndRun (context .Background (), args )
134
- require .NoError (t , cmdErr )
144
+ saveGenesisFile (outputFile .Name ())
145
+ readIt := func (p string ) string {
146
+ blob , err := os .ReadFile (p )
147
+ require .NoError (t , err )
148
+ return string (blob )
149
+ }
135
150
136
151
// Validate the transactions were written down
152
+ outputFile .Seek (0 , 0 ) // Seek back to the front of the outputFile.
137
153
scanner := bufio .NewScanner (outputFile )
138
154
139
155
outputBalances := make ([]gnoland.Balance , 0 )
@@ -146,11 +162,46 @@ func TestGenesis_Balances_Export(t *testing.T) {
146
162
}
147
163
148
164
require .NoError (t , scanner .Err ())
149
-
150
165
assert .Len (t , outputBalances , len (balances ))
151
166
152
- for index , balance := range outputBalances {
153
- assert .Equal (t , balances [index ], balance )
167
+ // Next ensure that all balances are sorted by address, deterministically.
168
+ for i := 1 ; i < len (outputBalances ); i ++ {
169
+ curr := outputBalances [i ].Address
170
+ for j := 0 ; j < i ; j ++ {
171
+ prev := outputBalances [j ].Address
172
+ if addressIsGreater (prev , curr ) {
173
+ t .Fatalf ("Non-deterministic order of exported balances\n \t [%d](%s)\n >\n \t [%d](%s)" , j , prev , i , curr )
174
+ }
175
+ }
176
+ }
177
+
178
+ // Lastly compute the checksum and ensure that it is the same each of the N times.
179
+ outputFile .Close ()
180
+ firstGenesisPathMD5 := md5SumFromFile (t , outputFile .Name ())
181
+ firstGenesis := readIt (outputFile .Name ())
182
+ for i := 1 ; i <= 10 ; i ++ {
183
+ outpath := filepath .Join (t .TempDir (), "out" )
184
+ saveGenesisFile (outpath )
185
+ currentMD5 := md5SumFromFile (t , outpath )
186
+ currentGenesis := readIt (outpath )
187
+ require .Equal (t , firstGenesisPathMD5 , currentMD5 , "Iteration #%d has a different MD5 checksum\n %s\n \n %s" , i , firstGenesis , currentGenesis )
154
188
}
189
+
155
190
})
156
191
}
192
+
193
+ func md5SumFromFile (t * testing.T , p string ) string {
194
+ f , err := os .Open (p )
195
+ require .NoError (t , err )
196
+ fi , err := f .Stat ()
197
+ require .NoError (t , err )
198
+ require .True (t , fi .Size () > 100 , "at least 100 bytes expected" )
199
+ defer f .Close ()
200
+ h := md5 .New ()
201
+ io .Copy (h , f )
202
+ return fmt .Sprintf ("%x" , h .Sum (nil ))
203
+ }
204
+
205
+ func addressIsGreater (a , b bft.Address ) bool {
206
+ return a .Compare (b ) == 1
207
+ }
0 commit comments