示例#1
0
func (s *S) TestAuthAddUserReplaces(c *C) {
	session, err := mgo.Dial("localhost:40002")
	c.Assert(err, IsNil)
	defer session.Close()

	admindb := session.DB("admin")
	err = admindb.Login("root", "rapadura")
	c.Assert(err, IsNil)

	mydb := session.DB("mydb")
	err = mydb.AddUser("myuser", "myoldpass", false)
	c.Assert(err, IsNil)
	err = mydb.AddUser("myuser", "mynewpass", true)
	c.Assert(err, IsNil)

	admindb.Logout()

	err = mydb.Login("myuser", "myoldpass")
	c.Assert(err, ErrorMatches, "auth fails")
	err = mydb.Login("myuser", "mynewpass")
	c.Assert(err, IsNil)

	// ReadOnly flag was changed too.
	err = mydb.C("mycoll").Insert(M{"n": 1})
	c.Assert(err, ErrorMatches, "unauthorized")
}
示例#2
0
func (s *S) TestAuthLoginChangePassword(c *C) {
	session, err := mgo.Dial("localhost:40002")
	c.Assert(err, IsNil)
	defer session.Close()

	admindb := session.DB("admin")
	err = admindb.Login("root", "rapadura")
	c.Assert(err, IsNil)

	mydb := session.DB("mydb")
	err = mydb.AddUser("myuser", "myoldpass", false)
	c.Assert(err, IsNil)

	err = mydb.Login("myuser", "myoldpass")
	c.Assert(err, IsNil)

	err = mydb.AddUser("myuser", "mynewpass", true)
	c.Assert(err, IsNil)

	err = mydb.Login("myuser", "mynewpass")
	c.Assert(err, IsNil)

	admindb.Logout()

	// The second login must be in effect, which means read-only.
	err = mydb.C("mycoll").Insert(M{"n": 1})
	c.Assert(err, ErrorMatches, "unauthorized")
}
示例#3
0
func (s *S) TestAuthLoginSwitchUser(c *C) {
	session, err := mgo.Dial("localhost:40002")
	c.Assert(err, IsNil)
	defer session.Close()

	admindb := session.DB("admin")
	err = admindb.Login("root", "rapadura")
	c.Assert(err, IsNil)

	coll := session.DB("mydb").C("mycoll")
	err = coll.Insert(M{"n": 1})
	c.Assert(err, IsNil)

	err = admindb.Login("reader", "rapadura")
	c.Assert(err, IsNil)

	// Can't write.
	err = coll.Insert(M{"n": 1})
	c.Assert(err, ErrorMatches, "unauthorized")

	// But can read.
	result := struct{ N int }{}
	err = coll.Find(nil).One(&result)
	c.Assert(err, IsNil)
	c.Assert(result.N, Equals, 1)
}
示例#4
0
func (s *S) TestGridFSOpen(c *C) {
	session, err := mgo.Dial("localhost:40011")
	c.Assert(err, IsNil)
	defer session.Close()

	db := session.DB("mydb")

	gfs := db.GridFS("fs")

	file, err := gfs.Create("myfile.txt")
	c.Assert(err, IsNil)
	file.Write([]byte{'1'})
	file.Close()

	file, err = gfs.Create("myfile.txt")
	c.Assert(err, IsNil)
	file.Write([]byte{'2'})
	file.Close()

	file, err = gfs.Open("myfile.txt")
	c.Assert(err, IsNil)
	defer file.Close()

	var b [1]byte

	_, err = file.Read(b[:])
	c.Assert(err, IsNil)
	c.Assert(string(b[:]), Equals, "2")
}
示例#5
0
func (s *S) TestGridFSRemove(c *C) {
	session, err := mgo.Dial("localhost:40011")
	c.Assert(err, IsNil)
	defer session.Close()

	db := session.DB("mydb")

	gfs := db.GridFS("fs")

	file, err := gfs.Create("myfile.txt")
	c.Assert(err, IsNil)
	file.Write([]byte{'1'})
	file.Close()

	file, err = gfs.Create("myfile.txt")
	c.Assert(err, IsNil)
	file.Write([]byte{'2'})
	file.Close()

	err = gfs.Remove("myfile.txt")
	c.Assert(err, IsNil)

	_, err = gfs.Open("myfile.txt")
	c.Assert(err == mgo.ErrNotFound, Equals, true)

	n, err := db.C("fs.chunks").Find(nil).Count()
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 0)
}
示例#6
0
func (s *S) TestAuthAddUser(c *C) {
	session, err := mgo.Dial("localhost:40002")
	c.Assert(err, IsNil)
	defer session.Close()

	admindb := session.DB("admin")
	err = admindb.Login("root", "rapadura")
	c.Assert(err, IsNil)

	mydb := session.DB("mydb")
	err = mydb.AddUser("myruser", "mypass", true)
	c.Assert(err, IsNil)
	err = mydb.AddUser("mywuser", "mypass", false)
	c.Assert(err, IsNil)

	err = mydb.Login("myruser", "mypass")
	c.Assert(err, IsNil)

	admindb.Logout()

	coll := session.DB("mydb").C("mycoll")
	err = coll.Insert(M{"n": 1})
	c.Assert(err, ErrorMatches, "unauthorized")

	err = mydb.Login("mywuser", "mypass")
	c.Assert(err, IsNil)

	err = coll.Insert(M{"n": 1})
	c.Assert(err, IsNil)
}
示例#7
0
func (s *S) TestGridFSReadChunking(c *C) {
	session, err := mgo.Dial("localhost:40011")
	c.Assert(err, IsNil)
	defer session.Close()

	db := session.DB("mydb")

	gfs := db.GridFS("fs")

	file, err := gfs.Create("")
	c.Assert(err, IsNil)

	id := file.Id()

	file.SetChunkSize(5)

	n, err := file.Write([]byte("abcdefghijklmnopqrstuv"))
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 22)

	err = file.Close()
	c.Assert(err, IsNil)

	file, err = gfs.OpenId(id)
	c.Assert(err, IsNil)

	b := make([]byte, 30)

	// Smaller than the chunk size.
	n, err = file.Read(b[:3])
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 3)
	c.Assert(b[:3], DeepEquals, []byte("abc"))

	// Boundary in the middle.
	n, err = file.Read(b[:4])
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 4)
	c.Assert(b[:4], DeepEquals, []byte("defg"))

	// Boundary at the end.
	n, err = file.Read(b[:3])
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 3)
	c.Assert(b[:3], DeepEquals, []byte("hij"))

	// Larger than the chunk size, with 3 chunks.
	n, err = file.Read(b)
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 12)
	c.Assert(b[:12], DeepEquals, []byte("klmnopqrstuv"))

	n, err = file.Read(b)
	c.Assert(n, Equals, 0)
	c.Assert(err == io.EOF, Equals, true)

	err = file.Close()
	c.Assert(err, IsNil)
}
示例#8
0
func (s *S) TestAuthURLWrongCredentials(c *C) {
	session, err := mgo.Dial("mongodb://*****:*****@localhost:40002/")
	if session != nil {
		session.Close()
	}
	c.Assert(err, ErrorMatches, "auth fails")
	c.Assert(session, IsNil)
}
示例#9
0
func (s *S) TestAuthURL(c *C) {
	session, err := mgo.Dial("mongodb://*****:*****@localhost:40002/")
	c.Assert(err, IsNil)
	defer session.Close()

	err = session.DB("mydb").C("mycoll").Insert(M{"n": 1})
	c.Assert(err, IsNil)
}
示例#10
0
func (s *S) TestGridFSOpenNext(c *C) {
	session, err := mgo.Dial("localhost:40011")
	c.Assert(err, IsNil)
	defer session.Close()

	db := session.DB("mydb")

	gfs := db.GridFS("fs")

	file, err := gfs.Create("myfile1.txt")
	c.Assert(err, IsNil)
	file.Write([]byte{'1'})
	file.Close()

	file, err = gfs.Create("myfile2.txt")
	c.Assert(err, IsNil)
	file.Write([]byte{'2'})
	file.Close()

	var f *mgo.GridFile
	var b [1]byte

	iter := gfs.Find(nil).Sort("-filename").Iter()

	ok := gfs.OpenNext(iter, &f)
	c.Assert(ok, Equals, true)
	c.Check(f.Name(), Equals, "myfile2.txt")

	_, err = f.Read(b[:])
	c.Assert(err, IsNil)
	c.Assert(string(b[:]), Equals, "2")

	ok = gfs.OpenNext(iter, &f)
	c.Assert(ok, Equals, true)
	c.Check(f.Name(), Equals, "myfile1.txt")

	_, err = f.Read(b[:])
	c.Assert(err, IsNil)
	c.Assert(string(b[:]), Equals, "1")

	ok = gfs.OpenNext(iter, &f)
	c.Assert(ok, Equals, false)
	c.Assert(iter.Err(), IsNil)
	c.Assert(f, IsNil)

	// Do it again with a more restrictive query to make sure
	// it's actually taken into account.
	iter = gfs.Find(bson.M{"filename": "myfile1.txt"}).Iter()

	ok = gfs.OpenNext(iter, &f)
	c.Assert(ok, Equals, true)
	c.Check(f.Name(), Equals, "myfile1.txt")

	ok = gfs.OpenNext(iter, &f)
	c.Assert(ok, Equals, false)
	c.Assert(iter.Err(), IsNil)
	c.Assert(f, IsNil)
}
示例#11
0
func (s *S) TestAuthLoginCachingAcrossPoolWithLogout(c *C) {
	// Now verify that logouts are properly flushed if they
	// are not revalidated after leaving the pool.

	session, err := mgo.Dial("localhost:40002")
	c.Assert(err, IsNil)
	defer session.Close()

	admindb := session.DB("admin")
	err = admindb.Login("root", "rapadura")
	c.Assert(err, IsNil)

	// Add another user to test the logout case at the same time.
	mydb := session.DB("mydb")
	err = mydb.AddUser("myuser", "mypass", true)
	c.Assert(err, IsNil)

	err = mydb.Login("myuser", "mypass")
	c.Assert(err, IsNil)

	// Just some data to query later.
	err = session.DB("mydb").C("mycoll").Insert(M{"n": 1})
	c.Assert(err, IsNil)

	// Give socket back to pool.
	session.Refresh()

	// Brand new session, should use socket from the pool.
	other := session.New()
	defer other.Close()

	oldStats := mgo.GetStats()

	err = other.DB("mydb").Login("myuser", "mypass")
	c.Assert(err, IsNil)

	// Login was cached, so no ops.
	newStats := mgo.GetStats()
	c.Assert(newStats.SentOps, Equals, oldStats.SentOps)

	// Can't write, since root has been implicitly logged out
	// when the collection went into the pool, and not revalidated.
	err = other.DB("mydb").C("mycoll").Insert(M{"n": 1})
	c.Assert(err, ErrorMatches, "unauthorized")

	// But can read due to the revalidated myuser login.
	result := struct{ N int }{}
	err = other.DB("mydb").C("mycoll").Find(nil).One(&result)
	c.Assert(err, IsNil)
	c.Assert(result.N, Equals, 1)
}
示例#12
0
func (s *S) TestAuthLoginCachingAcrossPool(c *C) {
	// Logins are cached even when the conenction goes back
	// into the pool.

	session, err := mgo.Dial("localhost:40002")
	c.Assert(err, IsNil)
	defer session.Close()

	admindb := session.DB("admin")
	err = admindb.Login("root", "rapadura")
	c.Assert(err, IsNil)

	// Add another user to test the logout case at the same time.
	mydb := session.DB("mydb")
	err = mydb.AddUser("myuser", "mypass", false)
	c.Assert(err, IsNil)

	err = mydb.Login("myuser", "mypass")
	c.Assert(err, IsNil)

	// Logout root explicitly, to test both cases.
	admindb.Logout()

	// Give socket back to pool.
	session.Refresh()

	// Brand new session, should use socket from the pool.
	other := session.New()
	defer other.Close()

	oldStats := mgo.GetStats()

	err = other.DB("admin").Login("root", "rapadura")
	c.Assert(err, IsNil)
	err = other.DB("mydb").Login("myuser", "mypass")
	c.Assert(err, IsNil)

	// Both logins were cached, so no ops.
	newStats := mgo.GetStats()
	c.Assert(newStats.SentOps, Equals, oldStats.SentOps)

	// And they actually worked.
	err = other.DB("mydb").C("mycoll").Insert(M{"n": 1})
	c.Assert(err, IsNil)

	other.DB("admin").Logout()

	err = other.DB("mydb").C("mycoll").Insert(M{"n": 1})
	c.Assert(err, IsNil)
}
示例#13
0
func (s *S) TestAuthLoginCachingWithSessionRefresh(c *C) {
	session, err := mgo.Dial("localhost:40002")
	c.Assert(err, IsNil)
	defer session.Close()

	admindb := session.DB("admin")
	err = admindb.Login("root", "rapadura")
	c.Assert(err, IsNil)

	session.Refresh()

	coll := session.DB("mydb").C("mycoll")
	err = coll.Insert(M{"n": 1})
	c.Assert(err, IsNil)
}
示例#14
0
func (s *S) TestGridFSOpenNotFound(c *C) {
	session, err := mgo.Dial("localhost:40011")
	c.Assert(err, IsNil)
	defer session.Close()

	db := session.DB("mydb")

	gfs := db.GridFS("fs")
	file, err := gfs.OpenId("non-existent")
	c.Assert(err == mgo.ErrNotFound, Equals, true)
	c.Assert(file, IsNil)

	file, err = gfs.Open("non-existent")
	c.Assert(err == mgo.ErrNotFound, Equals, true)
	c.Assert(file, IsNil)
}
示例#15
0
func (s *S) TestAuthLoginCachingWithNewSession(c *C) {
	session, err := mgo.Dial("localhost:40002")
	c.Assert(err, IsNil)
	defer session.Close()

	admindb := session.DB("admin")
	err = admindb.Login("root", "rapadura")
	c.Assert(err, IsNil)

	session = session.New()
	defer session.Close()

	coll := session.DB("mydb").C("mycoll")
	err = coll.Insert(M{"n": 1})
	c.Assert(err, ErrorMatches, "unauthorized")
}
示例#16
0
func (s *S) TestAuthLoginTwiceDoesNothing(c *C) {
	session, err := mgo.Dial("localhost:40002")
	c.Assert(err, IsNil)
	defer session.Close()

	admindb := session.DB("admin")
	err = admindb.Login("root", "rapadura")
	c.Assert(err, IsNil)

	oldStats := mgo.GetStats()

	err = admindb.Login("root", "rapadura")
	c.Assert(err, IsNil)

	newStats := mgo.GetStats()
	c.Assert(newStats.SentOps, Equals, oldStats.SentOps)
}
示例#17
0
func (s *S) TestAuthURLWithNewSession(c *C) {
	// When authentication is in the URL, the new session will
	// actually carry it on as well, even if logged out explicitly.
	session, err := mgo.Dial("mongodb://*****:*****@localhost:40002/")
	c.Assert(err, IsNil)
	defer session.Close()

	session.DB("admin").Logout()

	// Do it twice to ensure it passes the needed data on.
	session = session.New()
	defer session.Close()
	session = session.New()
	defer session.Close()

	err = session.DB("mydb").C("mycoll").Insert(M{"n": 1})
	c.Assert(err, IsNil)
}
示例#18
0
func (s *S) TestAuthRemoveUser(c *C) {
	session, err := mgo.Dial("localhost:40002")
	c.Assert(err, IsNil)
	defer session.Close()

	admindb := session.DB("admin")
	err = admindb.Login("root", "rapadura")
	c.Assert(err, IsNil)

	mydb := session.DB("mydb")
	err = mydb.AddUser("myuser", "mypass", true)
	c.Assert(err, IsNil)
	err = mydb.RemoveUser("myuser")
	c.Assert(err, IsNil)

	err = mydb.Login("myuser", "mypass")
	c.Assert(err, ErrorMatches, "auth fails")
}
示例#19
0
func (s *S) TestAuthLoginLogoutAll(c *C) {
	session, err := mgo.Dial("localhost:40002")
	c.Assert(err, IsNil)
	defer session.Close()

	admindb := session.DB("admin")
	err = admindb.Login("root", "rapadura")
	c.Assert(err, IsNil)

	session.LogoutAll()

	coll := session.DB("mydb").C("mycoll")
	err = coll.Insert(M{"n": 1})
	c.Assert(err, ErrorMatches, "unauthorized")

	// Must have dropped auth from the session too.
	session = session.Copy()
	defer session.Close()

	coll = session.DB("mydb").C("mycoll")
	err = coll.Insert(M{"n": 1})
	c.Assert(err, ErrorMatches, "unauthorized")
}
示例#20
0
func (s *S) TestGridFSRemoveId(c *C) {
	session, err := mgo.Dial("localhost:40011")
	c.Assert(err, IsNil)
	defer session.Close()

	db := session.DB("mydb")

	gfs := db.GridFS("fs")

	file, err := gfs.Create("myfile.txt")
	c.Assert(err, IsNil)
	file.Write([]byte{'1'})
	file.Close()

	file, err = gfs.Create("myfile.txt")
	c.Assert(err, IsNil)
	file.Write([]byte{'2'})
	id := file.Id()
	file.Close()

	err = gfs.RemoveId(id)
	c.Assert(err, IsNil)

	file, err = gfs.Open("myfile.txt")
	c.Assert(err, IsNil)
	defer file.Close()

	var b [1]byte

	_, err = file.Read(b[:])
	c.Assert(err, IsNil)
	c.Assert(string(b[:]), Equals, "1")

	n, err := db.C("fs.chunks").Find(M{"files_id": id}).Count()
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 0)
}
示例#21
0
func (s *S) TestAuthEventual(c *C) {
	// Eventual sessions don't keep sockets around, so they are
	// an interesting test case.
	session, err := mgo.Dial("localhost:40002")
	c.Assert(err, IsNil)
	defer session.Close()

	admindb := session.DB("admin")
	err = admindb.Login("root", "rapadura")
	c.Assert(err, IsNil)

	err = session.DB("mydb").C("mycoll").Insert(M{"n": 1})
	c.Assert(err, IsNil)

	var wg sync.WaitGroup
	wg.Add(20)

	for i := 0; i != 10; i++ {
		go func() {
			defer wg.Done()
			var result struct{ N int }
			err := session.DB("mydb").C("mycoll").Find(nil).One(&result)
			c.Assert(err, IsNil)
			c.Assert(result.N, Equals, 1)
		}()
	}

	for i := 0; i != 10; i++ {
		go func() {
			defer wg.Done()
			err := session.DB("mydb").C("mycoll").Insert(M{"n": 1})
			c.Assert(err, IsNil)
		}()
	}

	wg.Wait()
}
示例#22
0
func (s *S) TestGridFSReadAll(c *C) {
	session, err := mgo.Dial("localhost:40011")
	c.Assert(err, IsNil)
	defer session.Close()

	db := session.DB("mydb")

	gfs := db.GridFS("fs")
	file, err := gfs.Create("")
	c.Assert(err, IsNil)
	id := file.Id()

	file.SetChunkSize(5)

	n, err := file.Write([]byte("abcdefghijklmnopqrstuv"))
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 22)

	err = file.Close()
	c.Assert(err, IsNil)

	file, err = gfs.OpenId(id)
	c.Assert(err, IsNil)

	b := make([]byte, 30)
	n, err = file.Read(b)
	c.Assert(n, Equals, 22)
	c.Assert(err, IsNil)

	n, err = file.Read(b)
	c.Assert(n, Equals, 0)
	c.Assert(err == io.EOF, Equals, true)

	err = file.Close()
	c.Assert(err, IsNil)
}
示例#23
0
func (s *S) TestGridFSSeek(c *C) {
	session, err := mgo.Dial("localhost:40011")
	c.Assert(err, IsNil)
	defer session.Close()

	db := session.DB("mydb")

	gfs := db.GridFS("fs")
	file, err := gfs.Create("")
	c.Assert(err, IsNil)
	id := file.Id()

	file.SetChunkSize(5)

	n, err := file.Write([]byte("abcdefghijklmnopqrstuv"))
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 22)

	err = file.Close()
	c.Assert(err, IsNil)

	b := make([]byte, 5)

	file, err = gfs.OpenId(id)
	c.Assert(err, IsNil)

	o, err := file.Seek(3, os.SEEK_SET)
	c.Assert(err, IsNil)
	c.Assert(o, Equals, int64(3))
	_, err = file.Read(b)
	c.Assert(err, IsNil)
	c.Assert(b, DeepEquals, []byte("defgh"))

	o, err = file.Seek(5, os.SEEK_CUR)
	c.Assert(err, IsNil)
	c.Assert(o, Equals, int64(13))
	_, err = file.Read(b)
	c.Assert(err, IsNil)
	c.Assert(b, DeepEquals, []byte("nopqr"))

	o, err = file.Seek(-10, os.SEEK_END)
	c.Assert(err, IsNil)
	c.Assert(o, Equals, int64(12))
	_, err = file.Read(b)
	c.Assert(err, IsNil)
	c.Assert(b, DeepEquals, []byte("mnopq"))

	o, err = file.Seek(8, os.SEEK_SET)
	c.Assert(err, IsNil)
	c.Assert(o, Equals, int64(8))
	_, err = file.Read(b)
	c.Assert(err, IsNil)
	c.Assert(b, DeepEquals, []byte("ijklm"))

	// Trivial seek forward within same chunk. Already
	// got the data, shouldn't touch the database.
	sent := mgo.GetStats().SentOps
	o, err = file.Seek(1, os.SEEK_CUR)
	c.Assert(err, IsNil)
	c.Assert(o, Equals, int64(14))
	c.Assert(mgo.GetStats().SentOps, Equals, sent)
	_, err = file.Read(b)
	c.Assert(err, IsNil)
	c.Assert(b, DeepEquals, []byte("opqrs"))

	// Try seeking past end of file.
	file.Seek(3, os.SEEK_SET)
	o, err = file.Seek(23, os.SEEK_SET)
	c.Assert(err, ErrorMatches, "Seek past end of file")
	c.Assert(o, Equals, int64(3))
}
示例#24
0
func (s *S) TestGridFSCreate(c *C) {
	session, err := mgo.Dial("localhost:40011")
	c.Assert(err, IsNil)
	defer session.Close()

	db := session.DB("mydb")

	before := bson.Now()

	gfs := db.GridFS("fs")
	file, err := gfs.Create("")
	c.Assert(err, IsNil)

	n, err := file.Write([]byte("some data"))
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 9)

	err = file.Close()
	c.Assert(err, IsNil)

	after := bson.Now()

	// Check the file information.
	result := M{}
	err = db.C("fs.files").Find(nil).One(result)
	c.Assert(err, IsNil)

	fileId, ok := result["_id"].(bson.ObjectId)
	c.Assert(ok, Equals, true)
	c.Assert(fileId.Valid(), Equals, true)
	result["_id"] = "<id>"

	ud, ok := result["uploadDate"].(time.Time)
	c.Assert(ok, Equals, true)
	c.Assert(ud.After(before) && ud.Before(after), Equals, true)
	result["uploadDate"] = "<timestamp>"

	expected := M{
		"_id":        "<id>",
		"length":     9,
		"chunkSize":  262144,
		"uploadDate": "<timestamp>",
		"md5":        "1e50210a0202497fb79bc38b6ade6c34",
	}
	c.Assert(result, DeepEquals, expected)

	// Check the chunk.
	result = M{}
	err = db.C("fs.chunks").Find(nil).One(result)
	c.Assert(err, IsNil)

	chunkId, ok := result["_id"].(bson.ObjectId)
	c.Assert(ok, Equals, true)
	c.Assert(chunkId.Valid(), Equals, true)
	result["_id"] = "<id>"

	expected = M{
		"_id":      "<id>",
		"files_id": fileId,
		"n":        0,
		"data":     []byte("some data"),
	}
	c.Assert(result, DeepEquals, expected)

	// Check that an index was created.
	indexes, err := db.C("fs.chunks").Indexes()
	c.Assert(err, IsNil)
	c.Assert(len(indexes), Equals, 2)
	c.Assert(indexes[1].Key, DeepEquals, []string{"files_id", "n"})
}
示例#25
0
func (s *S) TestGridFSCreateWithChunking(c *C) {
	session, err := mgo.Dial("localhost:40011")
	c.Assert(err, IsNil)
	defer session.Close()

	db := session.DB("mydb")

	gfs := db.GridFS("fs")

	file, err := gfs.Create("")
	c.Assert(err, IsNil)

	file.SetChunkSize(5)

	// Smaller than the chunk size.
	n, err := file.Write([]byte("abc"))
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 3)

	// Boundary in the middle.
	n, err = file.Write([]byte("defg"))
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 4)

	// Boundary at the end.
	n, err = file.Write([]byte("hij"))
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 3)

	// Larger than the chunk size, with 3 chunks.
	n, err = file.Write([]byte("klmnopqrstuv"))
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 12)

	err = file.Close()
	c.Assert(err, IsNil)

	// Check the file information.
	result := M{}
	err = db.C("fs.files").Find(nil).One(result)
	c.Assert(err, IsNil)

	fileId, _ := result["_id"].(bson.ObjectId)
	c.Assert(fileId.Valid(), Equals, true)
	result["_id"] = "<id>"
	result["uploadDate"] = "<timestamp>"

	expected := M{
		"_id":        "<id>",
		"length":     22,
		"chunkSize":  5,
		"uploadDate": "<timestamp>",
		"md5":        "44a66044834cbe55040089cabfc102d5",
	}
	c.Assert(result, DeepEquals, expected)

	// Check the chunks.
	iter := db.C("fs.chunks").Find(nil).Sort("n").Iter()
	dataChunks := []string{"abcde", "fghij", "klmno", "pqrst", "uv"}
	for i := 0; ; i++ {
		result = M{}
		if !iter.Next(result) {
			if i != 5 {
				c.Fatalf("Expected 5 chunks, got %d", i)
			}
			break
		}
		c.Assert(iter.Err(), IsNil)

		result["_id"] = "<id>"

		expected = M{
			"_id":      "<id>",
			"files_id": fileId,
			"n":        i,
			"data":     []byte(dataChunks[i]),
		}
		c.Assert(result, DeepEquals, expected)
	}
}
示例#26
0
func (s *S) TestGridFSFileDetails(c *C) {
	session, err := mgo.Dial("localhost:40011")
	c.Assert(err, IsNil)
	defer session.Close()

	db := session.DB("mydb")

	gfs := db.GridFS("fs")

	file, err := gfs.Create("myfile1.txt")
	c.Assert(err, IsNil)

	n, err := file.Write([]byte("some"))
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 4)

	c.Assert(file.Size(), Equals, int64(4))

	n, err = file.Write([]byte(" data"))
	c.Assert(err, IsNil)
	c.Assert(n, Equals, 5)

	c.Assert(file.Size(), Equals, int64(9))

	id, _ := file.Id().(bson.ObjectId)
	c.Assert(id.Valid(), Equals, true)
	c.Assert(file.Name(), Equals, "myfile1.txt")
	c.Assert(file.ContentType(), Equals, "")

	var info interface{}
	err = file.GetMeta(&info)
	c.Assert(err, IsNil)
	c.Assert(info, IsNil)

	file.SetId("myid")
	file.SetName("myfile2.txt")
	file.SetContentType("text/plain")
	file.SetMeta(M{"any": "thing"})

	c.Assert(file.Id(), Equals, "myid")
	c.Assert(file.Name(), Equals, "myfile2.txt")
	c.Assert(file.ContentType(), Equals, "text/plain")

	err = file.GetMeta(&info)
	c.Assert(err, IsNil)
	c.Assert(info, DeepEquals, bson.M{"any": "thing"})

	err = file.Close()
	c.Assert(err, IsNil)

	c.Assert(file.MD5(), Equals, "1e50210a0202497fb79bc38b6ade6c34")

	ud := file.UploadDate()
	now := time.Now()
	c.Assert(ud.Before(now), Equals, true)
	c.Assert(ud.After(now.Add(-3*time.Second)), Equals, true)

	result := M{}
	err = db.C("fs.files").Find(nil).One(result)
	c.Assert(err, IsNil)

	result["uploadDate"] = "<timestamp>"

	expected := M{
		"_id":         "myid",
		"length":      9,
		"chunkSize":   262144,
		"uploadDate":  "<timestamp>",
		"md5":         "1e50210a0202497fb79bc38b6ade6c34",
		"filename":    "myfile2.txt",
		"contentType": "text/plain",
		"metadata":    bson.M{"any": "thing"},
	}
	c.Assert(result, DeepEquals, expected)
}