2011-03-25 00:42:34 +00:00
|
|
|
/*
|
|
|
|
Copyright 2011 Google Inc.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package schema
|
|
|
|
|
|
|
|
import (
|
|
|
|
"camli/test"
|
|
|
|
"io/ioutil"
|
|
|
|
"log"
|
|
|
|
"testing"
|
|
|
|
)
|
|
|
|
|
|
|
|
var _ = log.Printf
|
|
|
|
|
|
|
|
var testFetcher = &test.Fetcher{}
|
|
|
|
|
|
|
|
var blobA = &test.Blob{"AAAAAaaaaa"}
|
|
|
|
var blobB = &test.Blob{"BBBBBbbbbb"}
|
|
|
|
var blobC = &test.Blob{"CCCCCccccc"}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
testFetcher.AddBlob(blobA)
|
|
|
|
testFetcher.AddBlob(blobB)
|
|
|
|
testFetcher.AddBlob(blobC)
|
|
|
|
}
|
|
|
|
|
|
|
|
type readTest struct {
|
|
|
|
parts []*ContentPart
|
|
|
|
skip uint64
|
|
|
|
expected string
|
|
|
|
}
|
|
|
|
|
|
|
|
func part(blob *test.Blob, offset, size uint64) *ContentPart {
|
|
|
|
return &ContentPart{BlobRef: blob.BlobRef(), Size: size, Offset: offset}
|
|
|
|
}
|
|
|
|
|
2011-06-06 18:31:45 +00:00
|
|
|
// filePart returns a ContentPart that references a file JSON schema
|
|
|
|
// blob made of the provided content parts.
|
2011-06-06 20:30:54 +00:00
|
|
|
func filePart(cps []*ContentPart, skip uint64) *ContentPart {
|
2011-06-06 18:31:45 +00:00
|
|
|
m := NewCommonFilenameMap("")
|
|
|
|
fileSize := int64(0)
|
|
|
|
cpl := []ContentPart{}
|
|
|
|
for _, cp := range cps {
|
|
|
|
fileSize += int64(cp.Size)
|
|
|
|
cpl = append(cpl, *cp)
|
|
|
|
}
|
|
|
|
err := PopulateRegularFileMap(m, fileSize, cpl)
|
|
|
|
if err != nil {
|
|
|
|
panic(err.String())
|
|
|
|
}
|
|
|
|
json, err := MapToCamliJson(m)
|
|
|
|
if err != nil {
|
|
|
|
panic(err.String())
|
|
|
|
}
|
|
|
|
tb := &test.Blob{json}
|
|
|
|
testFetcher.AddBlob(tb)
|
2011-06-06 20:30:54 +00:00
|
|
|
return &ContentPart{SubBlobRef: tb.BlobRef(), Size: uint64(fileSize) - skip, Offset: skip}
|
2011-06-06 18:31:45 +00:00
|
|
|
}
|
|
|
|
|
2011-03-25 00:42:34 +00:00
|
|
|
func all(blob *test.Blob) *ContentPart {
|
|
|
|
return part(blob, 0, uint64(blob.Size()))
|
|
|
|
}
|
|
|
|
|
2011-06-06 18:31:45 +00:00
|
|
|
func zero(size uint64) *ContentPart {
|
|
|
|
return &ContentPart{Size: size}
|
|
|
|
}
|
|
|
|
|
2011-03-25 00:42:34 +00:00
|
|
|
func parts(parts ...*ContentPart) []*ContentPart {
|
|
|
|
return parts
|
|
|
|
}
|
|
|
|
|
2011-06-06 15:50:20 +00:00
|
|
|
func sizeSum(parts []*ContentPart) (s uint64) {
|
|
|
|
for _, p := range parts {
|
|
|
|
s += uint64(p.Size)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2011-03-25 00:42:34 +00:00
|
|
|
var readTests = []readTest{
|
|
|
|
{parts(all(blobA)), 0, "AAAAAaaaaa"},
|
|
|
|
{parts(all(blobA)), 2, "AAAaaaaa"},
|
|
|
|
{parts(part(blobA, 0, 5)), 0, "AAAAA"},
|
|
|
|
{parts(part(blobA, 2, 8)), 0, "AAAaaaaa"},
|
|
|
|
{parts(part(blobA, 2, 8)), 1, "AAaaaaa"},
|
|
|
|
{parts(part(blobA, 4, 6)), 0, "Aaaaaa"},
|
|
|
|
{parts(all(blobA), all(blobB)), 0, "AAAAAaaaaaBBBBBbbbbb"},
|
|
|
|
{parts(all(blobA), all(blobB)), 1, "AAAAaaaaaBBBBBbbbbb"},
|
|
|
|
{parts(all(blobA), all(blobB)), 10, "BBBBBbbbbb"},
|
|
|
|
{parts(all(blobA), all(blobB)), 11, "BBBBbbbbb"},
|
|
|
|
{parts(all(blobA), all(blobB)), 100, ""},
|
|
|
|
{parts(all(blobA), all(blobB), all(blobC)), 0, "AAAAAaaaaaBBBBBbbbbbCCCCCccccc"},
|
|
|
|
{parts(all(blobA), all(blobB), all(blobC)), 20, "CCCCCccccc"},
|
|
|
|
{parts(all(blobA), all(blobB), all(blobC)), 22, "CCCccccc"},
|
|
|
|
{parts(part(blobA, 5, 5), part(blobB, 0, 5), part(blobC, 4, 2)), 1, "aaaaBBBBBCc"},
|
2011-06-06 18:31:45 +00:00
|
|
|
{parts(all(blobA), zero(2), all(blobB)), 5, "aaaaa\x00\x00BBBBBbbbbb"},
|
2011-06-06 20:30:54 +00:00
|
|
|
{parts(all(blobB), part(blobC, 4, 2)), 0, "BBBBBbbbbbCc"},
|
|
|
|
{parts(
|
|
|
|
all(blobA),
|
|
|
|
filePart(parts(all(blobB), part(blobC, 4, 2)), 0),
|
|
|
|
part(blobA, 5, 5)),
|
|
|
|
1,
|
|
|
|
"AAAAaaaaa" + "BBBBBbbbbb" + "Cc" + "aaaaa"},
|
|
|
|
{parts(
|
|
|
|
all(blobA),
|
|
|
|
filePart(parts(all(blobB), part(blobC, 4, 2)), 4),
|
|
|
|
part(blobA, 5, 5)),
|
|
|
|
1,
|
|
|
|
"AAAAaaaaa" + "Bbbbbb" + "Cc" + "aaaaa"},
|
2011-03-25 00:42:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestReader(t *testing.T) {
|
|
|
|
for idx, rt := range readTests {
|
|
|
|
ss := new(Superset)
|
|
|
|
ss.Type = "file"
|
|
|
|
ss.Version = 1
|
2011-06-06 15:50:20 +00:00
|
|
|
ss.Size = sizeSum(rt.parts)
|
2011-03-25 00:42:34 +00:00
|
|
|
ss.ContentParts = rt.parts
|
|
|
|
fr := ss.NewFileReader(testFetcher)
|
|
|
|
fr.Skip(rt.skip)
|
|
|
|
all, err := ioutil.ReadAll(fr)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("read error on test %d: %v", idx, err)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if g, e := string(all), rt.expected; e != g {
|
2011-06-06 20:30:54 +00:00
|
|
|
t.Errorf("test %d\nwant %q\n got %q", idx, e, g)
|
2011-03-25 00:42:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|