github.com/nsqio/nsq@v1.3.0/nsqlookupd/http_test.go (about)

     1  package nsqlookupd
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"net/http"
     8  	"os"
     9  	"strconv"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/nsqio/nsq/internal/test"
    14  	"github.com/nsqio/nsq/internal/version"
    15  	"github.com/nsqio/nsq/nsqd"
    16  )
    17  
    18  type InfoDoc struct {
    19  	Version string `json:"version"`
    20  }
    21  
    22  type ChannelsDoc struct {
    23  	Channels []interface{} `json:"channels"`
    24  }
    25  
    26  type ErrMessage struct {
    27  	Message string `json:"message"`
    28  }
    29  
    30  func bootstrapNSQCluster(t *testing.T) (string, []*nsqd.NSQD, *NSQLookupd) {
    31  	lgr := test.NewTestLogger(t)
    32  
    33  	nsqlookupdOpts := NewOptions()
    34  	nsqlookupdOpts.TCPAddress = "127.0.0.1:0"
    35  	nsqlookupdOpts.HTTPAddress = "127.0.0.1:0"
    36  	nsqlookupdOpts.BroadcastAddress = "127.0.0.1"
    37  	nsqlookupdOpts.Logger = lgr
    38  	nsqlookupd1, err := New(nsqlookupdOpts)
    39  	if err != nil {
    40  		panic(err)
    41  	}
    42  	go func() {
    43  		err := nsqlookupd1.Main()
    44  		if err != nil {
    45  			panic(err)
    46  		}
    47  	}()
    48  
    49  	time.Sleep(100 * time.Millisecond)
    50  
    51  	nsqdOpts := nsqd.NewOptions()
    52  	nsqdOpts.TCPAddress = "127.0.0.1:0"
    53  	nsqdOpts.HTTPAddress = "127.0.0.1:0"
    54  	nsqdOpts.BroadcastAddress = "127.0.0.1"
    55  	nsqdOpts.NSQLookupdTCPAddresses = []string{nsqlookupd1.RealTCPAddr().String()}
    56  	nsqdOpts.Logger = lgr
    57  	tmpDir, err := os.MkdirTemp("", fmt.Sprintf("nsq-test-%d", time.Now().UnixNano()))
    58  	if err != nil {
    59  		panic(err)
    60  	}
    61  	nsqdOpts.DataPath = tmpDir
    62  	nsqd1, err := nsqd.New(nsqdOpts)
    63  	if err != nil {
    64  		panic(err)
    65  	}
    66  	go func() {
    67  		err := nsqd1.Main()
    68  		if err != nil {
    69  			panic(err)
    70  		}
    71  	}()
    72  
    73  	time.Sleep(100 * time.Millisecond)
    74  
    75  	return tmpDir, []*nsqd.NSQD{nsqd1}, nsqlookupd1
    76  }
    77  
    78  func makeTopic(nsqlookupd *NSQLookupd, topicName string) {
    79  	key := Registration{"topic", topicName, ""}
    80  	nsqlookupd.DB.AddRegistration(key)
    81  }
    82  
    83  func makeChannel(nsqlookupd *NSQLookupd, topicName string, channelName string) {
    84  	key := Registration{"channel", topicName, channelName}
    85  	nsqlookupd.DB.AddRegistration(key)
    86  	makeTopic(nsqlookupd, topicName)
    87  }
    88  
    89  func TestPing(t *testing.T) {
    90  	dataPath, nsqds, nsqlookupd1 := bootstrapNSQCluster(t)
    91  	defer os.RemoveAll(dataPath)
    92  	defer nsqds[0].Exit()
    93  	defer nsqlookupd1.Exit()
    94  
    95  	client := http.Client{}
    96  	url := fmt.Sprintf("http://%s/ping", nsqlookupd1.RealHTTPAddr())
    97  	req, _ := http.NewRequest("GET", url, nil)
    98  	resp, err := client.Do(req)
    99  	test.Nil(t, err)
   100  	test.Equal(t, 200, resp.StatusCode)
   101  	body, _ := io.ReadAll(resp.Body)
   102  	resp.Body.Close()
   103  
   104  	test.Equal(t, []byte("OK"), body)
   105  }
   106  
   107  func TestInfo(t *testing.T) {
   108  	dataPath, nsqds, nsqlookupd1 := bootstrapNSQCluster(t)
   109  	defer os.RemoveAll(dataPath)
   110  	defer nsqds[0].Exit()
   111  	defer nsqlookupd1.Exit()
   112  
   113  	client := http.Client{}
   114  	url := fmt.Sprintf("http://%s/info", nsqlookupd1.RealHTTPAddr())
   115  	req, _ := http.NewRequest("GET", url, nil)
   116  	resp, err := client.Do(req)
   117  	test.Nil(t, err)
   118  	test.Equal(t, 200, resp.StatusCode)
   119  	body, _ := io.ReadAll(resp.Body)
   120  	resp.Body.Close()
   121  
   122  	t.Logf("%s", body)
   123  	info := InfoDoc{}
   124  	err = json.Unmarshal(body, &info)
   125  	test.Nil(t, err)
   126  	test.Equal(t, version.Binary, info.Version)
   127  }
   128  
   129  func TestCreateTopic(t *testing.T) {
   130  	dataPath, nsqds, nsqlookupd1 := bootstrapNSQCluster(t)
   131  	defer os.RemoveAll(dataPath)
   132  	defer nsqds[0].Exit()
   133  	defer nsqlookupd1.Exit()
   134  
   135  	em := ErrMessage{}
   136  	client := http.Client{}
   137  	url := fmt.Sprintf("http://%s/topic/create", nsqlookupd1.RealHTTPAddr())
   138  
   139  	req, _ := http.NewRequest("POST", url, nil)
   140  	resp, err := client.Do(req)
   141  	test.Nil(t, err)
   142  	test.Equal(t, 400, resp.StatusCode)
   143  	test.Equal(t, "Bad Request", http.StatusText(resp.StatusCode))
   144  	body, _ := io.ReadAll(resp.Body)
   145  	resp.Body.Close()
   146  
   147  	t.Logf("%s", body)
   148  	err = json.Unmarshal(body, &em)
   149  	test.Nil(t, err)
   150  	test.Equal(t, "MISSING_ARG_TOPIC", em.Message)
   151  
   152  	topicName := "sampletopicA" + strconv.Itoa(int(time.Now().Unix())) + "$"
   153  	url = fmt.Sprintf("http://%s/topic/create?topic=%s", nsqlookupd1.RealHTTPAddr(), topicName)
   154  
   155  	req, _ = http.NewRequest("POST", url, nil)
   156  	resp, err = client.Do(req)
   157  	test.Nil(t, err)
   158  	test.Equal(t, 400, resp.StatusCode)
   159  	test.Equal(t, "Bad Request", http.StatusText(resp.StatusCode))
   160  	body, _ = io.ReadAll(resp.Body)
   161  	resp.Body.Close()
   162  
   163  	t.Logf("%s", body)
   164  	err = json.Unmarshal(body, &em)
   165  	test.Nil(t, err)
   166  	test.Equal(t, "INVALID_ARG_TOPIC", em.Message)
   167  
   168  	topicName = "sampletopicA" + strconv.Itoa(int(time.Now().Unix()))
   169  	url = fmt.Sprintf("http://%s/topic/create?topic=%s", nsqlookupd1.RealHTTPAddr(), topicName)
   170  
   171  	req, _ = http.NewRequest("POST", url, nil)
   172  	resp, err = client.Do(req)
   173  	test.Nil(t, err)
   174  	test.Equal(t, 200, resp.StatusCode)
   175  	body, _ = io.ReadAll(resp.Body)
   176  	resp.Body.Close()
   177  
   178  	t.Logf("%s", body)
   179  	test.Equal(t, []byte(""), body)
   180  }
   181  
   182  func TestDeleteTopic(t *testing.T) {
   183  	dataPath, nsqds, nsqlookupd1 := bootstrapNSQCluster(t)
   184  	defer os.RemoveAll(dataPath)
   185  	defer nsqds[0].Exit()
   186  	defer nsqlookupd1.Exit()
   187  
   188  	em := ErrMessage{}
   189  	client := http.Client{}
   190  	url := fmt.Sprintf("http://%s/topic/delete", nsqlookupd1.RealHTTPAddr())
   191  
   192  	req, _ := http.NewRequest("POST", url, nil)
   193  	resp, err := client.Do(req)
   194  	test.Nil(t, err)
   195  	test.Equal(t, 400, resp.StatusCode)
   196  	test.Equal(t, "Bad Request", http.StatusText(resp.StatusCode))
   197  	body, _ := io.ReadAll(resp.Body)
   198  	resp.Body.Close()
   199  
   200  	t.Logf("%s", body)
   201  	err = json.Unmarshal(body, &em)
   202  	test.Nil(t, err)
   203  	test.Equal(t, "MISSING_ARG_TOPIC", em.Message)
   204  
   205  	topicName := "sampletopicA" + strconv.Itoa(int(time.Now().Unix()))
   206  	makeTopic(nsqlookupd1, topicName)
   207  
   208  	url = fmt.Sprintf("http://%s/topic/delete?topic=%s", nsqlookupd1.RealHTTPAddr(), topicName)
   209  
   210  	req, _ = http.NewRequest("POST", url, nil)
   211  	resp, err = client.Do(req)
   212  	test.Nil(t, err)
   213  	test.Equal(t, 200, resp.StatusCode)
   214  	body, _ = io.ReadAll(resp.Body)
   215  	resp.Body.Close()
   216  
   217  	t.Logf("%s", body)
   218  	test.Equal(t, []byte(""), body)
   219  
   220  	topicName = "sampletopicB" + strconv.Itoa(int(time.Now().Unix()))
   221  	channelName := "foobar" + strconv.Itoa(int(time.Now().Unix()))
   222  	makeChannel(nsqlookupd1, topicName, channelName)
   223  
   224  	url = fmt.Sprintf("http://%s/topic/delete?topic=%s", nsqlookupd1.RealHTTPAddr(), topicName)
   225  
   226  	req, _ = http.NewRequest("POST", url, nil)
   227  	resp, err = client.Do(req)
   228  	test.Nil(t, err)
   229  	test.Equal(t, 200, resp.StatusCode)
   230  	body, _ = io.ReadAll(resp.Body)
   231  	resp.Body.Close()
   232  
   233  	t.Logf("%s", body)
   234  	test.Equal(t, []byte(""), body)
   235  }
   236  
   237  func TestGetChannels(t *testing.T) {
   238  	dataPath, nsqds, nsqlookupd1 := bootstrapNSQCluster(t)
   239  	defer os.RemoveAll(dataPath)
   240  	defer nsqds[0].Exit()
   241  	defer nsqlookupd1.Exit()
   242  
   243  	client := http.Client{}
   244  	url := fmt.Sprintf("http://%s/channels", nsqlookupd1.RealHTTPAddr())
   245  
   246  	em := ErrMessage{}
   247  	req, _ := http.NewRequest("GET", url, nil)
   248  	req.Header.Add("Accept", "application/vnd.nsq; version=1.0")
   249  	resp, err := client.Do(req)
   250  	test.Nil(t, err)
   251  	test.Equal(t, 400, resp.StatusCode)
   252  	test.Equal(t, "Bad Request", http.StatusText(resp.StatusCode))
   253  	body, _ := io.ReadAll(resp.Body)
   254  	resp.Body.Close()
   255  
   256  	t.Logf("%s", body)
   257  	err = json.Unmarshal(body, &em)
   258  	test.Nil(t, err)
   259  	test.Equal(t, "MISSING_ARG_TOPIC", em.Message)
   260  
   261  	ch := ChannelsDoc{}
   262  	topicName := "sampletopicA" + strconv.Itoa(int(time.Now().Unix()))
   263  	makeTopic(nsqlookupd1, topicName)
   264  
   265  	url = fmt.Sprintf("http://%s/channels?topic=%s", nsqlookupd1.RealHTTPAddr(), topicName)
   266  
   267  	req, _ = http.NewRequest("GET", url, nil)
   268  	req.Header.Add("Accept", "application/vnd.nsq; version=1.0")
   269  	resp, err = client.Do(req)
   270  	test.Nil(t, err)
   271  	test.Equal(t, 200, resp.StatusCode)
   272  	body, _ = io.ReadAll(resp.Body)
   273  	resp.Body.Close()
   274  
   275  	t.Logf("%s", body)
   276  	err = json.Unmarshal(body, &ch)
   277  	test.Nil(t, err)
   278  	test.Equal(t, 0, len(ch.Channels))
   279  
   280  	topicName = "sampletopicB" + strconv.Itoa(int(time.Now().Unix()))
   281  	channelName := "foobar" + strconv.Itoa(int(time.Now().Unix()))
   282  	makeChannel(nsqlookupd1, topicName, channelName)
   283  
   284  	url = fmt.Sprintf("http://%s/channels?topic=%s", nsqlookupd1.RealHTTPAddr(), topicName)
   285  
   286  	req, _ = http.NewRequest("GET", url, nil)
   287  	req.Header.Add("Accept", "application/vnd.nsq; version=1.0")
   288  	resp, err = client.Do(req)
   289  	test.Nil(t, err)
   290  	test.Equal(t, 200, resp.StatusCode)
   291  	body, _ = io.ReadAll(resp.Body)
   292  	resp.Body.Close()
   293  
   294  	t.Logf("%s", body)
   295  	err = json.Unmarshal(body, &ch)
   296  	test.Nil(t, err)
   297  	test.Equal(t, 1, len(ch.Channels))
   298  	test.Equal(t, channelName, ch.Channels[0])
   299  }
   300  
   301  func TestCreateChannel(t *testing.T) {
   302  	dataPath, nsqds, nsqlookupd1 := bootstrapNSQCluster(t)
   303  	defer os.RemoveAll(dataPath)
   304  	defer nsqds[0].Exit()
   305  	defer nsqlookupd1.Exit()
   306  
   307  	em := ErrMessage{}
   308  	client := http.Client{}
   309  	url := fmt.Sprintf("http://%s/channel/create", nsqlookupd1.RealHTTPAddr())
   310  
   311  	req, _ := http.NewRequest("POST", url, nil)
   312  	resp, err := client.Do(req)
   313  	test.Nil(t, err)
   314  	test.Equal(t, 400, resp.StatusCode)
   315  	test.Equal(t, "Bad Request", http.StatusText(resp.StatusCode))
   316  	body, _ := io.ReadAll(resp.Body)
   317  	resp.Body.Close()
   318  
   319  	t.Logf("%s", body)
   320  	err = json.Unmarshal(body, &em)
   321  	test.Nil(t, err)
   322  	test.Equal(t, "MISSING_ARG_TOPIC", em.Message)
   323  
   324  	topicName := "sampletopicB" + strconv.Itoa(int(time.Now().Unix())) + "$"
   325  	url = fmt.Sprintf("http://%s/channel/create?topic=%s", nsqlookupd1.RealHTTPAddr(), topicName)
   326  
   327  	req, _ = http.NewRequest("POST", url, nil)
   328  	resp, err = client.Do(req)
   329  	test.Nil(t, err)
   330  	test.Equal(t, 400, resp.StatusCode)
   331  	test.Equal(t, "Bad Request", http.StatusText(resp.StatusCode))
   332  	body, _ = io.ReadAll(resp.Body)
   333  	resp.Body.Close()
   334  
   335  	t.Logf("%s", body)
   336  	err = json.Unmarshal(body, &em)
   337  	test.Nil(t, err)
   338  	test.Equal(t, "INVALID_ARG_TOPIC", em.Message)
   339  
   340  	topicName = "sampletopicB" + strconv.Itoa(int(time.Now().Unix()))
   341  	url = fmt.Sprintf("http://%s/channel/create?topic=%s", nsqlookupd1.RealHTTPAddr(), topicName)
   342  
   343  	req, _ = http.NewRequest("POST", url, nil)
   344  	resp, err = client.Do(req)
   345  	test.Nil(t, err)
   346  	test.Equal(t, 400, resp.StatusCode)
   347  	test.Equal(t, "Bad Request", http.StatusText(resp.StatusCode))
   348  	body, _ = io.ReadAll(resp.Body)
   349  	resp.Body.Close()
   350  
   351  	t.Logf("%s", body)
   352  	err = json.Unmarshal(body, &em)
   353  	test.Nil(t, err)
   354  	test.Equal(t, "MISSING_ARG_CHANNEL", em.Message)
   355  
   356  	channelName := "foobar" + strconv.Itoa(int(time.Now().Unix())) + "$"
   357  	url = fmt.Sprintf("http://%s/channel/create?topic=%s&channel=%s", nsqlookupd1.RealHTTPAddr(), topicName, channelName)
   358  
   359  	req, _ = http.NewRequest("POST", url, nil)
   360  	resp, err = client.Do(req)
   361  	test.Nil(t, err)
   362  	test.Equal(t, 400, resp.StatusCode)
   363  	test.Equal(t, "Bad Request", http.StatusText(resp.StatusCode))
   364  	body, _ = io.ReadAll(resp.Body)
   365  	resp.Body.Close()
   366  
   367  	t.Logf("%s", body)
   368  	err = json.Unmarshal(body, &em)
   369  	test.Nil(t, err)
   370  	test.Equal(t, "INVALID_ARG_CHANNEL", em.Message)
   371  
   372  	channelName = "foobar" + strconv.Itoa(int(time.Now().Unix()))
   373  	url = fmt.Sprintf("http://%s/channel/create?topic=%s&channel=%s", nsqlookupd1.RealHTTPAddr(), topicName, channelName)
   374  
   375  	req, _ = http.NewRequest("POST", url, nil)
   376  	resp, err = client.Do(req)
   377  	test.Nil(t, err)
   378  	test.Equal(t, 200, resp.StatusCode)
   379  	body, _ = io.ReadAll(resp.Body)
   380  	resp.Body.Close()
   381  
   382  	t.Logf("%s", body)
   383  	test.Equal(t, []byte(""), body)
   384  }
   385  
   386  func TestDeleteChannel(t *testing.T) {
   387  	dataPath, nsqds, nsqlookupd1 := bootstrapNSQCluster(t)
   388  	defer os.RemoveAll(dataPath)
   389  	defer nsqds[0].Exit()
   390  	defer nsqlookupd1.Exit()
   391  
   392  	em := ErrMessage{}
   393  	client := http.Client{}
   394  	url := fmt.Sprintf("http://%s/channel/delete", nsqlookupd1.RealHTTPAddr())
   395  
   396  	req, _ := http.NewRequest("POST", url, nil)
   397  	resp, err := client.Do(req)
   398  	test.Nil(t, err)
   399  	test.Equal(t, 400, resp.StatusCode)
   400  	test.Equal(t, "Bad Request", http.StatusText(resp.StatusCode))
   401  	body, _ := io.ReadAll(resp.Body)
   402  	resp.Body.Close()
   403  
   404  	t.Logf("%s", body)
   405  	err = json.Unmarshal(body, &em)
   406  	test.Nil(t, err)
   407  	test.Equal(t, "MISSING_ARG_TOPIC", em.Message)
   408  
   409  	topicName := "sampletopicB" + strconv.Itoa(int(time.Now().Unix())) + "$"
   410  	url = fmt.Sprintf("http://%s/channel/delete?topic=%s", nsqlookupd1.RealHTTPAddr(), topicName)
   411  
   412  	req, _ = http.NewRequest("POST", url, nil)
   413  	resp, err = client.Do(req)
   414  	test.Nil(t, err)
   415  	test.Equal(t, 400, resp.StatusCode)
   416  	test.Equal(t, "Bad Request", http.StatusText(resp.StatusCode))
   417  	body, _ = io.ReadAll(resp.Body)
   418  	resp.Body.Close()
   419  
   420  	t.Logf("%s", body)
   421  	err = json.Unmarshal(body, &em)
   422  	test.Nil(t, err)
   423  	test.Equal(t, "INVALID_ARG_TOPIC", em.Message)
   424  
   425  	topicName = "sampletopicB" + strconv.Itoa(int(time.Now().Unix()))
   426  	url = fmt.Sprintf("http://%s/channel/delete?topic=%s", nsqlookupd1.RealHTTPAddr(), topicName)
   427  
   428  	req, _ = http.NewRequest("POST", url, nil)
   429  	resp, err = client.Do(req)
   430  	test.Nil(t, err)
   431  	test.Equal(t, 400, resp.StatusCode)
   432  	test.Equal(t, "Bad Request", http.StatusText(resp.StatusCode))
   433  	body, _ = io.ReadAll(resp.Body)
   434  	resp.Body.Close()
   435  
   436  	t.Logf("%s", body)
   437  	err = json.Unmarshal(body, &em)
   438  	test.Nil(t, err)
   439  	test.Equal(t, "MISSING_ARG_CHANNEL", em.Message)
   440  
   441  	channelName := "foobar" + strconv.Itoa(int(time.Now().Unix())) + "$"
   442  	url = fmt.Sprintf("http://%s/channel/delete?topic=%s&channel=%s", nsqlookupd1.RealHTTPAddr(), topicName, channelName)
   443  
   444  	req, _ = http.NewRequest("POST", url, nil)
   445  	resp, err = client.Do(req)
   446  	test.Nil(t, err)
   447  	test.Equal(t, 400, resp.StatusCode)
   448  	test.Equal(t, "Bad Request", http.StatusText(resp.StatusCode))
   449  	body, _ = io.ReadAll(resp.Body)
   450  	resp.Body.Close()
   451  
   452  	t.Logf("%s", body)
   453  	err = json.Unmarshal(body, &em)
   454  	test.Nil(t, err)
   455  	test.Equal(t, "INVALID_ARG_CHANNEL", em.Message)
   456  
   457  	channelName = "foobar" + strconv.Itoa(int(time.Now().Unix()))
   458  	url = fmt.Sprintf("http://%s/channel/delete?topic=%s&channel=%s", nsqlookupd1.RealHTTPAddr(), topicName, channelName)
   459  
   460  	req, _ = http.NewRequest("POST", url, nil)
   461  	resp, err = client.Do(req)
   462  	test.Nil(t, err)
   463  	test.Equal(t, 404, resp.StatusCode)
   464  	test.Equal(t, "Not Found", http.StatusText(resp.StatusCode))
   465  	body, _ = io.ReadAll(resp.Body)
   466  	resp.Body.Close()
   467  
   468  	t.Logf("%s", body)
   469  	err = json.Unmarshal(body, &em)
   470  	test.Nil(t, err)
   471  	test.Equal(t, "CHANNEL_NOT_FOUND", em.Message)
   472  
   473  	makeChannel(nsqlookupd1, topicName, channelName)
   474  
   475  	req, _ = http.NewRequest("POST", url, nil)
   476  	resp, err = client.Do(req)
   477  	test.Nil(t, err)
   478  	test.Equal(t, 200, resp.StatusCode)
   479  	body, _ = io.ReadAll(resp.Body)
   480  	resp.Body.Close()
   481  
   482  	t.Logf("%s", body)
   483  	test.Equal(t, []byte(""), body)
   484  }