github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/registry/memory/memory_test.go (about)

     1  package memory
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/volts-dev/volts/registry"
    10  )
    11  
    12  var (
    13  	testData = map[string][]*registry.Service{
    14  		"foo": {
    15  			{
    16  				Name:    "foo",
    17  				Version: "1.0.0",
    18  				Nodes: []*registry.Node{
    19  					{
    20  						Id:      "foo-1.0.0-123",
    21  						Address: "localhost:9999",
    22  					},
    23  					{
    24  						Id:      "foo-1.0.0-321",
    25  						Address: "localhost:9999",
    26  					},
    27  				},
    28  			},
    29  			{
    30  				Name:    "foo",
    31  				Version: "1.0.1",
    32  				Nodes: []*registry.Node{
    33  					{
    34  						Id:      "foo-1.0.1-321",
    35  						Address: "localhost:6666",
    36  					},
    37  				},
    38  			},
    39  			{
    40  				Name:    "foo",
    41  				Version: "1.0.3",
    42  				Nodes: []*registry.Node{
    43  					{
    44  						Id:      "foo-1.0.3-345",
    45  						Address: "localhost:8888",
    46  					},
    47  				},
    48  			},
    49  		},
    50  		"bar": {
    51  			{
    52  				Name:    "bar",
    53  				Version: "default",
    54  				Nodes: []*registry.Node{
    55  					{
    56  						Id:      "bar-1.0.0-123",
    57  						Address: "localhost:9999",
    58  					},
    59  					{
    60  						Id:      "bar-1.0.0-321",
    61  						Address: "localhost:9999",
    62  					},
    63  				},
    64  			},
    65  			{
    66  				Name:    "bar",
    67  				Version: "latest",
    68  				Nodes: []*registry.Node{
    69  					{
    70  						Id:      "bar-1.0.1-321",
    71  						Address: "localhost:6666",
    72  					},
    73  				},
    74  			},
    75  		},
    76  	}
    77  )
    78  
    79  func TestMemoryRegistry(t *testing.T) {
    80  	m := New()
    81  
    82  	fn := func(k string, v []*registry.Service) {
    83  		services, err := m.GetService(k)
    84  		if err != nil {
    85  			t.Errorf("Unexpected error getting service %s: %v", k, err)
    86  		}
    87  
    88  		if len(services) != len(v) {
    89  			t.Errorf("Expected %d services for %s, got %d", len(v), k, len(services))
    90  		}
    91  
    92  		for _, service := range v {
    93  			var seen bool
    94  			for _, s := range services {
    95  				if s.Version == service.Version {
    96  					seen = true
    97  					break
    98  				}
    99  			}
   100  			if !seen {
   101  				t.Errorf("expected to find version %s", service.Version)
   102  			}
   103  		}
   104  	}
   105  
   106  	// register data
   107  	for _, v := range testData {
   108  		serviceCount := 0
   109  		for _, service := range v {
   110  			if err := m.Register(service); err != nil {
   111  				t.Errorf("Unexpected register error: %v", err)
   112  			}
   113  			serviceCount++
   114  			// after the service has been registered we should be able to query it
   115  			services, err := m.GetService(service.Name)
   116  			if err != nil {
   117  				t.Errorf("Unexpected error getting service %s: %v", service.Name, err)
   118  			}
   119  			if len(services) != serviceCount {
   120  				t.Errorf("Expected %d services for %s, got %d", serviceCount, service.Name, len(services))
   121  			}
   122  		}
   123  	}
   124  
   125  	// using test data
   126  	for k, v := range testData {
   127  		fn(k, v)
   128  	}
   129  
   130  	services, err := m.ListServices()
   131  	if err != nil {
   132  		t.Errorf("Unexpected error when listing services: %v", err)
   133  	}
   134  
   135  	totalServiceCount := 0
   136  	for _, testSvc := range testData {
   137  		for range testSvc {
   138  			totalServiceCount++
   139  		}
   140  	}
   141  
   142  	if len(services) != totalServiceCount {
   143  		t.Errorf("Expected total service count: %d, got: %d", totalServiceCount, len(services))
   144  	}
   145  
   146  	// deregister
   147  	for _, v := range testData {
   148  		for _, service := range v {
   149  			if err := m.Deregister(service); err != nil {
   150  				t.Errorf("Unexpected deregister error: %v", err)
   151  			}
   152  		}
   153  	}
   154  
   155  	// after all the service nodes have been deregistered we should not get any results
   156  	for _, v := range testData {
   157  		for _, service := range v {
   158  			services, err := m.GetService(service.Name)
   159  			if err != registry.ErrNotFound {
   160  				t.Errorf("Expected error: %v, got: %v", registry.ErrNotFound, err)
   161  			}
   162  			if len(services) != 0 {
   163  				t.Errorf("Expected %d services for %s, got %d", 0, service.Name, len(services))
   164  			}
   165  		}
   166  	}
   167  }
   168  
   169  func TestMemoryRegistryTTL(t *testing.T) {
   170  	m := New()
   171  
   172  	for _, v := range testData {
   173  		for _, service := range v {
   174  			if err := m.Register(service, registry.RegisterTTL(time.Millisecond)); err != nil {
   175  				t.Fatal(err)
   176  			}
   177  		}
   178  	}
   179  
   180  	time.Sleep(ttlPruneTime * 2)
   181  
   182  	for name := range testData {
   183  		svcs, err := m.GetService(name)
   184  		if err != nil {
   185  			t.Fatal(err)
   186  		}
   187  
   188  		for _, svc := range svcs {
   189  			if len(svc.Nodes) > 0 {
   190  				t.Fatalf("Service %q still has nodes registered", name)
   191  			}
   192  		}
   193  	}
   194  }
   195  
   196  func TestMemoryRegistryTTLConcurrent(t *testing.T) {
   197  	concurrency := 1000
   198  	waitTime := ttlPruneTime * 2
   199  	m := New()
   200  
   201  	for _, v := range testData {
   202  		for _, service := range v {
   203  			if err := m.Register(service, registry.RegisterTTL(waitTime/2)); err != nil {
   204  				t.Fatal(err)
   205  			}
   206  		}
   207  	}
   208  
   209  	if len(os.Getenv("IN_TRAVIS_CI")) == 0 {
   210  		t.Logf("test will wait %v, then check TTL timeouts", waitTime)
   211  	}
   212  
   213  	errChan := make(chan error, concurrency)
   214  	syncChan := make(chan struct{})
   215  
   216  	for i := 0; i < concurrency; i++ {
   217  		go func() {
   218  			<-syncChan
   219  			for name := range testData {
   220  				svcs, err := m.GetService(name)
   221  				if err != nil {
   222  					errChan <- err
   223  					return
   224  				}
   225  
   226  				for _, svc := range svcs {
   227  					if len(svc.Nodes) > 0 {
   228  						errChan <- fmt.Errorf("Service %q still has nodes registered", name)
   229  						return
   230  					}
   231  				}
   232  			}
   233  
   234  			errChan <- nil
   235  		}()
   236  	}
   237  
   238  	time.Sleep(waitTime)
   239  	close(syncChan)
   240  
   241  	for i := 0; i < concurrency; i++ {
   242  		if err := <-errChan; err != nil {
   243  			t.Fatal(err)
   244  		}
   245  	}
   246  }