func TestHandleWriteValue(t *testing.T) { assert := assert.New(t) cs := chunks.NewTestStore() ds := NewDatabase(cs) l := types.NewList( ds.WriteValue(types.Bool(true)), ds.WriteValue(types.Bool(false)), ) ds.WriteValue(l) hint := l.Hash() newItem := types.NewEmptyBlob() itemChunk := types.EncodeValue(newItem, nil) l2 := l.Insert(1, types.NewRef(newItem)) listChunk := types.EncodeValue(l2, nil) body := &bytes.Buffer{} serializeHints(body, map[hash.Hash]struct{}{hint: struct{}{}}) chunks.Serialize(itemChunk, body) chunks.Serialize(listChunk, body) w := httptest.NewRecorder() HandleWriteValue(w, newRequest("POST", "", "", body, nil), params{}, cs) if assert.Equal(http.StatusCreated, w.Code, "Handler error:\n%s", string(w.Body.Bytes())) { ds2 := NewDatabase(cs) v := ds2.ReadValue(l2.Hash()) if assert.NotNil(v) { assert.True(v.Equals(l2), "%+v != %+v", v, l2) } } }
func TestHandleWriteValueBackpressure(t *testing.T) { assert := assert.New(t) cs := &backpressureCS{ChunkStore: chunks.NewMemoryStore()} ds := NewDatabase(cs) l := types.NewList( ds.WriteValue(types.Bool(true)), ds.WriteValue(types.Bool(false)), ) ds.WriteValue(l) hint := l.Hash() newItem := types.NewEmptyBlob() itemChunk := types.EncodeValue(newItem, nil) l2 := l.Insert(1, types.NewRef(newItem)) listChunk := types.EncodeValue(l2, nil) body := &bytes.Buffer{} serializeHints(body, map[hash.Hash]struct{}{hint: struct{}{}}) chunks.Serialize(itemChunk, body) chunks.Serialize(listChunk, body) w := httptest.NewRecorder() HandleWriteValue(w, newRequest("POST", "", "", body, nil), params{}, cs) if assert.Equal(httpStatusTooManyRequests, w.Code, "Handler error:\n%s", string(w.Body.Bytes())) { hashes := deserializeHashes(w.Body) assert.Len(hashes, 1) assert.Equal(l2.Hash(), hashes[0]) } }
func TestWriteValue(t *testing.T) { assert := assert.New(t) factory := chunks.NewMemoryStoreFactory() defer factory.Shutter() router = setupWebServer(factory) defer func() { router = nil }() testString := "Now, what?" authKey = "anauthkeyvalue" w := httptest.NewRecorder() r, err := newRequest("GET", dbName+constants.RootPath, nil) assert.NoError(err) router.ServeHTTP(w, r) lastRoot := w.Body assert.Equal(http.StatusOK, w.Code) tval := types.Bool(true) wval := types.String(testString) chunk1 := types.EncodeValue(tval, nil) chunk2 := types.EncodeValue(wval, nil) refList := types.NewList(types.NewRef(tval), types.NewRef(wval)) chunk3 := types.EncodeValue(refList, nil) body := &bytes.Buffer{} // we would use this func, but it's private so use next line instead: serializeHints(body, map[ref.Ref]struct{}{hint: struct{}{}}) err = binary.Write(body, binary.BigEndian, uint32(0)) assert.NoError(err) chunks.Serialize(chunk1, body) chunks.Serialize(chunk2, body) chunks.Serialize(chunk3, body) w = httptest.NewRecorder() r, err = newRequest("POST", dbName+constants.WriteValuePath+"?access_token="+authKey, ioutil.NopCloser(body)) assert.NoError(err) router.ServeHTTP(w, r) assert.Equal(http.StatusCreated, w.Code) w = httptest.NewRecorder() args := fmt.Sprintf("&last=%s¤t=%s", lastRoot, types.NewRef(refList).TargetHash()) r, _ = newRequest("POST", dbName+constants.RootPath+"?access_token="+authKey+args, ioutil.NopCloser(body)) router.ServeHTTP(w, r) assert.Equal(http.StatusOK, w.Code) whash := wval.Hash() hints := map[hash.Hash]struct{}{whash: struct{}{}} rdr := buildGetRefsRequestBody(hints) r, _ = newRequest("POST", dbName+constants.GetRefsPath, rdr) r.Header.Add("Content-Type", "application/x-www-form-urlencoded") router.ServeHTTP(w, r) assert.Equal(http.StatusOK, w.Code) ms := chunks.NewMemoryStore() chunks.Deserialize(w.Body, ms, nil) v := types.DecodeValue(ms.Get(whash), datas.NewDatabase(ms)) assert.Equal(testString, string(v.(types.String))) }
func serializeChunks(chnx []chunks.Chunk, assert *assert.Assertions) io.Reader { body := &bytes.Buffer{} sw := snappy.NewBufferedWriter(body) for _, chunk := range chnx { chunks.Serialize(chunk, sw) } assert.NoError(sw.Close()) return body }
// Contents of the returned io.Reader are snappy-compressed. func buildWriteValueRequest(chunkChan chan *chunks.Chunk, hints map[hash.Hash]struct{}) io.Reader { body, pw := io.Pipe() go func() { gw := snappy.NewBufferedWriter(pw) serializeHints(gw, hints) for c := range chunkChan { chunks.Serialize(*c, gw) } d.Chk.NoError(gw.Close()) d.Chk.NoError(pw.Close()) }() return body }
func handleGetRefs(w http.ResponseWriter, req *http.Request, ps URLParams, cs chunks.ChunkStore) { d.PanicIfTrue(req.Method != "POST", "Expected post method.") hashes := extractHashes(req) w.Header().Add("Content-Type", "application/octet-stream") writer := respWriter(req, w) defer writer.Close() for _, h := range hashes { c := cs.Get(h) if !c.IsEmpty() { chunks.Serialize(c, writer) } } }
// Insert can be called from any goroutine to store c in the cache. If c is successfully added to the cache, Insert returns true. If c was already in the cache, Insert returns false. func (p *orderedChunkCache) Insert(c chunks.Chunk, refHeight uint64) bool { hash := c.Hash() dbKey, present := func() (dbKey []byte, present bool) { p.mu.Lock() defer p.mu.Unlock() if _, present = p.chunkIndex[hash]; !present { dbKey = toDbKey(refHeight, c.Hash()) p.chunkIndex[hash] = dbKey } return }() if !present { buf := &bytes.Buffer{} gw := snappy.NewBufferedWriter(buf) chunks.Serialize(c, gw) gw.Close() d.Chk.NoError(p.orderedChunks.Put(dbKey, buf.Bytes(), nil)) return true } return false }