go-micro.dev/v5@v5.12.0/store/nats-js-kv/helpers_test.go (about) 1 package natsjskv 2 3 import ( 4 "context" 5 "fmt" 6 "net" 7 "os" 8 "path/filepath" 9 "strconv" 10 "strings" 11 "testing" 12 "time" 13 14 nserver "github.com/nats-io/nats-server/v2/server" 15 "github.com/pkg/errors" 16 "github.com/test-go/testify/require" 17 "go-micro.dev/v5/store" 18 ) 19 20 func testSetup(ctx context.Context, t *testing.T, opts ...store.Option) store.Store { 21 t.Helper() 22 23 var err error 24 var s store.Store 25 for i := 0; i < 5; i++ { 26 nCtx, cancel := context.WithCancel(ctx) 27 addr := startNatsServer(nCtx, t) 28 29 opts = append(opts, store.Nodes(addr), EncodeKeys()) 30 s = NewStore(opts...) 31 32 err = s.Init() 33 if err != nil { 34 t.Log(errors.Wrap(err, "Error: Server initialization failed, restarting server")) 35 cancel() 36 if err = s.Close(); err != nil { 37 t.Logf("Failed to close store: %v", err) 38 } 39 time.Sleep(time.Second) 40 continue 41 } 42 43 go func() { 44 <-ctx.Done() 45 cancel() 46 if err = s.Close(); err != nil { 47 t.Logf("Failed to close store: %v", err) 48 } 49 }() 50 51 return s 52 } 53 t.Error(errors.Wrap(err, "Store initialization failed")) 54 return s 55 } 56 57 func startNatsServer(ctx context.Context, t *testing.T) string { 58 t.Helper() 59 natsAddr := getFreeLocalhostAddress() 60 natsPort, err := strconv.Atoi(strings.Split(natsAddr, ":")[1]) 61 if err != nil { 62 t.Logf("Failed to parse port from address: %v", err) 63 } 64 65 clusterName := "gomicro-store-test-cluster" 66 67 // start the NATS with JetStream server 68 go natsServer(ctx, 69 t, 70 &nserver.Options{ 71 Host: strings.Split(natsAddr, ":")[0], 72 Port: natsPort, 73 Cluster: nserver.ClusterOpts{ 74 Name: clusterName, 75 }, 76 }, 77 ) 78 79 time.Sleep(2 * time.Second) 80 81 return natsAddr 82 } 83 84 func getFreeLocalhostAddress() string { 85 l, err := net.Listen("tcp", "127.0.0.1:0") 86 if err != nil { 87 return "" 88 } 89 90 addr := l.Addr().String() 91 if err := l.Close(); err != nil { 92 return addr 93 } 94 return addr 95 } 96 97 func natsServer(ctx context.Context, t *testing.T, opts *nserver.Options) { 98 t.Helper() 99 100 opts.TLSTimeout = 180 101 server, err := nserver.NewServer( 102 opts, 103 ) 104 require.NoError(t, err) 105 if err != nil { 106 return 107 } 108 defer server.Shutdown() 109 110 server.SetLoggerV2( 111 NewLogWrapper(), 112 false, false, false, 113 ) 114 115 tmpdir := t.TempDir() 116 natsdir := filepath.Join(tmpdir, "nats-js") 117 jsConf := &nserver.JetStreamConfig{ 118 StoreDir: natsdir, 119 } 120 121 // first start NATS 122 go server.Start() 123 time.Sleep(time.Second) 124 125 // second start JetStream 126 err = server.EnableJetStream(jsConf) 127 require.NoError(t, err) 128 if err != nil { 129 return 130 } 131 132 // This fixes some issues where tests fail because directory cleanup fails 133 t.Cleanup(func() { 134 contents, err := filepath.Glob(natsdir + "/*") 135 if err != nil { 136 t.Logf("Failed to glob directory: %v", err) 137 } 138 for _, item := range contents { 139 if err := os.RemoveAll(item); err != nil { 140 t.Logf("Failed to remove file: %v", err) 141 } 142 } 143 if err := os.RemoveAll(natsdir); err != nil { 144 t.Logf("Failed to remove directory: %v", err) 145 } 146 }) 147 148 <-ctx.Done() 149 } 150 151 func NewLogWrapper() *LogWrapper { 152 return &LogWrapper{} 153 } 154 155 type LogWrapper struct { 156 } 157 158 // Noticef logs a notice statement. 159 func (l *LogWrapper) Noticef(_ string, _ ...interface{}) { 160 } 161 162 // Warnf logs a warning statement. 163 func (l *LogWrapper) Warnf(format string, v ...interface{}) { 164 fmt.Printf(format+"\n", v...) 165 } 166 167 // Fatalf logs a fatal statement. 168 func (l *LogWrapper) Fatalf(format string, v ...interface{}) { 169 fmt.Printf(format+"\n", v...) 170 } 171 172 // Errorf logs an error statement. 173 func (l *LogWrapper) Errorf(format string, v ...interface{}) { 174 fmt.Printf(format+"\n", v...) 175 } 176 177 // Debugf logs a debug statement. 178 func (l *LogWrapper) Debugf(_ string, _ ...interface{}) { 179 } 180 181 // Tracef logs a trace statement. 182 func (l *LogWrapper) Tracef(format string, v ...interface{}) { 183 fmt.Printf(format+"\n", v...) 184 }