provider_client_test.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package testing
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "net/http"
  6. "sync"
  7. "testing"
  8. "time"
  9. "devel.mephi.ru/iacherepanov/openstack-gophercloud"
  10. th "devel.mephi.ru/iacherepanov/openstack-gophercloud/testhelper"
  11. "devel.mephi.ru/iacherepanov/openstack-gophercloud/testhelper/client"
  12. )
  13. func TestAuthenticatedHeaders(t *testing.T) {
  14. p := &gophercloud.ProviderClient{
  15. TokenID: "1234",
  16. }
  17. expected := map[string]string{"X-Auth-Token": "1234"}
  18. actual := p.AuthenticatedHeaders()
  19. th.CheckDeepEquals(t, expected, actual)
  20. }
  21. func TestUserAgent(t *testing.T) {
  22. p := &gophercloud.ProviderClient{}
  23. p.UserAgent.Prepend("custom-user-agent/2.4.0")
  24. expected := "custom-user-agent/2.4.0 gophercloud/2.0.0"
  25. actual := p.UserAgent.Join()
  26. th.CheckEquals(t, expected, actual)
  27. p.UserAgent.Prepend("another-custom-user-agent/0.3.0", "a-third-ua/5.9.0")
  28. expected = "another-custom-user-agent/0.3.0 a-third-ua/5.9.0 custom-user-agent/2.4.0 gophercloud/2.0.0"
  29. actual = p.UserAgent.Join()
  30. th.CheckEquals(t, expected, actual)
  31. p.UserAgent = gophercloud.UserAgent{}
  32. expected = "gophercloud/2.0.0"
  33. actual = p.UserAgent.Join()
  34. th.CheckEquals(t, expected, actual)
  35. }
  36. func TestConcurrentReauth(t *testing.T) {
  37. var info = struct {
  38. numreauths int
  39. mut *sync.RWMutex
  40. }{
  41. 0,
  42. new(sync.RWMutex),
  43. }
  44. numconc := 20
  45. prereauthTok := client.TokenID
  46. postreauthTok := "12345678"
  47. p := new(gophercloud.ProviderClient)
  48. p.UseTokenLock()
  49. p.SetToken(prereauthTok)
  50. p.ReauthFunc = func() error {
  51. time.Sleep(1 * time.Second)
  52. p.AuthenticatedHeaders()
  53. info.mut.Lock()
  54. info.numreauths++
  55. info.mut.Unlock()
  56. p.TokenID = postreauthTok
  57. return nil
  58. }
  59. th.SetupHTTP()
  60. defer th.TeardownHTTP()
  61. th.Mux.HandleFunc("/route", func(w http.ResponseWriter, r *http.Request) {
  62. if r.Header.Get("X-Auth-Token") != postreauthTok {
  63. w.WriteHeader(http.StatusUnauthorized)
  64. return
  65. }
  66. info.mut.RLock()
  67. hasReauthed := info.numreauths != 0
  68. info.mut.RUnlock()
  69. if hasReauthed {
  70. th.CheckEquals(t, p.Token(), postreauthTok)
  71. }
  72. w.Header().Add("Content-Type", "application/json")
  73. fmt.Fprintf(w, `{}`)
  74. })
  75. wg := new(sync.WaitGroup)
  76. reqopts := new(gophercloud.RequestOpts)
  77. reqopts.MoreHeaders = map[string]string{
  78. "X-Auth-Token": prereauthTok,
  79. }
  80. for i := 0; i < numconc; i++ {
  81. wg.Add(1)
  82. go func() {
  83. defer wg.Done()
  84. resp, err := p.Request("GET", fmt.Sprintf("%s/route", th.Endpoint()), reqopts)
  85. th.CheckNoErr(t, err)
  86. if resp == nil {
  87. t.Errorf("got a nil response")
  88. return
  89. }
  90. if resp.Body == nil {
  91. t.Errorf("response body was nil")
  92. return
  93. }
  94. defer resp.Body.Close()
  95. actual, err := ioutil.ReadAll(resp.Body)
  96. if err != nil {
  97. t.Errorf("error reading response body: %s", err)
  98. return
  99. }
  100. th.CheckByteArrayEquals(t, []byte(`{}`), actual)
  101. }()
  102. }
  103. wg.Wait()
  104. th.AssertEquals(t, 1, info.numreauths)
  105. }