Version Noms SDK and storage (#1841)

ChunkStores provide a Version() method so that anyone directly
using a ChunkStore (e.g. BatchStoreAdaptor) can retrieve and
check the version of the underlying store.

remoteDatabaseServer checks the version of the ChunkStore it's
backed by at startup, and then provides that version as an HTTP
header to all clients. In Go, httpBatchStore checks this header
anytime it gets a response from the server and bails if there's
version skew.

In Go, the responsibility for checking whether the running code and
the data being accessed lies with the BatchStore layer. In JS, there
is code in fetch.js that checks the header mentioned above.

Towards #1561
This commit is contained in:
cmasone-attic
2016-06-21 20:55:07 -07:00
committed by GitHub
parent 9b8d80852c
commit 4d5eb3b334
20 changed files with 436 additions and 162 deletions
+15 -6
View File
@@ -34,12 +34,12 @@ func TestRoot(t *testing.T) {
defer func() { router = nil }()
w := httptest.NewRecorder()
r, _ := http.NewRequest("GET", dbName+constants.RootPath, nil)
r, _ := newRequest("GET", dbName+constants.RootPath, nil)
router.ServeHTTP(w, r)
assert.Equal("sha1-0000000000000000000000000000000000000000", w.Body.String())
w = httptest.NewRecorder()
r, _ = http.NewRequest("OPTIONS", dbName+constants.RootPath, nil)
r, _ = newRequest("OPTIONS", dbName+constants.RootPath, nil)
r.Header.Add("Origin", "http://www.noms.io")
router.ServeHTTP(w, r)
assert.Equal(w.HeaderMap["Access-Control-Allow-Origin"][0], "http://www.noms.io")
@@ -65,7 +65,7 @@ func TestWriteValue(t *testing.T) {
authKey = "anauthkeyvalue"
w := httptest.NewRecorder()
r, err := http.NewRequest("GET", dbName+constants.RootPath, nil)
r, err := newRequest("GET", dbName+constants.RootPath, nil)
assert.NoError(err)
router.ServeHTTP(w, r)
lastRoot := w.Body
@@ -90,21 +90,21 @@ func TestWriteValue(t *testing.T) {
sz.Close()
w = httptest.NewRecorder()
r, err = http.NewRequest("POST", dbName+constants.WriteValuePath+"?access_token="+authKey, ioutil.NopCloser(body))
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&current=%s", lastRoot, types.NewRef(refList).TargetHash())
r, _ = http.NewRequest("POST", dbName+constants.RootPath+"?access_token="+authKey+args, ioutil.NopCloser(body))
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, _ = http.NewRequest("POST", dbName+constants.GetRefsPath, rdr)
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)
@@ -114,3 +114,12 @@ func TestWriteValue(t *testing.T) {
v := types.DecodeValue(ms.Get(whash), datas.NewDatabase(ms))
assert.Equal(testString, string(v.(types.String)))
}
func newRequest(method, url string, body io.Reader) (req *http.Request, err error) {
req, err = http.NewRequest(method, url, body)
if err != nil {
return
}
req.Header.Set(datas.NomsVersionHeader, constants.NomsVersion)
return
}