github.com/ergo-services/ergo@v1.999.224/tests/core_test.go (about) 1 package tests 2 3 import ( 4 "fmt" 5 "testing" 6 "time" 7 8 "github.com/ergo-services/ergo" 9 "github.com/ergo-services/ergo/etf" 10 "github.com/ergo-services/ergo/gen" 11 "github.com/ergo-services/ergo/lib" 12 "github.com/ergo-services/ergo/node" 13 ) 14 15 type TestCoreGenserver struct { 16 gen.Server 17 } 18 19 func (trg *TestCoreGenserver) HandleCall(process *gen.ServerProcess, from gen.ServerFrom, message etf.Term) (etf.Term, gen.ServerStatus) { 20 // fmt.Printf("TestCoreGenserver ({%s, %s}): HandleCall: %#v, From: %#v\n", trg.process.name, trg.process.Node.Name(), message, from) 21 return message, gen.ServerStatusOK 22 } 23 24 func (trg *TestCoreGenserver) HandleDirect(process *gen.ServerProcess, ref etf.Ref, message interface{}) (interface{}, gen.DirectStatus) { 25 switch m := message.(type) { 26 case makeCall: 27 return process.Call(m.to, m.message) 28 } 29 return nil, lib.ErrUnsupportedRequest 30 } 31 32 func TestCore(t *testing.T) { 33 fmt.Printf("\n=== Test Registrar\n") 34 fmt.Printf("Starting nodes: nodeR1@localhost, nodeR2@localhost: ") 35 node1, _ := ergo.StartNode("nodeR1@localhost", "cookies", node.Options{}) 36 defer node1.Stop() 37 if node1 == nil { 38 t.Fatal("can't start nodes") 39 } else { 40 fmt.Println("OK") 41 } 42 43 gs := &TestCoreGenserver{} 44 fmt.Printf("Starting TestCoreGenserver. registering as 'gs1' on %s and create an alias: ", node1.Name()) 45 node1gs1, err := node1.Spawn("gs1", gen.ProcessOptions{}, gs, nil) 46 if err != nil { 47 t.Fatal(err) 48 } 49 alias, err := node1gs1.CreateAlias() 50 if err != nil { 51 t.Fatal(err) 52 } 53 fmt.Println("OK") 54 55 fmt.Printf("...get process by name 'gs1': ") 56 p := node1.ProcessByName("gs1") 57 if p == nil { 58 message := fmt.Sprintf("missing process %v on %s", node1gs1.Self(), node1.Name()) 59 t.Fatal(message) 60 } 61 fmt.Println("OK") 62 fmt.Printf("...get process by pid of 'gs1': ") 63 p1 := node1.ProcessByPid(node1gs1.Self()) 64 if p1 == nil { 65 message := fmt.Sprintf("missing process %v on %s", node1gs1.Self(), node1.Name()) 66 t.Fatal(message) 67 } 68 69 if p != p1 { 70 message := fmt.Sprintf("not equal: %v on %s", p.Self(), p1.Self()) 71 t.Fatal(message) 72 } 73 fmt.Println("OK") 74 75 fmt.Printf("...get process by alias of 'gs1': ") 76 p2 := node1.ProcessByAlias(alias) 77 if p2 == nil { 78 message := fmt.Sprintf("missing process %v on %s", node1gs1.Self(), node1.Name()) 79 t.Fatal(message) 80 } 81 82 if p1 != p2 { 83 message := fmt.Sprintf("not equal: %v on %s", p1.Self(), p2.Self()) 84 t.Fatal(message) 85 } 86 fmt.Println("OK") 87 88 fmt.Printf("...registering name 'test' related to %v: ", node1gs1.Self()) 89 if e := node1.RegisterName("test", node1gs1.Self()); e != nil { 90 t.Fatal(e) 91 } else { 92 if e := node1.RegisterName("test", node1gs1.Self()); e == nil { 93 t.Fatal("registered duplicate name") 94 } 95 } 96 fmt.Println("OK") 97 fmt.Printf("...unregistering name 'test' related to %v: ", node1gs1.Self()) 98 node1.UnregisterName("test") 99 if e := node1.RegisterName("test", node1gs1.Self()); e != nil { 100 t.Fatal(e) 101 } 102 fmt.Println("OK") 103 104 fmt.Printf("Starting TestCoreGenserver and registering as 'gs2' on %s: ", node1.Name()) 105 node1gs2, err := node1.Spawn("gs2", gen.ProcessOptions{}, gs, nil) 106 if err != nil { 107 t.Fatal(err) 108 } 109 fmt.Println("OK") 110 111 fmt.Printf("...try to unregister 'test' related to %v using gs2 process (not allowed): ", node1gs1.Self()) 112 if err := node1gs2.UnregisterName("test"); err != lib.ErrNameOwner { 113 t.Fatal("not allowed to unregister by not an owner") 114 } 115 fmt.Println("OK") 116 117 fmt.Printf("...try to unregister 'test' related to %v using gs1 process (owner): ", node1gs1.Self()) 118 if err := node1gs1.UnregisterName("test"); err != nil { 119 t.Fatal(err) 120 } 121 122 fmt.Println("OK") 123 } 124 125 func TestCoreAlias(t *testing.T) { 126 fmt.Printf("\n=== Test Registrar Alias\n") 127 fmt.Printf("Starting node: nodeR1Alias@localhost: ") 128 node1, _ := ergo.StartNode("nodeR1Alias@localhost", "cookies", node.Options{}) 129 defer node1.Stop() 130 if node1 == nil { 131 t.Fatal("can't start nodes") 132 } else { 133 fmt.Println("OK") 134 } 135 136 gs := &TestCoreGenserver{} 137 fmt.Printf(" Starting gs1 and gs2 GenServers on %s: ", node1.Name()) 138 node1gs1, err := node1.Spawn("gs1", gen.ProcessOptions{}, gs, nil) 139 if err != nil { 140 t.Fatal(err) 141 } 142 node1gs2, err := node1.Spawn("gs2", gen.ProcessOptions{}, gs, nil) 143 if err != nil { 144 t.Fatal(err) 145 } 146 if len(node1gs1.Aliases()) > 0 || len(node1gs2.Aliases()) > 0 { 147 t.Fatal("alias table must be empty") 148 } 149 150 fmt.Println("OK") 151 152 fmt.Printf(" Create gs1 alias: ") 153 alias, err := node1gs1.CreateAlias() 154 if err != nil { 155 t.Fatal(err) 156 } 157 prc := node1gs1.ProcessByAlias(alias) 158 if prc == nil { 159 t.Fatal("missing alias") 160 } 161 if prc.Self() != node1gs1.Self() { 162 t.Fatal("wrong alias") 163 } 164 fmt.Println("OK") 165 166 fmt.Printf(" Make a call to gs1 via alias: ") 167 call := makeCall{ 168 to: alias, 169 message: "hi", 170 } 171 if reply, err := node1gs2.Direct(call); err == nil { 172 if r, ok := reply.(string); !ok || r != "hi" { 173 t.Fatal("wrong result", reply) 174 } 175 } else { 176 t.Fatal(err) 177 } 178 fmt.Println("OK") 179 180 fmt.Printf(" Delete gs1 alias by gs2 (not allowed): ") 181 if err := node1gs2.DeleteAlias(alias); err != lib.ErrAliasOwner { 182 t.Fatal(" expected ErrAliasOwner, got:", err) 183 } 184 fmt.Println("OK") 185 fmt.Printf(" Delete gs1 alias by itself: ") 186 if err := node1gs1.DeleteAlias(alias); err != nil { 187 t.Fatal(err) 188 } 189 fmt.Println("OK") 190 if a := node1gs1.Aliases(); len(a) > 0 { 191 t.Fatal("alias table (registrar) must be empty on gs1 process", a) 192 } 193 194 if a := node1gs2.Aliases(); len(a) > 0 { 195 t.Fatal("alias table (process) must be empty on gs2 process", a) 196 197 } 198 fmt.Printf(" Aliases must be cleaned up once the owner is down: ") 199 alias1, _ := node1gs1.CreateAlias() 200 alias2, _ := node1gs1.CreateAlias() 201 alias3, _ := node1gs1.CreateAlias() 202 if a := node1gs1.Aliases(); len(a) != 3 { 203 t.Fatal("alias table of gs1 must have 3 aliases", a) 204 } 205 206 if !node1.IsAlias(alias1) || !node1.IsAlias(alias2) || !node1.IsAlias(alias3) { 207 t.Fatal("not an alias", alias1, alias2, alias3) 208 } 209 210 node1gs1.Kill() 211 time.Sleep(100 * time.Millisecond) 212 if a := node1gs1.Aliases(); len(a) != 0 { 213 t.Fatal("alias table must be empty", a) 214 } 215 fmt.Println("OK") 216 217 fmt.Printf(" Create gs1 alias on a stopped process (shouldn't be allowed): ") 218 alias, err = node1gs1.CreateAlias() 219 if err != lib.ErrProcessTerminated { 220 t.Fatal(err) 221 } 222 fmt.Println("OK") 223 224 }