func ExitWithError(err error) { if Debugging || errutil.IsFatalError(err) { Panic(err, err.Error()) } else { if inner := errutil.GetInnerError(err); inner != nil { Error(inner.Error()) } Exit(err.Error()) } }
func buildTestData() (oidsExist, oidsMissing []TestObject, err error) { const oidCount = 50 oidsExist = make([]TestObject, 0, oidCount) oidsMissing = make([]TestObject, 0, oidCount) // Build test data for existing files & upload // Use test repo for this to simplify the process of making sure data matches oid // We're not performing a real test at this point (although an upload fail will break it) var callback testDataCallback repo := test.NewRepo(&callback) repo.Pushd() defer repo.Cleanup() // just one commit commit := test.CommitInput{CommitterName: "A N Other", CommitterEmail: "*****@*****.**"} var totalSize int64 for i := 0; i < oidCount; i++ { filename := fmt.Sprintf("file%d.dat", i) sz := int64(rand.Intn(200)) + 50 commit.Files = append(commit.Files, &test.FileInput{Filename: filename, Size: sz}) totalSize += sz } outputs := repo.AddCommits([]*test.CommitInput{&commit}) // now upload uploadQueue := lfs.NewUploadQueue(len(oidsExist), totalSize, false) for _, f := range outputs[0].Files { oidsExist = append(oidsExist, TestObject{Oid: f.Oid, Size: f.Size}) u, err := lfs.NewUploadable(f.Oid, "Test file") if err != nil { return nil, nil, err } uploadQueue.Add(u) } uploadQueue.Wait() for _, err := range uploadQueue.Errors() { if errutil.IsFatalError(err) { exit("Fatal error setting up test data: %s", err) } } // Generate SHAs for missing files, random but repeatable // No actual file content needed for these rand.Seed(int64(oidCount)) runningSha := sha256.New() for i := 0; i < oidCount; i++ { runningSha.Write([]byte{byte(rand.Intn(256))}) oid := hex.EncodeToString(runningSha.Sum(nil)) sz := int64(rand.Intn(200)) + 50 oidsMissing = append(oidsMissing, TestObject{Oid: oid, Size: sz}) } return oidsExist, oidsMissing, nil }
func TestUploadApiError(t *testing.T) { SetupTestCredentialsFunc() repo := test.NewRepo(t) repo.Pushd() defer func() { repo.Popd() repo.Cleanup() RestoreCredentialsFunc() }() mux := http.NewServeMux() server := httptest.NewServer(mux) tmp := tempdir(t) defer server.Close() defer os.RemoveAll(tmp) postCalled := false mux.HandleFunc("/media/objects", func(w http.ResponseWriter, r *http.Request) { postCalled = true w.WriteHeader(404) }) defer config.Config.ResetConfig() config.Config.SetConfig("lfs.url", server.URL+"/media") oidPath, _ := lfs.LocalMediaPath("988881adc9fc3655077dc2d4d757d480b5ea0e11") if err := ioutil.WriteFile(oidPath, []byte("test"), 0744); err != nil { t.Fatal(err) } oid := filepath.Base(oidPath) stat, _ := os.Stat(oidPath) _, _, err := api.BatchOrLegacySingle(&api.ObjectResource{Oid: oid, Size: stat.Size()}, "upload", []string{"basic"}) if err == nil { t.Fatal(err) } if errutil.IsFatalError(err) { t.Fatal("should not panic") } if isDockerConnectionError(err) { return } if err.Error() != fmt.Sprintf(httputil.GetDefaultError(404), server.URL+"/media/objects") { t.Fatalf("Unexpected error: %s", err.Error()) } if !postCalled { t.Errorf("POST not called") } }
func upload(c *uploadContext, unfiltered []*lfs.WrappedPointer) { if c.DryRun { for _, p := range unfiltered { if c.HasUploaded(p.Oid) { continue } Print("push %s => %s", p.Oid, p.Name) c.SetUploaded(p.Oid) } return } q, pointers := c.prepareUpload(unfiltered) for _, p := range pointers { u, err := lfs.NewUploadable(p.Oid, p.Name) if err != nil { if errutil.IsCleanPointerError(err) { Exit(uploadMissingErr, p.Oid, p.Name, errutil.ErrorGetContext(err, "pointer").(*lfs.Pointer).Oid) } else { ExitWithError(err) } } q.Add(u) c.SetUploaded(p.Oid) } q.Wait() for _, err := range q.Errors() { if Debugging || errutil.IsFatalError(err) { LoggedError(err, err.Error()) } else { if inner := errutil.GetInnerError(err); inner != nil { Error(inner.Error()) } Error(err.Error()) } } if len(q.Errors()) > 0 { os.Exit(2) } }
func TestDownloadAPIError(t *testing.T) { SetupTestCredentialsFunc() defer func() { RestoreCredentialsFunc() }() mux := http.NewServeMux() server := httptest.NewServer(mux) defer server.Close() tmp := tempdir(t) defer os.RemoveAll(tmp) mux.HandleFunc("/media/objects/oid", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(404) }) defer config.Config.ResetConfig() config.Config.SetConfig("lfs.batch", "false") config.Config.SetConfig("lfs.url", server.URL+"/media") _, _, err := api.BatchOrLegacySingle(&api.ObjectResource{Oid: "oid"}, "download", []string{"basic"}) if err == nil { t.Fatal("no error?") } if errutil.IsFatalError(err) { t.Fatal("should not panic") } if isDockerConnectionError(err) { return } if err.Error() != fmt.Sprintf(httputil.GetDefaultError(404), server.URL+"/media/objects/oid") { t.Fatalf("Unexpected error: %s", err.Error()) } }
func TestUploadVerifyError(t *testing.T) { SetupTestCredentialsFunc() repo := test.NewRepo(t) repo.Pushd() defer func() { repo.Popd() repo.Cleanup() RestoreCredentialsFunc() }() mux := http.NewServeMux() server := httptest.NewServer(mux) tmp := tempdir(t) defer server.Close() defer os.RemoveAll(tmp) postCalled := false verifyCalled := false mux.HandleFunc("/media/objects", func(w http.ResponseWriter, r *http.Request) { t.Logf("Server: %s %s", r.Method, r.URL) if r.Method != "POST" { w.WriteHeader(405) return } if r.Header.Get("Accept") != api.MediaType { t.Errorf("Invalid Accept") } if r.Header.Get("Content-Type") != api.MediaType { t.Errorf("Invalid Content-Type") } buf := &bytes.Buffer{} tee := io.TeeReader(r.Body, buf) reqObj := &api.ObjectResource{} err := json.NewDecoder(tee).Decode(reqObj) t.Logf("request header: %v", r.Header) t.Logf("request body: %s", buf.String()) if err != nil { t.Fatal(err) } if reqObj.Oid != "988881adc9fc3655077dc2d4d757d480b5ea0e11" { t.Errorf("invalid oid from request: %s", reqObj.Oid) } if reqObj.Size != 4 { t.Errorf("invalid size from request: %d", reqObj.Size) } obj := &api.ObjectResource{ Oid: reqObj.Oid, Size: reqObj.Size, Actions: map[string]*api.LinkRelation{ "upload": &api.LinkRelation{ Href: server.URL + "/upload", Header: map[string]string{"A": "1"}, }, "verify": &api.LinkRelation{ Href: server.URL + "/verify", Header: map[string]string{"B": "2"}, }, }, } by, err := json.Marshal(obj) if err != nil { t.Fatal(err) } postCalled = true head := w.Header() head.Set("Content-Type", api.MediaType) head.Set("Content-Length", strconv.Itoa(len(by))) w.WriteHeader(202) w.Write(by) }) mux.HandleFunc("/verify", func(w http.ResponseWriter, r *http.Request) { verifyCalled = true w.WriteHeader(404) }) defer config.Config.ResetConfig() config.Config.SetConfig("lfs.url", server.URL+"/media") oidPath, _ := lfs.LocalMediaPath("988881adc9fc3655077dc2d4d757d480b5ea0e11") if err := ioutil.WriteFile(oidPath, []byte("test"), 0744); err != nil { t.Fatal(err) } oid := filepath.Base(oidPath) stat, _ := os.Stat(oidPath) o, _, err := api.BatchOrLegacySingle(&api.ObjectResource{Oid: oid, Size: stat.Size()}, "upload", []string{"basic"}) if err != nil { if isDockerConnectionError(err) { return } t.Fatal(err) } err = api.VerifyUpload(o) if err == nil { t.Fatal("verify should fail") } if errutil.IsFatalError(err) { t.Fatal("should not panic") } if err.Error() != fmt.Sprintf(httputil.GetDefaultError(404), server.URL+"/verify") { t.Fatalf("Unexpected error: %s", err.Error()) } if !postCalled { t.Errorf("POST not called") } if !verifyCalled { t.Errorf("verify not called") } }