...

Source file src/github.com/gin-gonic/gin/githubapi_test.go

Documentation: github.com/gin-gonic/gin

     1  // Copyright 2014 Manu Martinez-Almeida. All rights reserved.
     2  // Use of this source code is governed by a MIT style
     3  // license that can be found in the LICENSE file.
     4  
     5  package gin
     6  
     7  import (
     8  	"fmt"
     9  	"math/rand"
    10  	"net/http"
    11  	"net/http/httptest"
    12  	"os"
    13  	"strings"
    14  	"testing"
    15  
    16  	"github.com/stretchr/testify/assert"
    17  )
    18  
    19  type route struct {
    20  	method string
    21  	path   string
    22  }
    23  
    24  // http://developer.github.com/v3/
    25  var githubAPI = []route{
    26  	// OAuth Authorizations
    27  	{http.MethodGet, "/authorizations"},
    28  	{http.MethodGet, "/authorizations/:id"},
    29  	{http.MethodPost, "/authorizations"},
    30  	//{http.MethodPut, "/authorizations/clients/:client_id"},
    31  	//{http.MethodPatch, "/authorizations/:id"},
    32  	{http.MethodDelete, "/authorizations/:id"},
    33  	{http.MethodGet, "/applications/:client_id/tokens/:access_token"},
    34  	{http.MethodDelete, "/applications/:client_id/tokens"},
    35  	{http.MethodDelete, "/applications/:client_id/tokens/:access_token"},
    36  
    37  	// Activity
    38  	{http.MethodGet, "/events"},
    39  	{http.MethodGet, "/repos/:owner/:repo/events"},
    40  	{http.MethodGet, "/networks/:owner/:repo/events"},
    41  	{http.MethodGet, "/orgs/:org/events"},
    42  	{http.MethodGet, "/users/:user/received_events"},
    43  	{http.MethodGet, "/users/:user/received_events/public"},
    44  	{http.MethodGet, "/users/:user/events"},
    45  	{http.MethodGet, "/users/:user/events/public"},
    46  	{http.MethodGet, "/users/:user/events/orgs/:org"},
    47  	{http.MethodGet, "/feeds"},
    48  	{http.MethodGet, "/notifications"},
    49  	{http.MethodGet, "/repos/:owner/:repo/notifications"},
    50  	{http.MethodPut, "/notifications"},
    51  	{http.MethodPut, "/repos/:owner/:repo/notifications"},
    52  	{http.MethodGet, "/notifications/threads/:id"},
    53  	//{http.MethodPatch, "/notifications/threads/:id"},
    54  	{http.MethodGet, "/notifications/threads/:id/subscription"},
    55  	{http.MethodPut, "/notifications/threads/:id/subscription"},
    56  	{http.MethodDelete, "/notifications/threads/:id/subscription"},
    57  	{http.MethodGet, "/repos/:owner/:repo/stargazers"},
    58  	{http.MethodGet, "/users/:user/starred"},
    59  	{http.MethodGet, "/user/starred"},
    60  	{http.MethodGet, "/user/starred/:owner/:repo"},
    61  	{http.MethodPut, "/user/starred/:owner/:repo"},
    62  	{http.MethodDelete, "/user/starred/:owner/:repo"},
    63  	{http.MethodGet, "/repos/:owner/:repo/subscribers"},
    64  	{http.MethodGet, "/users/:user/subscriptions"},
    65  	{http.MethodGet, "/user/subscriptions"},
    66  	{http.MethodGet, "/repos/:owner/:repo/subscription"},
    67  	{http.MethodPut, "/repos/:owner/:repo/subscription"},
    68  	{http.MethodDelete, "/repos/:owner/:repo/subscription"},
    69  	{http.MethodGet, "/user/subscriptions/:owner/:repo"},
    70  	{http.MethodPut, "/user/subscriptions/:owner/:repo"},
    71  	{http.MethodDelete, "/user/subscriptions/:owner/:repo"},
    72  
    73  	// Gists
    74  	{http.MethodGet, "/users/:user/gists"},
    75  	{http.MethodGet, "/gists"},
    76  	//{http.MethodGet, "/gists/public"},
    77  	//{http.MethodGet, "/gists/starred"},
    78  	{http.MethodGet, "/gists/:id"},
    79  	{http.MethodPost, "/gists"},
    80  	//{http.MethodPatch, "/gists/:id"},
    81  	{http.MethodPut, "/gists/:id/star"},
    82  	{http.MethodDelete, "/gists/:id/star"},
    83  	{http.MethodGet, "/gists/:id/star"},
    84  	{http.MethodPost, "/gists/:id/forks"},
    85  	{http.MethodDelete, "/gists/:id"},
    86  
    87  	// Git Data
    88  	{http.MethodGet, "/repos/:owner/:repo/git/blobs/:sha"},
    89  	{http.MethodPost, "/repos/:owner/:repo/git/blobs"},
    90  	{http.MethodGet, "/repos/:owner/:repo/git/commits/:sha"},
    91  	{http.MethodPost, "/repos/:owner/:repo/git/commits"},
    92  	//{http.MethodGet, "/repos/:owner/:repo/git/refs/*ref"},
    93  	{http.MethodGet, "/repos/:owner/:repo/git/refs"},
    94  	{http.MethodPost, "/repos/:owner/:repo/git/refs"},
    95  	//{http.MethodPatch, "/repos/:owner/:repo/git/refs/*ref"},
    96  	//{http.MethodDelete, "/repos/:owner/:repo/git/refs/*ref"},
    97  	{http.MethodGet, "/repos/:owner/:repo/git/tags/:sha"},
    98  	{http.MethodPost, "/repos/:owner/:repo/git/tags"},
    99  	{http.MethodGet, "/repos/:owner/:repo/git/trees/:sha"},
   100  	{http.MethodPost, "/repos/:owner/:repo/git/trees"},
   101  
   102  	// Issues
   103  	{http.MethodGet, "/issues"},
   104  	{http.MethodGet, "/user/issues"},
   105  	{http.MethodGet, "/orgs/:org/issues"},
   106  	{http.MethodGet, "/repos/:owner/:repo/issues"},
   107  	{http.MethodGet, "/repos/:owner/:repo/issues/:number"},
   108  	{http.MethodPost, "/repos/:owner/:repo/issues"},
   109  	//{http.MethodPatch, "/repos/:owner/:repo/issues/:number"},
   110  	{http.MethodGet, "/repos/:owner/:repo/assignees"},
   111  	{http.MethodGet, "/repos/:owner/:repo/assignees/:assignee"},
   112  	{http.MethodGet, "/repos/:owner/:repo/issues/:number/comments"},
   113  	//{http.MethodGet, "/repos/:owner/:repo/issues/comments"},
   114  	//{http.MethodGet, "/repos/:owner/:repo/issues/comments/:id"},
   115  	{http.MethodPost, "/repos/:owner/:repo/issues/:number/comments"},
   116  	//{http.MethodPatch, "/repos/:owner/:repo/issues/comments/:id"},
   117  	//{http.MethodDelete, "/repos/:owner/:repo/issues/comments/:id"},
   118  	{http.MethodGet, "/repos/:owner/:repo/issues/:number/events"},
   119  	//{http.MethodGet, "/repos/:owner/:repo/issues/events"},
   120  	//{http.MethodGet, "/repos/:owner/:repo/issues/events/:id"},
   121  	{http.MethodGet, "/repos/:owner/:repo/labels"},
   122  	{http.MethodGet, "/repos/:owner/:repo/labels/:name"},
   123  	{http.MethodPost, "/repos/:owner/:repo/labels"},
   124  	//{http.MethodPatch, "/repos/:owner/:repo/labels/:name"},
   125  	{http.MethodDelete, "/repos/:owner/:repo/labels/:name"},
   126  	{http.MethodGet, "/repos/:owner/:repo/issues/:number/labels"},
   127  	{http.MethodPost, "/repos/:owner/:repo/issues/:number/labels"},
   128  	{http.MethodDelete, "/repos/:owner/:repo/issues/:number/labels/:name"},
   129  	{http.MethodPut, "/repos/:owner/:repo/issues/:number/labels"},
   130  	{http.MethodDelete, "/repos/:owner/:repo/issues/:number/labels"},
   131  	{http.MethodGet, "/repos/:owner/:repo/milestones/:number/labels"},
   132  	{http.MethodGet, "/repos/:owner/:repo/milestones"},
   133  	{http.MethodGet, "/repos/:owner/:repo/milestones/:number"},
   134  	{http.MethodPost, "/repos/:owner/:repo/milestones"},
   135  	//{http.MethodPatch, "/repos/:owner/:repo/milestones/:number"},
   136  	{http.MethodDelete, "/repos/:owner/:repo/milestones/:number"},
   137  
   138  	// Miscellaneous
   139  	{http.MethodGet, "/emojis"},
   140  	{http.MethodGet, "/gitignore/templates"},
   141  	{http.MethodGet, "/gitignore/templates/:name"},
   142  	{http.MethodPost, "/markdown"},
   143  	{http.MethodPost, "/markdown/raw"},
   144  	{http.MethodGet, "/meta"},
   145  	{http.MethodGet, "/rate_limit"},
   146  
   147  	// Organizations
   148  	{http.MethodGet, "/users/:user/orgs"},
   149  	{http.MethodGet, "/user/orgs"},
   150  	{http.MethodGet, "/orgs/:org"},
   151  	//{http.MethodPatch, "/orgs/:org"},
   152  	{http.MethodGet, "/orgs/:org/members"},
   153  	{http.MethodGet, "/orgs/:org/members/:user"},
   154  	{http.MethodDelete, "/orgs/:org/members/:user"},
   155  	{http.MethodGet, "/orgs/:org/public_members"},
   156  	{http.MethodGet, "/orgs/:org/public_members/:user"},
   157  	{http.MethodPut, "/orgs/:org/public_members/:user"},
   158  	{http.MethodDelete, "/orgs/:org/public_members/:user"},
   159  	{http.MethodGet, "/orgs/:org/teams"},
   160  	{http.MethodGet, "/teams/:id"},
   161  	{http.MethodPost, "/orgs/:org/teams"},
   162  	//{http.MethodPatch, "/teams/:id"},
   163  	{http.MethodDelete, "/teams/:id"},
   164  	{http.MethodGet, "/teams/:id/members"},
   165  	{http.MethodGet, "/teams/:id/members/:user"},
   166  	{http.MethodPut, "/teams/:id/members/:user"},
   167  	{http.MethodDelete, "/teams/:id/members/:user"},
   168  	{http.MethodGet, "/teams/:id/repos"},
   169  	{http.MethodGet, "/teams/:id/repos/:owner/:repo"},
   170  	{http.MethodPut, "/teams/:id/repos/:owner/:repo"},
   171  	{http.MethodDelete, "/teams/:id/repos/:owner/:repo"},
   172  	{http.MethodGet, "/user/teams"},
   173  
   174  	// Pull Requests
   175  	{http.MethodGet, "/repos/:owner/:repo/pulls"},
   176  	{http.MethodGet, "/repos/:owner/:repo/pulls/:number"},
   177  	{http.MethodPost, "/repos/:owner/:repo/pulls"},
   178  	//{http.MethodPatch, "/repos/:owner/:repo/pulls/:number"},
   179  	{http.MethodGet, "/repos/:owner/:repo/pulls/:number/commits"},
   180  	{http.MethodGet, "/repos/:owner/:repo/pulls/:number/files"},
   181  	{http.MethodGet, "/repos/:owner/:repo/pulls/:number/merge"},
   182  	{http.MethodPut, "/repos/:owner/:repo/pulls/:number/merge"},
   183  	{http.MethodGet, "/repos/:owner/:repo/pulls/:number/comments"},
   184  	//{http.MethodGet, "/repos/:owner/:repo/pulls/comments"},
   185  	//{http.MethodGet, "/repos/:owner/:repo/pulls/comments/:number"},
   186  	{http.MethodPut, "/repos/:owner/:repo/pulls/:number/comments"},
   187  	//{http.MethodPatch, "/repos/:owner/:repo/pulls/comments/:number"},
   188  	//{http.MethodDelete, "/repos/:owner/:repo/pulls/comments/:number"},
   189  
   190  	// Repositories
   191  	{http.MethodGet, "/user/repos"},
   192  	{http.MethodGet, "/users/:user/repos"},
   193  	{http.MethodGet, "/orgs/:org/repos"},
   194  	{http.MethodGet, "/repositories"},
   195  	{http.MethodPost, "/user/repos"},
   196  	{http.MethodPost, "/orgs/:org/repos"},
   197  	{http.MethodGet, "/repos/:owner/:repo"},
   198  	//{http.MethodPatch, "/repos/:owner/:repo"},
   199  	{http.MethodGet, "/repos/:owner/:repo/contributors"},
   200  	{http.MethodGet, "/repos/:owner/:repo/languages"},
   201  	{http.MethodGet, "/repos/:owner/:repo/teams"},
   202  	{http.MethodGet, "/repos/:owner/:repo/tags"},
   203  	{http.MethodGet, "/repos/:owner/:repo/branches"},
   204  	{http.MethodGet, "/repos/:owner/:repo/branches/:branch"},
   205  	{http.MethodDelete, "/repos/:owner/:repo"},
   206  	{http.MethodGet, "/repos/:owner/:repo/collaborators"},
   207  	{http.MethodGet, "/repos/:owner/:repo/collaborators/:user"},
   208  	{http.MethodPut, "/repos/:owner/:repo/collaborators/:user"},
   209  	{http.MethodDelete, "/repos/:owner/:repo/collaborators/:user"},
   210  	{http.MethodGet, "/repos/:owner/:repo/comments"},
   211  	{http.MethodGet, "/repos/:owner/:repo/commits/:sha/comments"},
   212  	{http.MethodPost, "/repos/:owner/:repo/commits/:sha/comments"},
   213  	{http.MethodGet, "/repos/:owner/:repo/comments/:id"},
   214  	//{http.MethodPatch, "/repos/:owner/:repo/comments/:id"},
   215  	{http.MethodDelete, "/repos/:owner/:repo/comments/:id"},
   216  	{http.MethodGet, "/repos/:owner/:repo/commits"},
   217  	{http.MethodGet, "/repos/:owner/:repo/commits/:sha"},
   218  	{http.MethodGet, "/repos/:owner/:repo/readme"},
   219  	//{http.MethodGet, "/repos/:owner/:repo/contents/*path"},
   220  	//{http.MethodPut, "/repos/:owner/:repo/contents/*path"},
   221  	//{http.MethodDelete, "/repos/:owner/:repo/contents/*path"},
   222  	//{http.MethodGet, "/repos/:owner/:repo/:archive_format/:ref"},
   223  	{http.MethodGet, "/repos/:owner/:repo/keys"},
   224  	{http.MethodGet, "/repos/:owner/:repo/keys/:id"},
   225  	{http.MethodPost, "/repos/:owner/:repo/keys"},
   226  	//{http.MethodPatch, "/repos/:owner/:repo/keys/:id"},
   227  	{http.MethodDelete, "/repos/:owner/:repo/keys/:id"},
   228  	{http.MethodGet, "/repos/:owner/:repo/downloads"},
   229  	{http.MethodGet, "/repos/:owner/:repo/downloads/:id"},
   230  	{http.MethodDelete, "/repos/:owner/:repo/downloads/:id"},
   231  	{http.MethodGet, "/repos/:owner/:repo/forks"},
   232  	{http.MethodPost, "/repos/:owner/:repo/forks"},
   233  	{http.MethodGet, "/repos/:owner/:repo/hooks"},
   234  	{http.MethodGet, "/repos/:owner/:repo/hooks/:id"},
   235  	{http.MethodPost, "/repos/:owner/:repo/hooks"},
   236  	//{http.MethodPatch, "/repos/:owner/:repo/hooks/:id"},
   237  	{http.MethodPost, "/repos/:owner/:repo/hooks/:id/tests"},
   238  	{http.MethodDelete, "/repos/:owner/:repo/hooks/:id"},
   239  	{http.MethodPost, "/repos/:owner/:repo/merges"},
   240  	{http.MethodGet, "/repos/:owner/:repo/releases"},
   241  	{http.MethodGet, "/repos/:owner/:repo/releases/:id"},
   242  	{http.MethodPost, "/repos/:owner/:repo/releases"},
   243  	//{http.MethodPatch, "/repos/:owner/:repo/releases/:id"},
   244  	{http.MethodDelete, "/repos/:owner/:repo/releases/:id"},
   245  	{http.MethodGet, "/repos/:owner/:repo/releases/:id/assets"},
   246  	{http.MethodGet, "/repos/:owner/:repo/stats/contributors"},
   247  	{http.MethodGet, "/repos/:owner/:repo/stats/commit_activity"},
   248  	{http.MethodGet, "/repos/:owner/:repo/stats/code_frequency"},
   249  	{http.MethodGet, "/repos/:owner/:repo/stats/participation"},
   250  	{http.MethodGet, "/repos/:owner/:repo/stats/punch_card"},
   251  	{http.MethodGet, "/repos/:owner/:repo/statuses/:ref"},
   252  	{http.MethodPost, "/repos/:owner/:repo/statuses/:ref"},
   253  
   254  	// Search
   255  	{http.MethodGet, "/search/repositories"},
   256  	{http.MethodGet, "/search/code"},
   257  	{http.MethodGet, "/search/issues"},
   258  	{http.MethodGet, "/search/users"},
   259  	{http.MethodGet, "/legacy/issues/search/:owner/:repository/:state/:keyword"},
   260  	{http.MethodGet, "/legacy/repos/search/:keyword"},
   261  	{http.MethodGet, "/legacy/user/search/:keyword"},
   262  	{http.MethodGet, "/legacy/user/email/:email"},
   263  
   264  	// Users
   265  	{http.MethodGet, "/users/:user"},
   266  	{http.MethodGet, "/user"},
   267  	//{http.MethodPatch, "/user"},
   268  	{http.MethodGet, "/users"},
   269  	{http.MethodGet, "/user/emails"},
   270  	{http.MethodPost, "/user/emails"},
   271  	{http.MethodDelete, "/user/emails"},
   272  	{http.MethodGet, "/users/:user/followers"},
   273  	{http.MethodGet, "/user/followers"},
   274  	{http.MethodGet, "/users/:user/following"},
   275  	{http.MethodGet, "/user/following"},
   276  	{http.MethodGet, "/user/following/:user"},
   277  	{http.MethodGet, "/users/:user/following/:target_user"},
   278  	{http.MethodPut, "/user/following/:user"},
   279  	{http.MethodDelete, "/user/following/:user"},
   280  	{http.MethodGet, "/users/:user/keys"},
   281  	{http.MethodGet, "/user/keys"},
   282  	{http.MethodGet, "/user/keys/:id"},
   283  	{http.MethodPost, "/user/keys"},
   284  	//{http.MethodPatch, "/user/keys/:id"},
   285  	{http.MethodDelete, "/user/keys/:id"},
   286  }
   287  
   288  func TestShouldBindUri(t *testing.T) {
   289  	DefaultWriter = os.Stdout
   290  	router := New()
   291  
   292  	type Person struct {
   293  		Name string `uri:"name" binding:"required"`
   294  		ID   string `uri:"id" binding:"required"`
   295  	}
   296  	router.Handle(http.MethodGet, "/rest/:name/:id", func(c *Context) {
   297  		var person Person
   298  		assert.NoError(t, c.ShouldBindUri(&person))
   299  		assert.True(t, person.Name != "")
   300  		assert.True(t, person.ID != "")
   301  		c.String(http.StatusOK, "ShouldBindUri test OK")
   302  	})
   303  
   304  	path, _ := exampleFromPath("/rest/:name/:id")
   305  	w := PerformRequest(router, http.MethodGet, path)
   306  	assert.Equal(t, "ShouldBindUri test OK", w.Body.String())
   307  	assert.Equal(t, http.StatusOK, w.Code)
   308  }
   309  
   310  func TestBindUri(t *testing.T) {
   311  	DefaultWriter = os.Stdout
   312  	router := New()
   313  
   314  	type Person struct {
   315  		Name string `uri:"name" binding:"required"`
   316  		ID   string `uri:"id" binding:"required"`
   317  	}
   318  	router.Handle(http.MethodGet, "/rest/:name/:id", func(c *Context) {
   319  		var person Person
   320  		assert.NoError(t, c.BindUri(&person))
   321  		assert.True(t, person.Name != "")
   322  		assert.True(t, person.ID != "")
   323  		c.String(http.StatusOK, "BindUri test OK")
   324  	})
   325  
   326  	path, _ := exampleFromPath("/rest/:name/:id")
   327  	w := PerformRequest(router, http.MethodGet, path)
   328  	assert.Equal(t, "BindUri test OK", w.Body.String())
   329  	assert.Equal(t, http.StatusOK, w.Code)
   330  }
   331  
   332  func TestBindUriError(t *testing.T) {
   333  	DefaultWriter = os.Stdout
   334  	router := New()
   335  
   336  	type Member struct {
   337  		Number string `uri:"num" binding:"required,uuid"`
   338  	}
   339  	router.Handle(http.MethodGet, "/new/rest/:num", func(c *Context) {
   340  		var m Member
   341  		assert.Error(t, c.BindUri(&m))
   342  	})
   343  
   344  	path1, _ := exampleFromPath("/new/rest/:num")
   345  	w1 := PerformRequest(router, http.MethodGet, path1)
   346  	assert.Equal(t, http.StatusBadRequest, w1.Code)
   347  }
   348  
   349  func TestRaceContextCopy(t *testing.T) {
   350  	DefaultWriter = os.Stdout
   351  	router := Default()
   352  	router.GET("/test/copy/race", func(c *Context) {
   353  		c.Set("1", 0)
   354  		c.Set("2", 0)
   355  
   356  		// Sending a copy of the Context to two separate routines
   357  		go readWriteKeys(c.Copy())
   358  		go readWriteKeys(c.Copy())
   359  		c.String(http.StatusOK, "run OK, no panics")
   360  	})
   361  	w := PerformRequest(router, http.MethodGet, "/test/copy/race")
   362  	assert.Equal(t, "run OK, no panics", w.Body.String())
   363  }
   364  
   365  func readWriteKeys(c *Context) {
   366  	for {
   367  		c.Set("1", rand.Int())
   368  		c.Set("2", c.Value("1"))
   369  	}
   370  }
   371  
   372  func githubConfigRouter(router *Engine) {
   373  	for _, route := range githubAPI {
   374  		router.Handle(route.method, route.path, func(c *Context) {
   375  			output := make(map[string]string, len(c.Params)+1)
   376  			output["status"] = "good"
   377  			for _, param := range c.Params {
   378  				output[param.Key] = param.Value
   379  			}
   380  			c.JSON(http.StatusOK, output)
   381  		})
   382  	}
   383  }
   384  
   385  func TestGithubAPI(t *testing.T) {
   386  	DefaultWriter = os.Stdout
   387  	router := New()
   388  	githubConfigRouter(router)
   389  
   390  	for _, route := range githubAPI {
   391  		path, values := exampleFromPath(route.path)
   392  		w := PerformRequest(router, route.method, path)
   393  
   394  		// TEST
   395  		assert.Contains(t, w.Body.String(), "\"status\":\"good\"")
   396  		for _, value := range values {
   397  			str := fmt.Sprintf("\"%s\":\"%s\"", value.Key, value.Value)
   398  			assert.Contains(t, w.Body.String(), str)
   399  		}
   400  	}
   401  }
   402  
   403  func exampleFromPath(path string) (string, Params) {
   404  	output := new(strings.Builder)
   405  	params := make(Params, 0, 6)
   406  	start := -1
   407  	for i, c := range path {
   408  		if c == ':' {
   409  			start = i + 1
   410  		}
   411  		if start >= 0 {
   412  			if c == '/' {
   413  				value := fmt.Sprint(rand.Intn(100000))
   414  				params = append(params, Param{
   415  					Key:   path[start:i],
   416  					Value: value,
   417  				})
   418  				output.WriteString(value)
   419  				output.WriteRune(c)
   420  				start = -1
   421  			}
   422  		} else {
   423  			output.WriteRune(c)
   424  		}
   425  	}
   426  	if start >= 0 {
   427  		value := fmt.Sprint(rand.Intn(100000))
   428  		params = append(params, Param{
   429  			Key:   path[start:],
   430  			Value: value,
   431  		})
   432  		output.WriteString(value)
   433  	}
   434  
   435  	return output.String(), params
   436  }
   437  
   438  func BenchmarkGithub(b *testing.B) {
   439  	router := New()
   440  	githubConfigRouter(router)
   441  	runRequest(b, router, http.MethodGet, "/legacy/issues/search/:owner/:repository/:state/:keyword")
   442  }
   443  
   444  func BenchmarkParallelGithub(b *testing.B) {
   445  	DefaultWriter = os.Stdout
   446  	router := New()
   447  	githubConfigRouter(router)
   448  
   449  	req, _ := http.NewRequest(http.MethodPost, "/repos/manucorporat/sse/git/blobs", nil)
   450  
   451  	b.RunParallel(func(pb *testing.PB) {
   452  		// Each goroutine has its own bytes.Buffer.
   453  		for pb.Next() {
   454  			w := httptest.NewRecorder()
   455  			router.ServeHTTP(w, req)
   456  		}
   457  	})
   458  }
   459  
   460  func BenchmarkParallelGithubDefault(b *testing.B) {
   461  	DefaultWriter = os.Stdout
   462  	router := New()
   463  	githubConfigRouter(router)
   464  
   465  	req, _ := http.NewRequest(http.MethodPost, "/repos/manucorporat/sse/git/blobs", nil)
   466  
   467  	b.RunParallel(func(pb *testing.PB) {
   468  		// Each goroutine has its own bytes.Buffer.
   469  		for pb.Next() {
   470  			w := httptest.NewRecorder()
   471  			router.ServeHTTP(w, req)
   472  		}
   473  	})
   474  }
   475  

View as plain text