func chunkServer() { loadConfigOrDie() debug.SetGCPercent(config.GCPercent) stores := make([]store.Store, len(config.Chunk.Dirs)) for i := range config.Chunk.Dirs { dir := config.Chunk.Dirs[i] construct := func() store.Store { log.Printf("Trying to open store at %v", dir) start := time.Now() ds, err := storedir.OpenDirectory( dir, config.Chunk.Scrubber.SleepPerFile.Duration, config.Chunk.Scrubber.SleepPerByte.Duration, ) if err != nil { log.Printf("Couldn't open store at %v: %v", dir, err) return nil } dur := time.Now().Sub(start) log.Printf("Store at %v opened with UUID %v in %v", dir, uuid.Fmt(ds.UUID()), dur) return ds } stores[i] = store.NewRetryStore(construct, time.Second*15) } var h http.Handler var err error h, err = chunkserver.New(stores) if err != nil { log.Fatalf("Couldn't initialize handler: %v", err) } h = httputil.NewLimitParallelism(config.Chunk.ParallelRequests, h) h = httputil.AddDebugHandlers(h, config.Chunk.Debug) if !config.Chunk.DisableHTTPLogging { h = httputil.LogHTTPRequests(h) } serveOrDie(config.Chunk.Listen, h) }
func TestHandlerBasics(t *testing.T) { tmpdir, err := ioutil.TempDir("", "") if err != nil { t.Fatalf("Couldn't create temporary directory: %v", err) } defer os.RemoveAll(tmpdir) err = storedir.CreateDirectory(tmpdir) if err != nil { t.Fatalf("Couldn't initialize directory store in %v: %v", tmpdir, err) } uuidBytes, err := ioutil.ReadFile(filepath.Join(tmpdir, "uuid")) if err != nil { t.Fatalf("Couldn't read uuid file: %v", err) } uuid := string(uuidBytes) ds, err := storedir.OpenDirectory(tmpdir, 0, 0) if err != nil { t.Fatalf("Couldn't OpenDirectory %v: %v", tmpdir, err) } defer ds.Close() h, err := New([]store.Store{ds}) if err != nil { t.Fatalf("Couldn't create Handler: %v", err) } defer h.Close() h.WaitAllAvailable() shouldRespond(t, h, "GET", "/", "", 200, "Howdy, slime chunk server here!\n") shouldRespond(t, h, "GET", "/uuids", "", 200, uuid+"\n") shouldRespond(t, h, "GET", "/"+uuid+"/?mode=list", "", 200, "") shouldRespond(t, h, "PUT", "/"+uuid+"/file", "contents", 204, "") shouldRespond(t, h, "GET", "/"+uuid+"/file", "", 200, "contents") shouldRespond(t, h, "GET", "/"+uuid+"/?mode=list", "", 200, "file\n") shouldRespond(t, h, "DELETE", "/"+uuid+"/file", "", 204, "") shouldRespond(t, h, "GET", "/"+uuid+"/file", "", 404, "not found\n") shouldRespond(t, h, "DELETE", "/"+uuid+"/file", "", 404, "not found\n") shouldRespond(t, h, "GET", "/"+uuid+"/?mode=list", "", 200, "") shouldRespond(t, h, "PUT", "/"+uuid+"/z", "z", 204, "") shouldRespond(t, h, "PUT", "/"+uuid+"/y", "y", 204, "") shouldRespond(t, h, "PUT", "/"+uuid+"/a", "a", 204, "") shouldRespond(t, h, "PUT", "/"+uuid+"/c", "c", 204, "") shouldRespond(t, h, "PUT", "/"+uuid+"/x", "x", 204, "") shouldRespond(t, h, "PUT", "/"+uuid+"/b", "b", 204, "") shouldRespond(t, h, "GET", "/"+uuid+"/?mode=list", "", 200, "a\nb\nc\nx\ny\nz\n") shouldRespond(t, h, "GET", "/"+uuid+"/?mode=list&limit=3", "", 200, "a\nb\nc\n") shouldRespond(t, h, "GET", "/"+uuid+"/?mode=list&limit=2&after=b", "", 200, "c\nx\n") shouldRespond(t, h, "GET", "/"+uuid+"/?mode=list&limit=3&after=y", "", 200, "z\n") shouldRespondInteger(t, h, "GET", "/"+uuid+"/?mode=free", 200) }