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  }