PageRenderTime 44ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/drone-plugin-wf/main_test.go

https://gitlab.com/0072016/0072016-Google-WebFundementls
Go | 228 lines | 192 code | 20 blank | 16 comment | 49 complexity | 74dd9add8b3aad8b44e285af2df31499 MD5 | raw file
  1. // Copyright 2015 Google Inc
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package main
  15. import (
  16. "bytes"
  17. "compress/gzip"
  18. "encoding/json"
  19. "fmt"
  20. "io/ioutil"
  21. "mime"
  22. "mime/multipart"
  23. "net/http"
  24. "os"
  25. "path/filepath"
  26. "reflect"
  27. "strings"
  28. "sync"
  29. "testing"
  30. "github.com/drone/drone-plugin-go/plugin"
  31. "github.com/google/go-github/github"
  32. "golang.org/x/net/context"
  33. "google.golang.org/cloud"
  34. "google.golang.org/cloud/storage"
  35. )
  36. type fakeTransport struct {
  37. f func(*http.Request) (*http.Response, error)
  38. }
  39. func (ft *fakeTransport) RoundTrip(r *http.Request) (*http.Response, error) {
  40. return ft.f(r)
  41. }
  42. func gunzip(t *testing.T, bz []byte) []byte {
  43. r, err := gzip.NewReader(bytes.NewReader(bz))
  44. if err != nil {
  45. t.Errorf("gunzip NewReader: %v", err)
  46. return bz
  47. }
  48. defer r.Close()
  49. b, err := ioutil.ReadAll(r)
  50. if err != nil {
  51. t.Errorf("gunzip read: %v", err)
  52. return bz
  53. }
  54. return b
  55. }
  56. func mkdirs(t *testing.T, path ...string) {
  57. p := filepath.Join(path...)
  58. if err := os.MkdirAll(p, 0755); err != nil {
  59. t.Fatalf("MkdirAll(%q): %v", p, err)
  60. }
  61. }
  62. func writeFile(t *testing.T, dir, name string, b []byte) {
  63. p := filepath.Join(dir, name)
  64. if err := ioutil.WriteFile(p, b, 0644); err != nil {
  65. t.Fatalf("WriteFile(%q): %v", p, err)
  66. }
  67. }
  68. func TestRandomString(t *testing.T) {
  69. a := randomString(32)
  70. if len(a) != 32 {
  71. t.Fatalf("len(a) = %d; want 32", len(a))
  72. }
  73. b := randomString(32)
  74. if a == b {
  75. t.Errorf("a == b == %q", a)
  76. }
  77. }
  78. func TestRun(t *testing.T) {
  79. wdir, err := ioutil.TempDir("", "drone-gcs-test")
  80. if err != nil {
  81. t.Fatal(err)
  82. }
  83. updir := filepath.Join(wdir, "upload")
  84. subdir := filepath.Join(updir, "sub")
  85. mkdirs(t, subdir)
  86. writeFile(t, updir, "file.txt", []byte("text"))
  87. writeFile(t, updir, "file.js", []byte("javascript"))
  88. writeFile(t, subdir, "file.css", []byte("sub style"))
  89. writeFile(t, subdir, "file.bin", []byte("rubbish"))
  90. files := map[string]*struct {
  91. ctype string
  92. body []byte
  93. gzip bool
  94. }{
  95. "file.txt": {"text/plain", []byte("text"), false},
  96. "file.js": {"application/javascript", []byte("javascript"), true},
  97. "sub/file.css": {"text/css", []byte("sub style"), false},
  98. }
  99. workspace.Path = wdir
  100. build.Branch = "patch-1"
  101. build.Event = plugin.EventPull
  102. build.Ref = "refs/pull/123/merge"
  103. vargs.Source = "upload"
  104. vargs.BucketSuffix = "-suffix"
  105. vargs.Ignore = "sub/*.bin"
  106. vargs.Gzip = []string{"js"}
  107. vargs.CacheControl = "public,max-age=10"
  108. vargs.Metadata = map[string]string{"x-foo": "bar"}
  109. acls := []storage.ACLRule{storage.ACLRule{"allUsers", "READER"}}
  110. vargs.ACL = []string{fmt.Sprintf("%s:%s", acls[0].Entity, acls[0].Role)}
  111. var seenMu sync.Mutex // guards seen
  112. seen := make(map[string]struct{}, len(files))
  113. okTransport := &fakeTransport{func(r *http.Request) (*http.Response, error) {
  114. return &http.Response{
  115. Body: ioutil.NopCloser(strings.NewReader("")),
  116. Proto: "HTTP/1.0",
  117. ProtoMajor: 1,
  118. ProtoMinor: 0,
  119. StatusCode: http.StatusOK,
  120. }, nil
  121. }}
  122. rt := &fakeTransport{func(r *http.Request) (resp *http.Response, e error) {
  123. resp = &http.Response{
  124. Body: ioutil.NopCloser(strings.NewReader(`{"name": "fake"}`)),
  125. Proto: "HTTP/1.0",
  126. ProtoMajor: 1,
  127. ProtoMinor: 0,
  128. StatusCode: http.StatusOK,
  129. }
  130. // skip bucket.Attr() requests
  131. if r.URL.Path == "/storage/v1/b/pr-123-suffix" && r.Method == "GET" {
  132. return resp, nil
  133. }
  134. up := "/upload/storage/v1/b/pr-123-suffix/o"
  135. if r.URL.Path != up {
  136. t.Errorf("r.URL.Path = %q; want %q", r.URL.Path, up)
  137. }
  138. _, mp, err := mime.ParseMediaType(r.Header.Get("content-type"))
  139. if err != nil {
  140. t.Errorf("ParseMediaType: %v", err)
  141. return
  142. }
  143. mr := multipart.NewReader(r.Body, mp["boundary"])
  144. // metadata
  145. p, err := mr.NextPart()
  146. if err != nil {
  147. t.Errorf("meta NextPart: %v", err)
  148. return
  149. }
  150. var attrs storage.ObjectAttrs
  151. if err := json.NewDecoder(p).Decode(&attrs); err != nil {
  152. t.Errorf("meta json: %v", err)
  153. return
  154. }
  155. seenMu.Lock()
  156. seen[attrs.Name] = struct{}{}
  157. seenMu.Unlock()
  158. obj := files[attrs.Name]
  159. if obj == nil {
  160. t.Errorf("unexpected obj: %+v", attrs)
  161. return
  162. }
  163. if attrs.Bucket != "pr-123-suffix" {
  164. t.Errorf("attrs.Bucket = %q; want pr-123-suffix", attrs.Bucket)
  165. }
  166. if attrs.CacheControl != vargs.CacheControl {
  167. t.Errorf("attrs.CacheControl = %q; want %q", attrs.CacheControl, vargs.CacheControl)
  168. }
  169. if obj.gzip && attrs.ContentEncoding != "gzip" {
  170. t.Errorf("attrs.ContentEncoding = %q; want gzip", attrs.ContentEncoding)
  171. }
  172. if !strings.HasPrefix(attrs.ContentType, obj.ctype) {
  173. t.Errorf("attrs.ContentType = %q; want %q", attrs.ContentType, obj.ctype)
  174. }
  175. if !reflect.DeepEqual(attrs.ACL, acls) {
  176. t.Errorf("attrs.ACL = %v; want %v", attrs.ACL, acls)
  177. }
  178. if !reflect.DeepEqual(attrs.Metadata, vargs.Metadata) {
  179. t.Errorf("attrs.Metadata = %+v; want %+v", attrs.Metadata, vargs.Metadata)
  180. }
  181. // media
  182. p, err = mr.NextPart()
  183. if err != nil {
  184. t.Errorf("media NextPart: %v", err)
  185. return
  186. }
  187. b, _ := ioutil.ReadAll(p)
  188. if attrs.ContentEncoding == "gzip" {
  189. b = gunzip(t, b)
  190. }
  191. if bytes.Compare(b, obj.body) != 0 {
  192. t.Errorf("media b = %q; want %q", b, obj.body)
  193. }
  194. return
  195. }}
  196. client.http = &http.Client{Transport: okTransport}
  197. client.ghub = github.NewClient(&http.Client{Transport: okTransport})
  198. hc := &http.Client{Transport: rt}
  199. if client.gcs, err = storage.NewClient(context.Background(), cloud.WithBaseHTTP(hc)); err != nil {
  200. t.Fatal(err)
  201. }
  202. run()
  203. for k := range files {
  204. if _, ok := seen[k]; !ok {
  205. t.Errorf("%s didn't get uploaded", k)
  206. }
  207. }
  208. }