github.com/mckael/restic@v0.8.3/internal/backend/rest/rest_int_test.go (about) 1 package rest_test 2 3 import ( 4 "context" 5 "fmt" 6 "net/http" 7 "net/http/httptest" 8 "net/url" 9 "reflect" 10 "strconv" 11 "testing" 12 13 "github.com/restic/restic/internal/backend/rest" 14 "github.com/restic/restic/internal/restic" 15 ) 16 17 func TestListAPI(t *testing.T) { 18 var tests = []struct { 19 Name string 20 21 ContentType string // response header 22 Data string // response data 23 Requests int 24 25 Result []restic.FileInfo 26 }{ 27 { 28 Name: "content-type-unknown", 29 ContentType: "application/octet-stream", 30 Data: `[ 31 "1122e6749358b057fa1ac6b580a0fbe7a9a5fbc92e82743ee21aaf829624a985", 32 "3b6ec1af8d4f7099d0445b12fdb75b166ba19f789e5c48350c423dc3b3e68352", 33 "8271d221a60e0058e6c624f248d0080fc04f4fac07a28584a9b89d0eb69e189b" 34 ]`, 35 Result: []restic.FileInfo{ 36 {Name: "1122e6749358b057fa1ac6b580a0fbe7a9a5fbc92e82743ee21aaf829624a985", Size: 4386}, 37 {Name: "3b6ec1af8d4f7099d0445b12fdb75b166ba19f789e5c48350c423dc3b3e68352", Size: 15214}, 38 {Name: "8271d221a60e0058e6c624f248d0080fc04f4fac07a28584a9b89d0eb69e189b", Size: 33393}, 39 }, 40 Requests: 4, 41 }, 42 { 43 Name: "content-type-v1", 44 ContentType: "application/vnd.x.restic.rest.v1", 45 Data: `[ 46 "1122e6749358b057fa1ac6b580a0fbe7a9a5fbc92e82743ee21aaf829624a985", 47 "3b6ec1af8d4f7099d0445b12fdb75b166ba19f789e5c48350c423dc3b3e68352", 48 "8271d221a60e0058e6c624f248d0080fc04f4fac07a28584a9b89d0eb69e189b" 49 ]`, 50 Result: []restic.FileInfo{ 51 {Name: "1122e6749358b057fa1ac6b580a0fbe7a9a5fbc92e82743ee21aaf829624a985", Size: 4386}, 52 {Name: "3b6ec1af8d4f7099d0445b12fdb75b166ba19f789e5c48350c423dc3b3e68352", Size: 15214}, 53 {Name: "8271d221a60e0058e6c624f248d0080fc04f4fac07a28584a9b89d0eb69e189b", Size: 33393}, 54 }, 55 Requests: 4, 56 }, 57 { 58 Name: "content-type-v2", 59 ContentType: "application/vnd.x.restic.rest.v2", 60 Data: `[ 61 {"name": "1122e6749358b057fa1ac6b580a0fbe7a9a5fbc92e82743ee21aaf829624a985", "size": 1001}, 62 {"name": "3b6ec1af8d4f7099d0445b12fdb75b166ba19f789e5c48350c423dc3b3e68352", "size": 1002}, 63 {"name": "8271d221a60e0058e6c624f248d0080fc04f4fac07a28584a9b89d0eb69e189b", "size": 1003} 64 ]`, 65 Result: []restic.FileInfo{ 66 {Name: "1122e6749358b057fa1ac6b580a0fbe7a9a5fbc92e82743ee21aaf829624a985", Size: 1001}, 67 {Name: "3b6ec1af8d4f7099d0445b12fdb75b166ba19f789e5c48350c423dc3b3e68352", Size: 1002}, 68 {Name: "8271d221a60e0058e6c624f248d0080fc04f4fac07a28584a9b89d0eb69e189b", Size: 1003}, 69 }, 70 Requests: 1, 71 }, 72 } 73 74 for _, test := range tests { 75 t.Run(test.Name, func(t *testing.T) { 76 numRequests := 0 77 srv := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { 78 numRequests++ 79 t.Logf("req %v %v, accept: %v", req.Method, req.URL.Path, req.Header["Accept"]) 80 81 var err error 82 switch { 83 case req.Method == "GET": 84 // list files in data/ 85 res.Header().Set("Content-Type", test.ContentType) 86 _, err = res.Write([]byte(test.Data)) 87 88 if err != nil { 89 t.Fatal(err) 90 } 91 return 92 case req.Method == "HEAD": 93 // stat file in data/, use the first two bytes in the name 94 // of the file as the size :) 95 filename := req.URL.Path[6:] 96 len, err := strconv.ParseInt(filename[:4], 16, 64) 97 if err != nil { 98 t.Fatal(err) 99 } 100 101 res.Header().Set("Content-Length", fmt.Sprintf("%d", len)) 102 res.WriteHeader(http.StatusOK) 103 return 104 } 105 106 t.Errorf("unhandled request %v %v", req.Method, req.URL.Path) 107 })) 108 defer srv.Close() 109 110 srvURL, err := url.Parse(srv.URL) 111 if err != nil { 112 t.Fatal(err) 113 } 114 115 cfg := rest.Config{ 116 Connections: 5, 117 URL: srvURL, 118 } 119 120 be, err := rest.Open(cfg, http.DefaultTransport) 121 if err != nil { 122 t.Fatal(err) 123 } 124 125 var list []restic.FileInfo 126 err = be.List(context.TODO(), restic.DataFile, func(fi restic.FileInfo) error { 127 list = append(list, fi) 128 return nil 129 }) 130 if err != nil { 131 t.Fatal(err) 132 } 133 134 if !reflect.DeepEqual(list, test.Result) { 135 t.Fatalf("wrong response returned, want:\n %v\ngot: %v", test.Result, list) 136 } 137 138 if numRequests != test.Requests { 139 t.Fatalf("wrong number of HTTP requests executed, want %d, got %d", test.Requests, numRequests) 140 } 141 142 defer func() { 143 err = be.Close() 144 if err != nil { 145 t.Fatal(err) 146 } 147 }() 148 }) 149 } 150 }