func TestCloseBucket(t *testing.T) {
	mockdb := &database.MockDatabase{}

	// We're using this to verify closing timestamp.
	mockClock := common.NewFrozenClock()

	// If bucket is not currently open, return failure
	bucket := &model.Bucket{State: model.CLOSED}
	assert.Error(t, CloseBucket(bucket, mockdb, nil, nil))

	bucket_id := "bucket_id_1"

	// If DB throws error in any step, return failure
	bucket = &model.Bucket{State: model.OPEN, Id: bucket_id}
	mockdb.On("UpdateBucket", bucket).Return(database.WrapInternalDatabaseError(fmt.Errorf("foo"))).Once()
	assert.Error(t, CloseBucket(bucket, mockdb, nil, mockClock))

	bucket = &model.Bucket{State: model.OPEN, Id: bucket_id}
	mockdb.On("UpdateBucket", bucket).Return(nil).Once()
	mockdb.On("ListArtifactsInBucket", bucket.Id).Return(nil, database.WrapInternalDatabaseError(fmt.Errorf("err"))).Once()
	assert.Error(t, CloseBucket(bucket, mockdb, nil, mockClock))

	// Closing bucket with no artifacts successfully. Verify bucket state and dateclosed.
	bucket = &model.Bucket{State: model.OPEN, Id: bucket_id}
	mockdb.On("UpdateBucket", bucket).Return(nil).Once()
	mockdb.On("ListArtifactsInBucket", bucket.Id).Return([]model.Artifact{}, nil).Once()
	assert.NoError(t, CloseBucket(bucket, mockdb, nil, mockClock))
	assert.Equal(t, model.CLOSED, bucket.State)
	assert.Equal(t, mockClock.Now(), bucket.DateClosed)

	// Closing bucket with no artifacts successfully. Verify bucket state and dateclosed.
	bucket = &model.Bucket{State: model.OPEN, Id: bucket_id}
	artifact := model.Artifact{Id: 20, State: model.UPLOADED}
	mockdb.On("UpdateBucket", bucket).Return(nil).Once()
	mockdb.On("ListArtifactsInBucket", bucket.Id).Return([]model.Artifact{artifact}, nil).Once()

	assert.NoError(t, CloseBucket(bucket, mockdb, nil, mockClock))
	assert.Equal(t, model.CLOSED, bucket.State)
	assert.Equal(t, mockClock.Now(), bucket.DateClosed)

	mockdb.AssertExpectations(t)
}
func TestCreateBucket(t *testing.T) {
	mockdb := &database.MockDatabase{}

	// Used to verify creation timestamp.
	mockClock := common.NewFrozenClock()

	// var bucket *model.Bucket
	var err error

	// Bad request
	_, err = CreateBucket(mockdb, mockClock, "", "owner")
	assert.Error(t, err)

	_, err = CreateBucket(mockdb, mockClock, "id", "")
	assert.Error(t, err)

	// DB error
	mockdb.On("GetBucket", "id").Return(nil, database.WrapInternalDatabaseError(fmt.Errorf("Internal Error"))).Once()
	_, err = CreateBucket(mockdb, mockClock, "id", "owner")
	assert.Error(t, err)

	// Entity exists
	mockdb.On("GetBucket", "id").Return(&model.Bucket{}, nil).Once()
	_, err = CreateBucket(mockdb, mockClock, "id", "owner")
	assert.Error(t, err)

	// DB error while creating bucket
	mockdb.On("GetBucket", "id").Return(nil, database.NewEntityNotFoundError("ENF")).Once()
	mockdb.On("InsertBucket", mock.AnythingOfType("*model.Bucket")).Return(database.WrapInternalDatabaseError(fmt.Errorf("INT"))).Once()
	_, err = CreateBucket(mockdb, mockClock, "id", "owner")
	assert.Error(t, err)

	// Successfully created bucket
	mockdb.On("GetBucket", "id").Return(nil, database.NewEntityNotFoundError("ENF")).Once()
	mockdb.On("InsertBucket", mock.AnythingOfType("*model.Bucket")).Return(nil).Once()
	bucket, err := CreateBucket(mockdb, mockClock, "id", "owner")
	assert.NoError(t, err)
	assert.NotNil(t, bucket)

	mockdb.AssertExpectations(t)
}
func TestCreateArtifact(t *testing.T) {
	mockdb := &database.MockDatabase{}

	var artifact *model.Artifact
	var err error

	// Create artifact with no name
	artifact, err = CreateArtifact(CreateArtifactReq{}, &model.Bucket{
		State: model.CLOSED,
	}, mockdb)
	assert.Error(t, err)
	assert.Nil(t, artifact)

	// Create artifact in closed bucket
	artifact, err = CreateArtifact(CreateArtifactReq{
		Name: "aName",
	}, &model.Bucket{
		State: model.CLOSED,
	}, mockdb)
	assert.Error(t, err)
	assert.Nil(t, artifact)

	// Duplicate artifact name
	mockdb.On("GetArtifactByName", "bName", "aName").Return(&model.Artifact{}, nil).Once()
	artifact, err = CreateArtifact(CreateArtifactReq{
		Name: "aName",
	}, &model.Bucket{
		State: model.OPEN,
		Id:    "bName",
	}, mockdb)
	assert.Error(t, err)
	assert.Nil(t, artifact)

	// ---------- BEGIN Streamed artifact creation --------------
	mockdb.On("GetArtifactByName", "bName", "aName").Return(nil, database.NewEntityNotFoundError("Notfound")).Once()
	artifact, err = CreateArtifact(CreateArtifactReq{
		Name:    "aName",
		Size:    0, // Invalid size
		Chunked: false,
	}, &model.Bucket{
		State: model.OPEN,
		Id:    "bName",
	}, mockdb)
	assert.Error(t, err)
	assert.Nil(t, artifact)

	// Fail on inserting into DB
	mockdb.On("GetArtifactByName", "bName", "aName").Return(nil, database.NewEntityNotFoundError("Notfound")).Once()
	mockdb.On("InsertArtifact", mock.AnythingOfType("*model.Artifact")).Return(database.WrapInternalDatabaseError(fmt.Errorf("Err"))).Once()
	artifact, err = CreateArtifact(CreateArtifactReq{
		Name:    "aName",
		Size:    10,
		Chunked: false,
	}, &model.Bucket{
		State: model.OPEN,
		Id:    "bName",
	}, mockdb)
	assert.Error(t, err)
	assert.Nil(t, artifact)

	// Successfully create artifact
	mockdb.On("GetArtifactByName", "bName", "aName").Return(nil, database.NewEntityNotFoundError("Notfound")).Once()
	mockdb.On("InsertArtifact", mock.AnythingOfType("*model.Artifact")).Return(nil).Once()
	artifact, err = CreateArtifact(CreateArtifactReq{
		Name:    "aName",
		Size:    10,
		Chunked: false,
	}, &model.Bucket{
		State: model.OPEN,
		Id:    "bName",
	}, mockdb)
	assert.NoError(t, err)
	assert.NotNil(t, artifact)
	assert.Equal(t, "aName", artifact.Name)
	assert.Equal(t, "bName", artifact.BucketId)
	assert.Equal(t, model.WAITING_FOR_UPLOAD, artifact.State)
	assert.Equal(t, int64(10), artifact.Size)
	// ---------- END Streamed artifact creation --------------

	// ---------- BEGIN Chunked artifact creation --------------
	// Fail on inserting into DB
	mockdb.On("GetArtifactByName", "bName", "aName").Return(nil, database.NewEntityNotFoundError("Notfound")).Once()
	mockdb.On("InsertArtifact", mock.AnythingOfType("*model.Artifact")).Return(database.WrapInternalDatabaseError(fmt.Errorf("Err"))).Once()
	artifact, err = CreateArtifact(CreateArtifactReq{
		Name:    "aName",
		Chunked: true,
	}, &model.Bucket{
		State: model.OPEN,
		Id:    "bName",
	}, mockdb)
	assert.Error(t, err)
	assert.Nil(t, artifact)

	// Successfully create artifact
	mockdb.On("GetArtifactByName", "bName", "aName").Return(nil, database.NewEntityNotFoundError("Notfound")).Once()
	mockdb.On("InsertArtifact", mock.AnythingOfType("*model.Artifact")).Return(nil).Once()
	artifact, err = CreateArtifact(CreateArtifactReq{
		Name:         "aName",
		Chunked:      true,
		DeadlineMins: 20,
	}, &model.Bucket{
		State: model.OPEN,
		Id:    "bName",
	}, mockdb)
	assert.NoError(t, err)
	assert.NotNil(t, artifact)
	assert.Equal(t, "aName", artifact.Name)
	assert.Equal(t, "bName", artifact.BucketId)
	assert.Equal(t, model.APPENDING, artifact.State)
	assert.Equal(t, int64(0), artifact.Size)
	// ---------- END Streamed artifact creation --------------

	mockdb.AssertExpectations(t)
}