impl_test.gno
3.71 Kb · 98 lines
1package impl
2
3import (
4 "testing"
5
6 facade "gno.land/r/moul/x/upgrade/adminreg/facade/v0"
7 implv0 "gno.land/r/moul/x/upgrade/adminreg/impl/v0"
8
9 "gno.land/p/nt/uassert/v0"
10)
11
12// TestProposeThenAccept checks the two-step shape: deploying nominates, and
13// only an owner transaction naming a path promotes it.
14//
15// Both impl realms are imported here, so both have already nominated themselves
16// by the time this runs, and neither is serving.
17func TestProposeThenAccept(cur realm, t *testing.T) {
18 testing.SetRealm(testing.NewUserRealm(facade.Ownable.Owner()))
19
20 uassert.Equal(t, 2, len(facade.Candidates()), "both versions nominated themselves")
21 uassert.Equal(t, "", facade.Live(), "nominating is not serving")
22 uassert.AbortsContains(t, cur, "no implementation accepted", func() {
23 facade.Greet("world")
24 })
25
26 // Accepting names a path, not an object: this is a plain maketx call.
27 facade.Accept(cross(cur), "gno.land/r/moul/x/upgrade/adminreg/impl/v0")
28 uassert.Equal(t, "impl/v0", facade.Version())
29 uassert.Equal(t, "hello, world", facade.Greet("world"))
30
31 // The upgrade, and the rollback, are the same single call.
32 facade.Accept(cross(cur), "gno.land/r/moul/x/upgrade/adminreg/impl/v1")
33 uassert.Equal(t, "HELLO, world!", facade.Greet("world"))
34 facade.Accept(cross(cur), implv0.Path)
35 uassert.Equal(t, "hello, world", facade.Greet("world"))
36 facade.Accept(cross(cur), Path)
37
38 // A path nobody nominated cannot be accepted, however owned you are.
39 uassert.AbortsContains(t, cur, "no candidate at", func() {
40 facade.Accept(cross(cur), "gno.land/r/moul/x/upgrade/adminreg/impl/v9")
41 })
42
43 // A non-owner cannot accept even a legitimate candidate.
44 testing.SetRealm(testing.NewUserRealm("g1w4ek2u33ta047h6lta047h6lta047h6ldvdwpn"))
45 uassert.AbortsContains(t, cur, "caller is not owner", func() {
46 facade.Accept(cross(cur), implv0.Path)
47 })
48
49 uassert.Equal(t, "adminreg/facade/v0 [open]\n"+
50 "live: impl/v1 (gno.land/r/moul/x/upgrade/adminreg/impl/v1)\n"+
51 "HELLO, world!\n"+
52 "candidates: 2\n"+
53 "- gno.land/r/moul/x/upgrade/adminreg/impl/v0\n"+
54 "- gno.land/r/moul/x/upgrade/adminreg/impl/v1\n", facade.Render(""))
55}
56
57// TestLadder walks the three rungs and checks the ratchet refuses to loosen.
58//
59// Runs after TestProposeThenAccept on purpose: every rung is one-way, so the
60// tests that need to propose and accept freely must already have run.
61func TestLadder(cur realm, t *testing.T) {
62 testing.SetRealm(testing.NewUserRealm(facade.Ownable.Owner()))
63 uassert.Equal(t, facade.StageOpen, facade.Stage())
64
65 // Rung 2: no new code, but rolling back among what exists still works.
66 facade.Close(cross(cur))
67 uassert.Equal(t, facade.StageClosed, facade.Stage())
68 uassert.AbortsContains(t, cur, "no new candidate may be proposed", func() {
69 Propose(cross(cur))
70 })
71 facade.Accept(cross(cur), implv0.Path)
72 uassert.Equal(t, "hello, world", facade.Greet("world"), "rollback survives Close")
73 facade.Accept(cross(cur), Path)
74
75 // The ratchet only turns one way, even for the owner.
76 uassert.AbortsContains(t, cur, "only tightens", func() {
77 facade.Close(cross(cur))
78 })
79
80 // Rung 3: nothing is accepted again.
81 facade.Freeze(cross(cur))
82 uassert.Equal(t, facade.StageFrozen, facade.Stage())
83 uassert.AbortsContains(t, cur, "is frozen", func() {
84 facade.Accept(cross(cur), implv0.Path)
85 })
86 uassert.AbortsContains(t, cur, "only tightens", func() {
87 facade.Freeze(cross(cur))
88 })
89
90 // What was live stays live, and the render says which rung it is on.
91 uassert.Equal(t, "HELLO, world!", facade.Greet("world"))
92 uassert.Equal(t, "adminreg/facade/v0 [frozen]\n"+
93 "live: impl/v1 (gno.land/r/moul/x/upgrade/adminreg/impl/v1)\n"+
94 "HELLO, world!\n"+
95 "candidates: 2\n"+
96 "- gno.land/r/moul/x/upgrade/adminreg/impl/v0\n"+
97 "- gno.land/r/moul/x/upgrade/adminreg/impl/v1\n", facade.Render(""))
98}