Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ignite
GitHub Repository: ignite/cli
Path: blob/main/integration/tx/tx_test.go
1007 views
1
//go:build !relayer
2
3
package tx_test
4
5
import (
6
"bytes"
7
"context"
8
"encoding/json"
9
"fmt"
10
"net/http"
11
"testing"
12
"time"
13
14
"github.com/stretchr/testify/require"
15
16
"github.com/ignite/cli/v29/ignite/pkg/cmdrunner"
17
"github.com/ignite/cli/v29/ignite/pkg/cmdrunner/step"
18
"github.com/ignite/cli/v29/ignite/pkg/errors"
19
"github.com/ignite/cli/v29/ignite/pkg/randstr"
20
"github.com/ignite/cli/v29/ignite/pkg/xurl"
21
envtest "github.com/ignite/cli/v29/integration"
22
)
23
24
func TestSignTxWithDashedAppName(t *testing.T) {
25
var (
26
env = envtest.New(t)
27
appname = "da-shed-a-p-p"
28
app = env.ScaffoldApp(appname)
29
servers = app.RandomizeServerPorts()
30
ctx, cancel = context.WithCancel(env.Ctx())
31
)
32
33
nodeAddr, err := xurl.TCP(servers.RPC)
34
require.NoErrorf(t, err, "cant read nodeAddr from host.RPC %v", servers.RPC)
35
36
app.Scaffold(
37
"scaffold a simple list",
38
false,
39
"list",
40
"item",
41
"str",
42
)
43
44
var (
45
output = &bytes.Buffer{}
46
isTxBodyRetrieved bool
47
txResponse struct {
48
Code int
49
RawLog string `json:"raw_log"`
50
}
51
)
52
// sign tx to add an item to the list.
53
steps := step.NewSteps(
54
step.New(
55
step.Stdout(output),
56
step.Exec(
57
app.Binary(),
58
"tx",
59
"dashedapp",
60
"create-item",
61
"helloworld",
62
"--chain-id", "dashedapp",
63
"--from", "alice",
64
"--node", nodeAddr,
65
"--output", "json",
66
"--log_format", "json",
67
"--yes",
68
),
69
step.PostExec(func(execErr error) error {
70
if execErr != nil {
71
return execErr
72
}
73
err := json.Unmarshal(output.Bytes(), &txResponse)
74
if err != nil {
75
return errors.Errorf("unmarshling tx response: %w", err)
76
}
77
return nil
78
}),
79
),
80
)
81
82
go func() {
83
defer cancel()
84
app.WaitChainUp(ctx, servers.API)
85
isTxBodyRetrieved = env.Exec("sign a tx", steps, envtest.ExecRetry())
86
}()
87
88
app.MustServe(ctx)
89
90
if !isTxBodyRetrieved {
91
t.FailNow()
92
}
93
require.Equal(t, 0, txResponse.Code,
94
"tx failed code=%d log=%s", txResponse.Code, txResponse.RawLog)
95
}
96
97
func TestGetTxViaGRPCGateway(t *testing.T) {
98
var (
99
env = envtest.New(t)
100
appname = randstr.Runes(10)
101
app = env.ScaffoldApp(fmt.Sprintf("github.com/test/%s", appname))
102
servers = app.RandomizeServerPorts()
103
ctx, cancel = context.WithCancel(env.Ctx())
104
)
105
106
var (
107
output = &bytes.Buffer{}
108
isTxBodyRetrieved bool
109
txBody = struct {
110
Tx struct {
111
Body struct {
112
Messages []struct {
113
Amount []struct {
114
Denom string `json:"denom"`
115
Amount string `json:"amount"`
116
} `json:"amount"`
117
} `json:"messages"`
118
} `json:"body"`
119
} `json:"tx"`
120
}{}
121
)
122
123
// 1- list accounts
124
// 2- send tokens from one to other.
125
// 3- verify tx by using gRPC Gateway API.
126
steps := step.NewSteps(
127
step.New(
128
step.Exec(
129
app.Binary(),
130
"keys",
131
"list",
132
"--keyring-backend", "test",
133
"--output", "json",
134
"--log_format", "json",
135
),
136
step.PostExec(func(execErr error) error {
137
if execErr != nil {
138
return execErr
139
}
140
141
// collect addresses of alice and bob.
142
var (
143
accounts []struct {
144
Name string `json:"name"`
145
Address string `json:"address"`
146
}
147
addresses []string
148
)
149
if err := json.NewDecoder(output).Decode(&accounts); err != nil {
150
return err
151
}
152
for _, account := range accounts {
153
if account.Name == "alice" || account.Name == "bob" {
154
addresses = append(addresses, account.Address)
155
}
156
}
157
if len(addresses) != 2 {
158
return errors.New("expected alice and bob accounts to be created")
159
}
160
161
nodeAddr, err := xurl.TCP(servers.RPC)
162
require.NoErrorf(t, err, "cant read nodeAddr from host.RPC %v", servers.RPC)
163
164
// send some tokens from alice to bob and confirm the corresponding tx via gRPC gateway
165
// endpoint by asserting denom and amount.
166
return cmdrunner.New().Run(ctx, step.New(
167
step.Exec(
168
app.Binary(),
169
"tx",
170
"bank",
171
"send",
172
addresses[0],
173
addresses[1],
174
"10token",
175
"--keyring-backend", "test",
176
"--chain-id", appname,
177
"--node", nodeAddr,
178
"--output", "json",
179
"--log_format", "json",
180
"--yes",
181
),
182
step.PreExec(func() error {
183
output.Reset()
184
return nil
185
}),
186
step.PostExec(func(execErr error) error {
187
if execErr != nil {
188
return execErr
189
}
190
191
tx := struct {
192
Hash string `json:"txHash"`
193
}{}
194
if err := json.NewDecoder(output).Decode(&tx); err != nil {
195
return err
196
}
197
198
apiAddr, err := xurl.HTTP(servers.API)
199
if err != nil {
200
return err
201
}
202
203
addr := fmt.Sprintf("%s/cosmos/tx/v1beta1/txs/%s", apiAddr, tx.Hash)
204
req, err := http.NewRequestWithContext(ctx, http.MethodGet, addr, nil)
205
if err != nil {
206
return errors.Wrap(err, "call to get tx via gRPC gateway")
207
}
208
209
time.Sleep(5 * time.Second)
210
resp, err := http.DefaultClient.Do(req)
211
if err != nil {
212
return err
213
}
214
defer resp.Body.Close()
215
216
// Send error if the request failed
217
if resp.StatusCode != http.StatusOK {
218
return errors.New(resp.Status)
219
}
220
221
if err := json.NewDecoder(resp.Body).Decode(&txBody); err != nil {
222
return err
223
}
224
return nil
225
}),
226
step.Stdout(output),
227
))
228
}),
229
step.Stdout(output),
230
))
231
232
go func() {
233
defer cancel()
234
app.WaitChainUp(ctx, servers.API)
235
isTxBodyRetrieved = env.Exec("retrieve account addresses", steps, envtest.ExecRetry())
236
}()
237
238
app.MustServe(ctx)
239
240
if !isTxBodyRetrieved {
241
t.FailNow()
242
}
243
244
require.Len(t, txBody.Tx.Body.Messages, 1)
245
require.Len(t, txBody.Tx.Body.Messages[0].Amount, 1)
246
require.Equal(t, "token", txBody.Tx.Body.Messages[0].Amount[0].Denom)
247
require.Equal(t, "10", txBody.Tx.Body.Messages[0].Amount[0].Amount)
248
}
249
250