github.com/ergo-services/ergo@v1.999.224/tests/atomcache_test.go (about)

     1  package tests
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/ergo-services/ergo"
    10  	"github.com/ergo-services/ergo/etf"
    11  	"github.com/ergo-services/ergo/gen"
    12  	"github.com/ergo-services/ergo/lib"
    13  	"github.com/ergo-services/ergo/node"
    14  	"github.com/ergo-services/ergo/proto/dist"
    15  )
    16  
    17  func TestAtomCacheLess255Uniq(t *testing.T) {
    18  	fmt.Printf("\n=== Test Atom Cache (less 255 uniq) \n")
    19  	opts1 := node.Options{}
    20  	protoOptions := node.DefaultProtoOptions()
    21  	protoOptions.NumHandlers = 2
    22  	opts1.Proto = dist.CreateProto(protoOptions)
    23  	fmt.Printf("Starting node: nodeAtomCache1Less255@localhost with NumHandlers = 2: ")
    24  	node1, e := ergo.StartNode("nodeAtomCache1Less255@localhost", "cookie", opts1)
    25  	if e != nil {
    26  		t.Fatal(e)
    27  	}
    28  	fmt.Println("OK")
    29  
    30  	fmt.Printf("Starting node: nodeAtomCache2Less255@localhost with NubHandlers = 2: ")
    31  	opts2 := node.Options{}
    32  	opts2.Proto = dist.CreateProto(protoOptions)
    33  	node2, e := ergo.StartNode("nodeAtomCache2Less255@localhost", "cookie", opts2)
    34  	if e != nil {
    35  		t.Fatal(e)
    36  	}
    37  	fmt.Println("OK")
    38  	defer node1.Stop()
    39  	defer node2.Stop()
    40  
    41  	gs1 := &testMonitor{
    42  		v: make(chan interface{}, 2),
    43  	}
    44  	gs2 := &testMonitor{
    45  		v: make(chan interface{}, 2),
    46  	}
    47  
    48  	fmt.Printf("    wait for start of gs1 on %#v: ", node1.Name())
    49  	node1gs1, _ := node1.Spawn("gs1", gen.ProcessOptions{}, gs1, nil)
    50  	waitForResultWithValue(t, gs1.v, node1gs1.Self())
    51  
    52  	fmt.Printf("    wait for start of gs2 on %#v: ", node2.Name())
    53  	node2gs2, _ := node2.Spawn("gs2", gen.ProcessOptions{}, gs2, nil)
    54  	waitForResultWithValue(t, gs2.v, node2gs2.Self())
    55  
    56  	atoms2K := make(etf.List, 2100)
    57  	s := lib.RandomString(240)
    58  	for i := range atoms2K {
    59  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i/10))
    60  	}
    61  
    62  	long := make([]byte, 66*1024)
    63  	for i := range long {
    64  		long[i] = byte(i % 255)
    65  	}
    66  
    67  	fmt.Printf("case 1: sending 2.1K atoms: ")
    68  	rand.Shuffle(len(atoms2K), func(i, j int) {
    69  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
    70  	})
    71  	for i := 0; i < 10; i++ {
    72  		result := atoms2K
    73  		node1gs1.Send(node2gs2.Self(), result)
    74  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
    75  			t.Fatal(err)
    76  		}
    77  	}
    78  	fmt.Println("OK")
    79  
    80  	fmt.Printf("case 2: sending a tuple with 2.1K atoms and 66K binary: ")
    81  	rand.Shuffle(len(atoms2K), func(i, j int) {
    82  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
    83  	})
    84  	for i := 0; i < 10; i++ {
    85  		result := etf.Tuple{atoms2K, long}
    86  		node1gs1.Send(node2gs2.Self(), result)
    87  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
    88  			t.Fatal(err)
    89  		}
    90  	}
    91  	fmt.Println("OK")
    92  
    93  	fmt.Printf("case 3: sending 2.1K UTF-8 long atoms: ")
    94  	s = strings.Repeat("🚀", 252)
    95  	for i := range atoms2K {
    96  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i/10))
    97  	}
    98  	rand.Shuffle(len(atoms2K), func(i, j int) {
    99  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   100  	})
   101  	for i := 0; i < 10; i++ {
   102  		result := atoms2K
   103  		node1gs1.Send(node2gs2.Self(), result)
   104  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   105  			t.Fatal(err)
   106  		}
   107  	}
   108  	fmt.Println("OK")
   109  	fmt.Printf("case 4: sending a tuple with 2.1K UTF-8 long atoms and 66K binary: ")
   110  	rand.Shuffle(len(atoms2K), func(i, j int) {
   111  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   112  	})
   113  	for i := 0; i < 10; i++ {
   114  		result := etf.Tuple{atoms2K, long}
   115  		node1gs1.Send(node2gs2.Self(), result)
   116  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   117  			t.Fatal(err)
   118  		}
   119  	}
   120  	fmt.Println("OK")
   121  }
   122  
   123  func TestAtomCacheMore255Uniq(t *testing.T) {
   124  	fmt.Printf("\n=== Test Atom Cache (more 255 uniq) \n")
   125  	opts1 := node.Options{}
   126  	protoOptions := node.DefaultProtoOptions()
   127  	protoOptions.NumHandlers = 2
   128  	opts1.Proto = dist.CreateProto(protoOptions)
   129  	fmt.Printf("Starting node: nodeAtomCache1More255@localhost with NumHandlers = 2: ")
   130  	node1, e := ergo.StartNode("nodeAtomCache1More255@localhost", "cookie", opts1)
   131  	if e != nil {
   132  		t.Fatal(e)
   133  	}
   134  	fmt.Println("OK")
   135  
   136  	fmt.Printf("Starting node: nodeAtomCache2More255@localhost with NubHandlers = 2: ")
   137  	opts2 := node.Options{}
   138  	opts2.Proto = dist.CreateProto(protoOptions)
   139  	node2, e := ergo.StartNode("nodeAtomCache2More255@localhost", "cookie", opts2)
   140  	if e != nil {
   141  		t.Fatal(e)
   142  	}
   143  	fmt.Println("OK")
   144  	defer node1.Stop()
   145  	defer node2.Stop()
   146  
   147  	gs1 := &testMonitor{
   148  		v: make(chan interface{}, 2),
   149  	}
   150  	gs2 := &testMonitor{
   151  		v: make(chan interface{}, 2),
   152  	}
   153  
   154  	fmt.Printf("    wait for start of gs1 on %#v: ", node1.Name())
   155  	node1gs1, _ := node1.Spawn("gs1", gen.ProcessOptions{}, gs1, nil)
   156  	waitForResultWithValue(t, gs1.v, node1gs1.Self())
   157  
   158  	fmt.Printf("    wait for start of gs2 on %#v: ", node2.Name())
   159  	node2gs2, _ := node2.Spawn("gs2", gen.ProcessOptions{}, gs2, nil)
   160  	waitForResultWithValue(t, gs2.v, node2gs2.Self())
   161  
   162  	atoms2K := make(etf.List, 2100)
   163  	s := lib.RandomString(240)
   164  	for i := range atoms2K {
   165  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i))
   166  	}
   167  
   168  	long := make([]byte, 66*1024)
   169  	for i := range long {
   170  		long[i] = byte(i % 255)
   171  	}
   172  
   173  	fmt.Printf("case 1: sending 2.1K atoms: ")
   174  	rand.Shuffle(len(atoms2K), func(i, j int) {
   175  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   176  	})
   177  	for i := 0; i < 10; i++ {
   178  		result := atoms2K
   179  		node1gs1.Send(node2gs2.Self(), result)
   180  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   181  			t.Fatal(err)
   182  		}
   183  	}
   184  	fmt.Println("OK")
   185  	fmt.Printf("case 2: sending a tuple with 2.1K atoms and 66K binary: ")
   186  	rand.Shuffle(len(atoms2K), func(i, j int) {
   187  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   188  	})
   189  	for i := 0; i < 10; i++ {
   190  		result := etf.Tuple{atoms2K, long}
   191  		node1gs1.Send(node2gs2.Self(), result)
   192  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   193  			t.Fatal(err)
   194  		}
   195  	}
   196  	fmt.Println("OK")
   197  
   198  	fmt.Printf("case 3: sending 2.1K UTF-8 long atoms: ")
   199  	s = strings.Repeat("🚀", 251)
   200  	for i := range atoms2K {
   201  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i))
   202  	}
   203  	rand.Shuffle(len(atoms2K), func(i, j int) {
   204  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   205  	})
   206  	for i := 0; i < 10; i++ {
   207  		result := atoms2K
   208  		node1gs1.Send(node2gs2.Self(), result)
   209  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   210  			t.Fatal(err)
   211  		}
   212  	}
   213  	fmt.Println("OK")
   214  
   215  	fmt.Printf("case 4: sending a tuple with 2.1K UTF-8 long atoms  and 66K binary: ")
   216  	rand.Shuffle(len(atoms2K), func(i, j int) {
   217  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   218  	})
   219  	for i := 0; i < 10; i++ {
   220  		result := etf.Tuple{atoms2K, long}
   221  		node1gs1.Send(node2gs2.Self(), result)
   222  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   223  			t.Fatal(err)
   224  		}
   225  	}
   226  	fmt.Println("OK")
   227  }
   228  
   229  func TestAtomCacheLess255UniqWithCompression(t *testing.T) {
   230  	fmt.Printf("\n=== Test Atom Cache (less 255 uniq) with Compression \n")
   231  	opts1 := node.Options{}
   232  	protoOptions := node.DefaultProtoOptions()
   233  	protoOptions.NumHandlers = 2
   234  	opts1.Proto = dist.CreateProto(protoOptions)
   235  	fmt.Printf("Starting node: nodeAtomCache1Less255Compression@localhost with NumHandlers = 2: ")
   236  	node1, e := ergo.StartNode("nodeAtomCache1Less255Compression@localhost", "cookie", opts1)
   237  	if e != nil {
   238  		t.Fatal(e)
   239  	}
   240  	fmt.Println("OK")
   241  
   242  	fmt.Printf("Starting node: nodeAtomCache2Less255Compression@localhost with NubHandlers = 2: ")
   243  	opts2 := node.Options{}
   244  	opts2.Proto = dist.CreateProto(protoOptions)
   245  	node2, e := ergo.StartNode("nodeAtomCache2Less255Compression@localhost", "cookie", opts2)
   246  	if e != nil {
   247  		t.Fatal(e)
   248  	}
   249  	fmt.Println("OK")
   250  	defer node1.Stop()
   251  	defer node2.Stop()
   252  
   253  	gs1 := &testMonitor{
   254  		v: make(chan interface{}, 2),
   255  	}
   256  	gs2 := &testMonitor{
   257  		v: make(chan interface{}, 2),
   258  	}
   259  
   260  	fmt.Printf("    wait for start of gs1 on %#v: ", node1.Name())
   261  	node1gs1, _ := node1.Spawn("gs1", gen.ProcessOptions{}, gs1, nil)
   262  	waitForResultWithValue(t, gs1.v, node1gs1.Self())
   263  
   264  	node1gs1.SetCompression(true)
   265  
   266  	fmt.Printf("    wait for start of gs2 on %#v: ", node2.Name())
   267  	node2gs2, _ := node2.Spawn("gs2", gen.ProcessOptions{}, gs2, nil)
   268  	waitForResultWithValue(t, gs2.v, node2gs2.Self())
   269  
   270  	atoms2K := make(etf.List, 2100)
   271  	s := lib.RandomString(240)
   272  	for i := range atoms2K {
   273  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i/10))
   274  	}
   275  
   276  	long := make([]byte, 66*1024)
   277  	for i := range long {
   278  		long[i] = byte(i % 255)
   279  	}
   280  
   281  	fmt.Printf("case 1: sending 2.1K atoms: ")
   282  	rand.Shuffle(len(atoms2K), func(i, j int) {
   283  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   284  	})
   285  	for i := 0; i < 10; i++ {
   286  		result := atoms2K
   287  		node1gs1.Send(node2gs2.Self(), result)
   288  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   289  			t.Fatal(err)
   290  		}
   291  	}
   292  	fmt.Println("OK")
   293  	fmt.Printf("case 2: sending a tuple with 2.1K atoms and 66K binary: ")
   294  	rand.Shuffle(len(atoms2K), func(i, j int) {
   295  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   296  	})
   297  	for i := 0; i < 10; i++ {
   298  		result := etf.Tuple{atoms2K, long}
   299  		node1gs1.Send(node2gs2.Self(), result)
   300  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   301  			t.Fatal(err)
   302  		}
   303  	}
   304  	fmt.Println("OK")
   305  
   306  	fmt.Printf("case 3: sending 2.1K UTF-8 long atoms: ")
   307  	s = strings.Repeat("🚀", 252)
   308  	for i := range atoms2K {
   309  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i/10))
   310  	}
   311  	rand.Shuffle(len(atoms2K), func(i, j int) {
   312  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   313  	})
   314  	for i := 0; i < 10; i++ {
   315  		result := atoms2K
   316  		node1gs1.Send(node2gs2.Self(), result)
   317  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   318  			t.Fatal(err)
   319  		}
   320  	}
   321  	fmt.Println("OK")
   322  	fmt.Printf("case 4: sending a tuple with 2.1K UTF-8 long atoms and 66K binary: ")
   323  	rand.Shuffle(len(atoms2K), func(i, j int) {
   324  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   325  	})
   326  	for i := 0; i < 10; i++ {
   327  		result := etf.Tuple{atoms2K, long}
   328  		node1gs1.Send(node2gs2.Self(), result)
   329  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   330  			t.Fatal(err)
   331  		}
   332  	}
   333  	fmt.Println("OK")
   334  }
   335  func TestAtomCacheMore255UniqWithCompression(t *testing.T) {
   336  	fmt.Printf("\n=== Test Atom Cache (more 255 uniq) with Compression \n")
   337  	opts1 := node.Options{}
   338  	protoOptions := node.DefaultProtoOptions()
   339  	protoOptions.NumHandlers = 2
   340  	opts1.Proto = dist.CreateProto(protoOptions)
   341  	fmt.Printf("Starting node: nodeAtomCache1More255Compression@localhost with NumHandlers = 2: ")
   342  	node1, e := ergo.StartNode("nodeAtomCache1More255Compression@localhost", "cookie", opts1)
   343  	if e != nil {
   344  		t.Fatal(e)
   345  	}
   346  	fmt.Println("OK")
   347  
   348  	fmt.Printf("Starting node: nodeAtomCache2More255Compression@localhost with NubHandlers = 2: ")
   349  	opts2 := node.Options{}
   350  	opts2.Proto = dist.CreateProto(protoOptions)
   351  	node2, e := ergo.StartNode("nodeAtomCache2More255Compression@localhost", "cookie", opts2)
   352  	if e != nil {
   353  		t.Fatal(e)
   354  	}
   355  	fmt.Println("OK")
   356  	defer node1.Stop()
   357  	defer node2.Stop()
   358  
   359  	gs1 := &testMonitor{
   360  		v: make(chan interface{}, 2),
   361  	}
   362  	gs2 := &testMonitor{
   363  		v: make(chan interface{}, 2),
   364  	}
   365  
   366  	fmt.Printf("    wait for start of gs1 on %#v: ", node1.Name())
   367  	node1gs1, _ := node1.Spawn("gs1", gen.ProcessOptions{}, gs1, nil)
   368  	waitForResultWithValue(t, gs1.v, node1gs1.Self())
   369  
   370  	node1gs1.SetCompression(true)
   371  
   372  	fmt.Printf("    wait for start of gs2 on %#v: ", node2.Name())
   373  	node2gs2, _ := node2.Spawn("gs2", gen.ProcessOptions{}, gs2, nil)
   374  	waitForResultWithValue(t, gs2.v, node2gs2.Self())
   375  
   376  	atoms2K := make(etf.List, 2100)
   377  	s := lib.RandomString(240)
   378  	for i := range atoms2K {
   379  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i))
   380  	}
   381  
   382  	long := make([]byte, 66*1024)
   383  	for i := range long {
   384  		long[i] = byte(i % 255)
   385  	}
   386  
   387  	fmt.Printf("case 1: sending 2.1K atoms: ")
   388  	rand.Shuffle(len(atoms2K), func(i, j int) {
   389  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   390  	})
   391  	for i := 0; i < 10; i++ {
   392  		result := atoms2K
   393  		node1gs1.Send(node2gs2.Self(), result)
   394  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   395  			t.Fatal(err)
   396  		}
   397  	}
   398  	fmt.Println("OK")
   399  	fmt.Printf("case 2: sending a tuple with 2.1K atoms and 66K binary: ")
   400  	rand.Shuffle(len(atoms2K), func(i, j int) {
   401  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   402  	})
   403  	for i := 0; i < 10; i++ {
   404  		result := etf.Tuple{atoms2K, long}
   405  		node1gs1.Send(node2gs2.Self(), result)
   406  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   407  			t.Fatal(err)
   408  		}
   409  	}
   410  	fmt.Println("OK")
   411  
   412  	fmt.Printf("case 3: sending 2.1K UTF-8 long atoms: ")
   413  	s = strings.Repeat("🚀", 251)
   414  	for i := range atoms2K {
   415  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i))
   416  	}
   417  	rand.Shuffle(len(atoms2K), func(i, j int) {
   418  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   419  	})
   420  	for i := 0; i < 10; i++ {
   421  		result := atoms2K
   422  		node1gs1.Send(node2gs2.Self(), result)
   423  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   424  			t.Fatal(err)
   425  		}
   426  	}
   427  	fmt.Println("OK")
   428  	fmt.Printf("case 4: sending a tuple with 2.1K UTF-8 long atoms  and 66K binary: ")
   429  	rand.Shuffle(len(atoms2K), func(i, j int) {
   430  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   431  	})
   432  	for i := 0; i < 10; i++ {
   433  		result := etf.Tuple{atoms2K, long}
   434  		node1gs1.Send(node2gs2.Self(), result)
   435  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   436  			t.Fatal(err)
   437  		}
   438  	}
   439  	fmt.Println("OK")
   440  }
   441  
   442  func TestAtomCacheLess255UniqViaProxy(t *testing.T) {
   443  	fmt.Printf("\n=== Test Atom Cache (less 255 uniq) via Proxy connection \n")
   444  	opts1 := node.Options{}
   445  	protoOptions := node.DefaultProtoOptions()
   446  	protoOptions.NumHandlers = 2
   447  	opts1.Proto = dist.CreateProto(protoOptions)
   448  	fmt.Printf("Starting node: nodeAtomCache1Less255ViaProxy@localhost with NumHandlers = 2: ")
   449  	node1, e := ergo.StartNode("nodeAtomCache1Less255ViaProxy@localhost", "cookie", opts1)
   450  	if e != nil {
   451  		t.Fatal(e)
   452  	}
   453  	fmt.Println("OK")
   454  
   455  	fmt.Printf("Starting node: nodeAtomCacheTLess255ViaProxy@localhost with NubHandlers = 2: ")
   456  	optsT := node.Options{}
   457  	optsT.Proxy.Transit = true
   458  	optsT.Proto = dist.CreateProto(protoOptions)
   459  	nodeT, e := ergo.StartNode("nodeAtomCacheTLess255ViaProxy@localhost", "cookie", optsT)
   460  	if e != nil {
   461  		t.Fatal(e)
   462  	}
   463  	fmt.Println("OK")
   464  
   465  	fmt.Printf("Starting node: nodeAtomCache2Less255ViaProxy@localhost with NubHandlers = 2: ")
   466  	opts2 := node.Options{}
   467  	opts2.Proxy.Accept = true
   468  	opts2.Proto = dist.CreateProto(protoOptions)
   469  	node2, e := ergo.StartNode("nodeAtomCache2Less255ViaProxy@localhost", "cookie", opts2)
   470  	if e != nil {
   471  		t.Fatal(e)
   472  	}
   473  	fmt.Println("OK")
   474  	defer node1.Stop()
   475  	defer node2.Stop()
   476  	defer nodeT.Stop()
   477  
   478  	fmt.Printf("    connect %s with %s via proxy %s: ", node1.Name(), node2.Name(), nodeT.Name())
   479  	route := node.ProxyRoute{
   480  		Name:  node2.Name(),
   481  		Proxy: nodeT.Name(),
   482  	}
   483  	node1.AddProxyRoute(route)
   484  
   485  	if err := node1.Connect(node2.Name()); err != nil {
   486  		t.Fatal(err)
   487  	}
   488  
   489  	indirectNodes := node2.NodesIndirect()
   490  	if len(indirectNodes) != 1 || indirectNodes[0] != node1.Name() {
   491  		t.Fatal("wrong result:", indirectNodes)
   492  	}
   493  	fmt.Println("OK")
   494  
   495  	gs1 := &testMonitor{
   496  		v: make(chan interface{}, 2),
   497  	}
   498  	gs2 := &testMonitor{
   499  		v: make(chan interface{}, 2),
   500  	}
   501  
   502  	fmt.Printf("    wait for start of gs1 on %#v: ", node1.Name())
   503  	node1gs1, _ := node1.Spawn("gs1", gen.ProcessOptions{}, gs1, nil)
   504  	waitForResultWithValue(t, gs1.v, node1gs1.Self())
   505  
   506  	fmt.Printf("    wait for start of gs2 on %#v: ", node2.Name())
   507  	node2gs2, _ := node2.Spawn("gs2", gen.ProcessOptions{}, gs2, nil)
   508  	waitForResultWithValue(t, gs2.v, node2gs2.Self())
   509  
   510  	atoms2K := make(etf.List, 2100)
   511  	s := lib.RandomString(240)
   512  	for i := range atoms2K {
   513  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i/10))
   514  	}
   515  
   516  	long := make([]byte, 66*1024)
   517  	for i := range long {
   518  		long[i] = byte(i % 255)
   519  	}
   520  
   521  	fmt.Printf("case 1: sending 2.1K atoms: ")
   522  	rand.Shuffle(len(atoms2K), func(i, j int) {
   523  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   524  	})
   525  	for i := 0; i < 10; i++ {
   526  		result := atoms2K
   527  		node1gs1.Send(node2gs2.Self(), result)
   528  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   529  			t.Fatal(err)
   530  		}
   531  	}
   532  	fmt.Println("OK")
   533  	fmt.Printf("case 2: sending a tuple with 2.1K atoms and 66K binary: ")
   534  	rand.Shuffle(len(atoms2K), func(i, j int) {
   535  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   536  	})
   537  	for i := 0; i < 10; i++ {
   538  		result := etf.Tuple{atoms2K, long}
   539  		node1gs1.Send(node2gs2.Self(), result)
   540  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   541  			t.Fatal(err)
   542  		}
   543  	}
   544  	fmt.Println("OK")
   545  
   546  	fmt.Printf("case 3: sending 2.1K UTF-8 long atoms: ")
   547  	s = strings.Repeat("🚀", 252)
   548  	for i := range atoms2K {
   549  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i/10))
   550  	}
   551  	rand.Shuffle(len(atoms2K), func(i, j int) {
   552  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   553  	})
   554  	for i := 0; i < 10; i++ {
   555  		result := atoms2K
   556  		node1gs1.Send(node2gs2.Self(), result)
   557  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   558  			t.Fatal(err)
   559  		}
   560  	}
   561  	fmt.Println("OK")
   562  	fmt.Printf("case 4: sending a tuple with 2.1K UTF-8 long atoms and 66K binary: ")
   563  	rand.Shuffle(len(atoms2K), func(i, j int) {
   564  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   565  	})
   566  	for i := 0; i < 10; i++ {
   567  		result := etf.Tuple{atoms2K, long}
   568  		node1gs1.Send(node2gs2.Self(), result)
   569  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   570  			t.Fatal(err)
   571  		}
   572  	}
   573  	fmt.Println("OK")
   574  }
   575  
   576  func TestAtomCacheMore255UniqViaProxy(t *testing.T) {
   577  	fmt.Printf("\n=== Test Atom Cache (more 255 uniq) via Proxy connection \n")
   578  	opts1 := node.Options{}
   579  	protoOptions := node.DefaultProtoOptions()
   580  	protoOptions.NumHandlers = 2
   581  	opts1.Proto = dist.CreateProto(protoOptions)
   582  	fmt.Printf("Starting node: nodeAtomCache1More255ViaProxy@localhost with NumHandlers = 2: ")
   583  	node1, e := ergo.StartNode("nodeAtomCache1More255ViaProxy@localhost", "cookie", opts1)
   584  	if e != nil {
   585  		t.Fatal(e)
   586  	}
   587  	fmt.Println("OK")
   588  
   589  	fmt.Printf("Starting node: nodeAtomCacheTMore255ViaProxy@localhost with NubHandlers = 2: ")
   590  	optsT := node.Options{}
   591  	optsT.Proxy.Transit = true
   592  	optsT.Proto = dist.CreateProto(protoOptions)
   593  	nodeT, e := ergo.StartNode("nodeAtomCacheTMore255ViaProxy@localhost", "cookie", optsT)
   594  	if e != nil {
   595  		t.Fatal(e)
   596  	}
   597  	fmt.Println("OK")
   598  
   599  	fmt.Printf("Starting node: nodeAtomCache2More255ViaProxy@localhost with NubHandlers = 2: ")
   600  	opts2 := node.Options{}
   601  	opts2.Proxy.Accept = true
   602  	opts2.Proto = dist.CreateProto(protoOptions)
   603  	node2, e := ergo.StartNode("nodeAtomCache2More255ViaProxy@localhost", "cookie", opts2)
   604  	if e != nil {
   605  		t.Fatal(e)
   606  	}
   607  	fmt.Println("OK")
   608  	defer node1.Stop()
   609  	defer node2.Stop()
   610  	defer nodeT.Stop()
   611  
   612  	fmt.Printf("    connect %s with %s via proxy %s: ", node1.Name(), node2.Name(), nodeT.Name())
   613  	route := node.ProxyRoute{
   614  		Name:  node2.Name(),
   615  		Proxy: nodeT.Name(),
   616  	}
   617  	node1.AddProxyRoute(route)
   618  
   619  	if err := node1.Connect(node2.Name()); err != nil {
   620  		t.Fatal(err)
   621  	}
   622  
   623  	indirectNodes := node2.NodesIndirect()
   624  	if len(indirectNodes) != 1 || indirectNodes[0] != node1.Name() {
   625  		t.Fatal("wrong result:", indirectNodes)
   626  	}
   627  	fmt.Println("OK")
   628  
   629  	gs1 := &testMonitor{
   630  		v: make(chan interface{}, 2),
   631  	}
   632  	gs2 := &testMonitor{
   633  		v: make(chan interface{}, 2),
   634  	}
   635  
   636  	fmt.Printf("    wait for start of gs1 on %#v: ", node1.Name())
   637  	node1gs1, _ := node1.Spawn("gs1", gen.ProcessOptions{}, gs1, nil)
   638  	waitForResultWithValue(t, gs1.v, node1gs1.Self())
   639  
   640  	fmt.Printf("    wait for start of gs2 on %#v: ", node2.Name())
   641  	node2gs2, _ := node2.Spawn("gs2", gen.ProcessOptions{}, gs2, nil)
   642  	waitForResultWithValue(t, gs2.v, node2gs2.Self())
   643  
   644  	atoms2K := make(etf.List, 2100)
   645  	s := lib.RandomString(240)
   646  	for i := range atoms2K {
   647  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i))
   648  	}
   649  
   650  	long := make([]byte, 66*1024)
   651  	for i := range long {
   652  		long[i] = byte(i % 255)
   653  	}
   654  
   655  	fmt.Printf("case 1: sending 2.1K atoms: ")
   656  	rand.Shuffle(len(atoms2K), func(i, j int) {
   657  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   658  	})
   659  	for i := 0; i < 10; i++ {
   660  		result := atoms2K
   661  		node1gs1.Send(node2gs2.Self(), result)
   662  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   663  			t.Fatal(err)
   664  		}
   665  	}
   666  	fmt.Println("OK")
   667  	fmt.Printf("case 2: sending a tuple with 2.1K atoms and 66K binary: ")
   668  	rand.Shuffle(len(atoms2K), func(i, j int) {
   669  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   670  	})
   671  	for i := 0; i < 10; i++ {
   672  		result := etf.Tuple{atoms2K, long}
   673  		node1gs1.Send(node2gs2.Self(), result)
   674  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   675  			t.Fatal(err)
   676  		}
   677  	}
   678  	fmt.Println("OK")
   679  
   680  	fmt.Printf("case 3: sending 2.1K UTF-8 long atoms: ")
   681  	s = strings.Repeat("🚀", 252)
   682  	for i := range atoms2K {
   683  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i/10))
   684  	}
   685  	rand.Shuffle(len(atoms2K), func(i, j int) {
   686  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   687  	})
   688  	for i := 0; i < 10; i++ {
   689  		result := atoms2K
   690  		node1gs1.Send(node2gs2.Self(), result)
   691  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   692  			t.Fatal(err)
   693  		}
   694  	}
   695  	fmt.Println("OK")
   696  	fmt.Printf("case 4: sending a tuple with 2.1K UTF-8 long atoms and 66K binary: ")
   697  	rand.Shuffle(len(atoms2K), func(i, j int) {
   698  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   699  	})
   700  	for i := 0; i < 10; i++ {
   701  		result := etf.Tuple{atoms2K, long}
   702  		node1gs1.Send(node2gs2.Self(), result)
   703  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   704  			t.Fatal(err)
   705  		}
   706  	}
   707  	fmt.Println("OK")
   708  }
   709  
   710  func TestAtomCacheLess255UniqViaProxyWithEncryption(t *testing.T) {
   711  	fmt.Printf("\n=== Test Atom Cache (less 255 uniq) via Proxy connection with Encryption\n")
   712  	opts1 := node.Options{}
   713  	protoOptions := node.DefaultProtoOptions()
   714  	protoOptions.NumHandlers = 2
   715  	opts1.Proto = dist.CreateProto(protoOptions)
   716  
   717  	opts1.Proxy.Flags = node.DefaultProxyFlags()
   718  	opts1.Proxy.Flags.EnableEncryption = true
   719  
   720  	fmt.Printf("Starting node: nodeAtomCache1Less255ViaProxyEnc@localhost with NumHandlers = 2: ")
   721  	node1, e := ergo.StartNode("nodeAtomCache1Less255ViaProxyEnc@localhost", "cookie", opts1)
   722  	if e != nil {
   723  		t.Fatal(e)
   724  	}
   725  	fmt.Println("OK")
   726  
   727  	fmt.Printf("Starting node: nodeAtomCacheTLess255ViaProxyEnc@localhost with NubHandlers = 2: ")
   728  	optsT := node.Options{}
   729  	optsT.Proxy.Transit = true
   730  	optsT.Proto = dist.CreateProto(protoOptions)
   731  	nodeT, e := ergo.StartNode("nodeAtomCacheTLess255ViaProxyEnc@localhost", "cookie", optsT)
   732  	if e != nil {
   733  		t.Fatal(e)
   734  	}
   735  	fmt.Println("OK")
   736  
   737  	fmt.Printf("Starting node: nodeAtomCache2Less255ViaProxyEnc@localhost with NubHandlers = 2: ")
   738  	opts2 := node.Options{}
   739  	opts2.Proxy.Accept = true
   740  	opts2.Proto = dist.CreateProto(protoOptions)
   741  	node2, e := ergo.StartNode("nodeAtomCache2Less255ViaProxyEnc@localhost", "cookie", opts2)
   742  	if e != nil {
   743  		t.Fatal(e)
   744  	}
   745  	fmt.Println("OK")
   746  	defer node1.Stop()
   747  	defer node2.Stop()
   748  	defer nodeT.Stop()
   749  
   750  	fmt.Printf("    connect %s with %s via proxy %s: ", node1.Name(), node2.Name(), nodeT.Name())
   751  	route := node.ProxyRoute{
   752  		Name:  node2.Name(),
   753  		Proxy: nodeT.Name(),
   754  	}
   755  	node1.AddProxyRoute(route)
   756  
   757  	if err := node1.Connect(node2.Name()); err != nil {
   758  		t.Fatal(err)
   759  	}
   760  
   761  	indirectNodes := node2.NodesIndirect()
   762  	if len(indirectNodes) != 1 || indirectNodes[0] != node1.Name() {
   763  		t.Fatal("wrong result:", indirectNodes)
   764  	}
   765  	fmt.Println("OK")
   766  
   767  	gs1 := &testMonitor{
   768  		v: make(chan interface{}, 2),
   769  	}
   770  	gs2 := &testMonitor{
   771  		v: make(chan interface{}, 2),
   772  	}
   773  
   774  	fmt.Printf("    wait for start of gs1 on %#v: ", node1.Name())
   775  	node1gs1, _ := node1.Spawn("gs1", gen.ProcessOptions{}, gs1, nil)
   776  	waitForResultWithValue(t, gs1.v, node1gs1.Self())
   777  
   778  	fmt.Printf("    wait for start of gs2 on %#v: ", node2.Name())
   779  	node2gs2, _ := node2.Spawn("gs2", gen.ProcessOptions{}, gs2, nil)
   780  	waitForResultWithValue(t, gs2.v, node2gs2.Self())
   781  
   782  	atoms2K := make(etf.List, 2100)
   783  	s := lib.RandomString(240)
   784  	for i := range atoms2K {
   785  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i/10))
   786  	}
   787  
   788  	long := make([]byte, 66*1024)
   789  	for i := range long {
   790  		long[i] = byte(i % 255)
   791  	}
   792  
   793  	fmt.Printf("case 1: sending 2.1K atoms: ")
   794  	rand.Shuffle(len(atoms2K), func(i, j int) {
   795  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   796  	})
   797  	for i := 0; i < 10; i++ {
   798  		result := atoms2K
   799  		node1gs1.Send(node2gs2.Self(), result)
   800  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   801  			t.Fatal(err)
   802  		}
   803  	}
   804  	fmt.Println("OK")
   805  	fmt.Printf("case 2: sending a tuple with 2.1K atoms and 66K binary: ")
   806  	rand.Shuffle(len(atoms2K), func(i, j int) {
   807  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   808  	})
   809  	for i := 0; i < 10; i++ {
   810  		result := etf.Tuple{atoms2K, long}
   811  		node1gs1.Send(node2gs2.Self(), result)
   812  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   813  			t.Fatal(err)
   814  		}
   815  	}
   816  	fmt.Println("OK")
   817  
   818  	fmt.Printf("case 3: sending 2.1K UTF-8 long atoms: ")
   819  	s = strings.Repeat("🚀", 252)
   820  	for i := range atoms2K {
   821  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i/10))
   822  	}
   823  	rand.Shuffle(len(atoms2K), func(i, j int) {
   824  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   825  	})
   826  	for i := 0; i < 10; i++ {
   827  		result := atoms2K
   828  		node1gs1.Send(node2gs2.Self(), result)
   829  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   830  			t.Fatal(err)
   831  		}
   832  	}
   833  	fmt.Println("OK")
   834  	fmt.Printf("case 4: sending a tuple with 2.1K UTF-8 long atoms and 66K binary: ")
   835  	rand.Shuffle(len(atoms2K), func(i, j int) {
   836  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   837  	})
   838  	for i := 0; i < 10; i++ {
   839  		result := etf.Tuple{atoms2K, long}
   840  		node1gs1.Send(node2gs2.Self(), result)
   841  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   842  			t.Fatal(err)
   843  		}
   844  	}
   845  	fmt.Println("OK")
   846  }
   847  
   848  func TestAtomCacheMore255UniqViaProxyWithEncryption(t *testing.T) {
   849  	fmt.Printf("\n=== Test Atom Cache (more 255 uniq) via Proxy connection with Encriptin \n")
   850  	opts1 := node.Options{}
   851  	protoOptions := node.DefaultProtoOptions()
   852  	protoOptions.NumHandlers = 2
   853  	opts1.Proto = dist.CreateProto(protoOptions)
   854  
   855  	opts1.Proxy.Flags = node.DefaultProxyFlags()
   856  	opts1.Proxy.Flags.EnableEncryption = true
   857  
   858  	fmt.Printf("Starting node: nodeAtomCache1More255ViaProxyEnc@localhost with NumHandlers = 2: ")
   859  	node1, e := ergo.StartNode("nodeAtomCache1More255ViaProxyEnc@localhost", "cookie", opts1)
   860  	if e != nil {
   861  		t.Fatal(e)
   862  	}
   863  	fmt.Println("OK")
   864  
   865  	fmt.Printf("Starting node: nodeAtomCacheTMore255ViaProxyEnc@localhost with NubHandlers = 2: ")
   866  	optsT := node.Options{}
   867  	optsT.Proxy.Transit = true
   868  	optsT.Proto = dist.CreateProto(protoOptions)
   869  	nodeT, e := ergo.StartNode("nodeAtomCacheTMore255ViaProxyEnc@localhost", "cookie", optsT)
   870  	if e != nil {
   871  		t.Fatal(e)
   872  	}
   873  	fmt.Println("OK")
   874  
   875  	fmt.Printf("Starting node: nodeAtomCache2More255ViaProxyEnc@localhost with NubHandlers = 2: ")
   876  	opts2 := node.Options{}
   877  	opts2.Proxy.Accept = true
   878  	opts2.Proto = dist.CreateProto(protoOptions)
   879  	node2, e := ergo.StartNode("nodeAtomCache2More255ViaProxyEnc@localhost", "cookie", opts2)
   880  	if e != nil {
   881  		t.Fatal(e)
   882  	}
   883  	fmt.Println("OK")
   884  	defer node1.Stop()
   885  	defer node2.Stop()
   886  	defer nodeT.Stop()
   887  
   888  	fmt.Printf("    connect %s with %s via proxy %s: ", node1.Name(), node2.Name(), nodeT.Name())
   889  	route := node.ProxyRoute{
   890  		Name:  node2.Name(),
   891  		Proxy: nodeT.Name(),
   892  	}
   893  	node1.AddProxyRoute(route)
   894  
   895  	if err := node1.Connect(node2.Name()); err != nil {
   896  		t.Fatal(err)
   897  	}
   898  
   899  	indirectNodes := node2.NodesIndirect()
   900  	if len(indirectNodes) != 1 || indirectNodes[0] != node1.Name() {
   901  		t.Fatal("wrong result:", indirectNodes)
   902  	}
   903  	fmt.Println("OK")
   904  
   905  	gs1 := &testMonitor{
   906  		v: make(chan interface{}, 2),
   907  	}
   908  	gs2 := &testMonitor{
   909  		v: make(chan interface{}, 2),
   910  	}
   911  
   912  	fmt.Printf("    wait for start of gs1 on %#v: ", node1.Name())
   913  	node1gs1, _ := node1.Spawn("gs1", gen.ProcessOptions{}, gs1, nil)
   914  	waitForResultWithValue(t, gs1.v, node1gs1.Self())
   915  
   916  	fmt.Printf("    wait for start of gs2 on %#v: ", node2.Name())
   917  	node2gs2, _ := node2.Spawn("gs2", gen.ProcessOptions{}, gs2, nil)
   918  	waitForResultWithValue(t, gs2.v, node2gs2.Self())
   919  
   920  	atoms2K := make(etf.List, 2100)
   921  	s := lib.RandomString(240)
   922  	for i := range atoms2K {
   923  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i))
   924  	}
   925  
   926  	long := make([]byte, 66*1024)
   927  	for i := range long {
   928  		long[i] = byte(i % 255)
   929  	}
   930  
   931  	fmt.Printf("case 1: sending 2.1K atoms: ")
   932  	rand.Shuffle(len(atoms2K), func(i, j int) {
   933  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   934  	})
   935  	for i := 0; i < 10; i++ {
   936  		result := atoms2K
   937  		node1gs1.Send(node2gs2.Self(), result)
   938  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   939  			t.Fatal(err)
   940  		}
   941  	}
   942  	fmt.Println("OK")
   943  	fmt.Printf("case 2: sending a tuple with 2.1K atoms and 66K binary: ")
   944  	rand.Shuffle(len(atoms2K), func(i, j int) {
   945  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   946  	})
   947  	for i := 0; i < 10; i++ {
   948  		result := etf.Tuple{atoms2K, long}
   949  		node1gs1.Send(node2gs2.Self(), result)
   950  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   951  			t.Fatal(err)
   952  		}
   953  	}
   954  	fmt.Println("OK")
   955  
   956  	fmt.Printf("case 3: sending 2.1K UTF-8 long atoms: ")
   957  	s = strings.Repeat("🚀", 252)
   958  	for i := range atoms2K {
   959  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i/10))
   960  	}
   961  	rand.Shuffle(len(atoms2K), func(i, j int) {
   962  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   963  	})
   964  	for i := 0; i < 10; i++ {
   965  		result := atoms2K
   966  		node1gs1.Send(node2gs2.Self(), result)
   967  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   968  			t.Fatal(err)
   969  		}
   970  	}
   971  	fmt.Println("OK")
   972  	fmt.Printf("case 4: sending a tuple with 2.1K UTF-8 long atoms and 66K binary: ")
   973  	rand.Shuffle(len(atoms2K), func(i, j int) {
   974  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
   975  	})
   976  	for i := 0; i < 10; i++ {
   977  		result := etf.Tuple{atoms2K, long}
   978  		node1gs1.Send(node2gs2.Self(), result)
   979  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
   980  			t.Fatal(err)
   981  		}
   982  	}
   983  	fmt.Println("OK")
   984  }
   985  
   986  func TestAtomCacheLess255UniqViaProxyWithEncryptionCompression(t *testing.T) {
   987  	fmt.Printf("\n=== Test Atom Cache (less 255 uniq) via Proxy connection with Encryption and Compression\n")
   988  	opts1 := node.Options{}
   989  	protoOptions := node.DefaultProtoOptions()
   990  	protoOptions.NumHandlers = 2
   991  	opts1.Proto = dist.CreateProto(protoOptions)
   992  
   993  	opts1.Proxy.Flags = node.DefaultProxyFlags()
   994  	opts1.Proxy.Flags.EnableEncryption = true
   995  
   996  	fmt.Printf("Starting node: nodeAtomCache1Less255ViaProxyEncComp@localhost with NumHandlers = 2: ")
   997  	node1, e := ergo.StartNode("nodeAtomCache1Less255ViaProxyEncComp@localhost", "cookie", opts1)
   998  	if e != nil {
   999  		t.Fatal(e)
  1000  	}
  1001  	fmt.Println("OK")
  1002  
  1003  	fmt.Printf("Starting node: nodeAtomCacheTLess255ViaProxyEncComp@localhost with NubHandlers = 2: ")
  1004  	optsT := node.Options{}
  1005  	optsT.Proxy.Transit = true
  1006  	optsT.Proto = dist.CreateProto(protoOptions)
  1007  	nodeT, e := ergo.StartNode("nodeAtomCacheTLess255ViaProxyEncComp@localhost", "cookie", optsT)
  1008  	if e != nil {
  1009  		t.Fatal(e)
  1010  	}
  1011  	fmt.Println("OK")
  1012  
  1013  	fmt.Printf("Starting node: nodeAtomCache2Less255ViaProxyEncComp@localhost with NubHandlers = 2: ")
  1014  	opts2 := node.Options{}
  1015  	opts2.Proxy.Accept = true
  1016  	opts2.Proto = dist.CreateProto(protoOptions)
  1017  	node2, e := ergo.StartNode("nodeAtomCache2Less255ViaProxyEncComp@localhost", "cookie", opts2)
  1018  	if e != nil {
  1019  		t.Fatal(e)
  1020  	}
  1021  	fmt.Println("OK")
  1022  	defer node1.Stop()
  1023  	defer node2.Stop()
  1024  	defer nodeT.Stop()
  1025  
  1026  	fmt.Printf("    connect %s with %s via proxy %s: ", node1.Name(), node2.Name(), nodeT.Name())
  1027  	route := node.ProxyRoute{
  1028  		Name:  node2.Name(),
  1029  		Proxy: nodeT.Name(),
  1030  	}
  1031  	node1.AddProxyRoute(route)
  1032  
  1033  	if err := node1.Connect(node2.Name()); err != nil {
  1034  		t.Fatal(err)
  1035  	}
  1036  
  1037  	indirectNodes := node2.NodesIndirect()
  1038  	if len(indirectNodes) != 1 || indirectNodes[0] != node1.Name() {
  1039  		t.Fatal("wrong result:", indirectNodes)
  1040  	}
  1041  	fmt.Println("OK")
  1042  
  1043  	gs1 := &testMonitor{
  1044  		v: make(chan interface{}, 2),
  1045  	}
  1046  	gs2 := &testMonitor{
  1047  		v: make(chan interface{}, 2),
  1048  	}
  1049  
  1050  	fmt.Printf("    wait for start of gs1 on %#v: ", node1.Name())
  1051  	node1gs1, _ := node1.Spawn("gs1", gen.ProcessOptions{}, gs1, nil)
  1052  	waitForResultWithValue(t, gs1.v, node1gs1.Self())
  1053  
  1054  	node1gs1.SetCompression(true)
  1055  
  1056  	fmt.Printf("    wait for start of gs2 on %#v: ", node2.Name())
  1057  	node2gs2, _ := node2.Spawn("gs2", gen.ProcessOptions{}, gs2, nil)
  1058  	waitForResultWithValue(t, gs2.v, node2gs2.Self())
  1059  
  1060  	atoms2K := make(etf.List, 2100)
  1061  	s := lib.RandomString(240)
  1062  	for i := range atoms2K {
  1063  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i/10))
  1064  	}
  1065  
  1066  	long := make([]byte, 66*1024)
  1067  	for i := range long {
  1068  		long[i] = byte(i % 255)
  1069  	}
  1070  
  1071  	fmt.Printf("case 1: sending 2.1K atoms: ")
  1072  	rand.Shuffle(len(atoms2K), func(i, j int) {
  1073  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
  1074  	})
  1075  	for i := 0; i < 10; i++ {
  1076  		result := atoms2K
  1077  		node1gs1.Send(node2gs2.Self(), result)
  1078  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
  1079  			t.Fatal(err)
  1080  		}
  1081  	}
  1082  	fmt.Println("OK")
  1083  	fmt.Printf("case 2: sending a tuple with 2.1K atoms and 66K binary: ")
  1084  	rand.Shuffle(len(atoms2K), func(i, j int) {
  1085  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
  1086  	})
  1087  	for i := 0; i < 10; i++ {
  1088  		result := etf.Tuple{atoms2K, long}
  1089  		node1gs1.Send(node2gs2.Self(), result)
  1090  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
  1091  			t.Fatal(err)
  1092  		}
  1093  	}
  1094  	fmt.Println("OK")
  1095  
  1096  	fmt.Printf("case 3: sending 2.1K UTF-8 long atoms: ")
  1097  	s = strings.Repeat("🚀", 252)
  1098  	for i := range atoms2K {
  1099  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i/10))
  1100  	}
  1101  	rand.Shuffle(len(atoms2K), func(i, j int) {
  1102  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
  1103  	})
  1104  	for i := 0; i < 10; i++ {
  1105  		result := atoms2K
  1106  		node1gs1.Send(node2gs2.Self(), result)
  1107  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
  1108  			t.Fatal(err)
  1109  		}
  1110  	}
  1111  	fmt.Println("OK")
  1112  	fmt.Printf("case 4: sending a tuple with 2.1K UTF-8 long atoms and 66K binary: ")
  1113  	rand.Shuffle(len(atoms2K), func(i, j int) {
  1114  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
  1115  	})
  1116  	for i := 0; i < 10; i++ {
  1117  		result := etf.Tuple{atoms2K, long}
  1118  		node1gs1.Send(node2gs2.Self(), result)
  1119  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
  1120  			t.Fatal(err)
  1121  		}
  1122  	}
  1123  	fmt.Println("OK")
  1124  }
  1125  
  1126  func TestAtomCacheMore255UniqViaProxyWithEncryptionCompression(t *testing.T) {
  1127  	fmt.Printf("\n=== Test Atom Cache (more 255 uniq) via Proxy connection with Encription and Compression \n")
  1128  	opts1 := node.Options{}
  1129  	protoOptions := node.DefaultProtoOptions()
  1130  	protoOptions.NumHandlers = 2
  1131  	opts1.Proto = dist.CreateProto(protoOptions)
  1132  
  1133  	opts1.Proxy.Flags = node.DefaultProxyFlags()
  1134  	opts1.Proxy.Flags.EnableEncryption = true
  1135  
  1136  	fmt.Printf("Starting node: nodeAtomCache1More255ViaProxyEncComp@localhost with NumHandlers = 2: ")
  1137  	node1, e := ergo.StartNode("nodeAtomCache1More255ViaProxyEncComp@localhost", "cookie", opts1)
  1138  	if e != nil {
  1139  		t.Fatal(e)
  1140  	}
  1141  	fmt.Println("OK")
  1142  
  1143  	fmt.Printf("Starting node: nodeAtomCacheTMore255ViaProxyEncComp@localhost with NubHandlers = 2: ")
  1144  	optsT := node.Options{}
  1145  	optsT.Proxy.Transit = true
  1146  	optsT.Proto = dist.CreateProto(protoOptions)
  1147  	nodeT, e := ergo.StartNode("nodeAtomCacheTMore255ViaProxyEncComp@localhost", "cookie", optsT)
  1148  	if e != nil {
  1149  		t.Fatal(e)
  1150  	}
  1151  	fmt.Println("OK")
  1152  
  1153  	fmt.Printf("Starting node: nodeAtomCache2More255ViaProxyEncComp@localhost with NubHandlers = 2: ")
  1154  	opts2 := node.Options{}
  1155  	opts2.Proxy.Accept = true
  1156  	opts2.Proto = dist.CreateProto(protoOptions)
  1157  	node2, e := ergo.StartNode("nodeAtomCache2More255ViaProxyEncComp@localhost", "cookie", opts2)
  1158  	if e != nil {
  1159  		t.Fatal(e)
  1160  	}
  1161  	fmt.Println("OK")
  1162  	defer node1.Stop()
  1163  	defer node2.Stop()
  1164  	defer nodeT.Stop()
  1165  
  1166  	fmt.Printf("    connect %s with %s via proxy %s: ", node1.Name(), node2.Name(), nodeT.Name())
  1167  	route := node.ProxyRoute{
  1168  		Name:  node2.Name(),
  1169  		Proxy: nodeT.Name(),
  1170  	}
  1171  	node1.AddProxyRoute(route)
  1172  
  1173  	if err := node1.Connect(node2.Name()); err != nil {
  1174  		t.Fatal(err)
  1175  	}
  1176  
  1177  	indirectNodes := node2.NodesIndirect()
  1178  	if len(indirectNodes) != 1 || indirectNodes[0] != node1.Name() {
  1179  		t.Fatal("wrong result:", indirectNodes)
  1180  	}
  1181  	fmt.Println("OK")
  1182  
  1183  	gs1 := &testMonitor{
  1184  		v: make(chan interface{}, 2),
  1185  	}
  1186  	gs2 := &testMonitor{
  1187  		v: make(chan interface{}, 2),
  1188  	}
  1189  
  1190  	fmt.Printf("    wait for start of gs1 on %#v: ", node1.Name())
  1191  	node1gs1, _ := node1.Spawn("gs1", gen.ProcessOptions{}, gs1, nil)
  1192  	waitForResultWithValue(t, gs1.v, node1gs1.Self())
  1193  
  1194  	node1gs1.SetCompression(true)
  1195  
  1196  	fmt.Printf("    wait for start of gs2 on %#v: ", node2.Name())
  1197  	node2gs2, _ := node2.Spawn("gs2", gen.ProcessOptions{}, gs2, nil)
  1198  	waitForResultWithValue(t, gs2.v, node2gs2.Self())
  1199  
  1200  	atoms2K := make(etf.List, 2100)
  1201  	s := lib.RandomString(240)
  1202  	for i := range atoms2K {
  1203  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i))
  1204  	}
  1205  
  1206  	long := make([]byte, 66*1024)
  1207  	for i := range long {
  1208  		long[i] = byte(i % 255)
  1209  	}
  1210  
  1211  	fmt.Printf("case 1: sending 2.1K atoms: ")
  1212  	rand.Shuffle(len(atoms2K), func(i, j int) {
  1213  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
  1214  	})
  1215  	for i := 0; i < 10; i++ {
  1216  		result := atoms2K
  1217  		node1gs1.Send(node2gs2.Self(), result)
  1218  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
  1219  			t.Fatal(err)
  1220  		}
  1221  	}
  1222  	fmt.Println("OK")
  1223  	fmt.Printf("case 2: sending a tuple with 2.1K atoms and 66K binary: ")
  1224  	rand.Shuffle(len(atoms2K), func(i, j int) {
  1225  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
  1226  	})
  1227  	for i := 0; i < 10; i++ {
  1228  		result := etf.Tuple{atoms2K, long}
  1229  		node1gs1.Send(node2gs2.Self(), result)
  1230  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
  1231  			t.Fatal(err)
  1232  		}
  1233  	}
  1234  	fmt.Println("OK")
  1235  
  1236  	fmt.Printf("case 3: sending 2.1K UTF-8 long atoms: ")
  1237  	s = strings.Repeat("🚀", 252)
  1238  	for i := range atoms2K {
  1239  		atoms2K[i] = etf.Atom(fmt.Sprintf("%s%d", s, i/10))
  1240  	}
  1241  	rand.Shuffle(len(atoms2K), func(i, j int) {
  1242  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
  1243  	})
  1244  	for i := 0; i < 10; i++ {
  1245  		result := atoms2K
  1246  		node1gs1.Send(node2gs2.Self(), result)
  1247  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
  1248  			t.Fatal(err)
  1249  		}
  1250  	}
  1251  	fmt.Println("OK")
  1252  	fmt.Printf("case 4: sending a tuple with 2.1K UTF-8 long atoms and 66K binary: ")
  1253  	rand.Shuffle(len(atoms2K), func(i, j int) {
  1254  		atoms2K[i], atoms2K[j] = atoms2K[j], atoms2K[i]
  1255  	})
  1256  	for i := 0; i < 10; i++ {
  1257  		result := etf.Tuple{atoms2K, long}
  1258  		node1gs1.Send(node2gs2.Self(), result)
  1259  		if err := waitForResultWithValueReturnError(t, gs2.v, result); err != nil {
  1260  			t.Fatal(err)
  1261  		}
  1262  	}
  1263  	fmt.Println("OK")
  1264  }