func TestBackupWithExcludeBuckets(t *testing.T) {
	defer cleanup()
	defer deleteAllBuckets(testHost, t)
	cleanup()
	deleteAllBuckets(testHost, t)
	createCouchbaseBucket(testHost, "default", "", t)
	createCouchbaseBucket(testHost, "saslbucket", "saslpwd", t)

	loadData(testHost, "default", "", 5000, "full", t)
	loadData(testHost, "saslbucket", "saslpwd", 2500, "full", t)

	exclude_buckets := []string{"default"}
	config := value.CreateBackupConfig("", "", exclude_buckets,
		make([]string, 0), make([]string, 0), make([]string, 0),
		false, false, false, false, false, false, false, false)

	a, err := archive.MountArchive(testDir, true)
	checkError(err, t)

	checkError(a.CreateBackup("full-backup-test", config), t)

	name, err := executeBackup(a, "full-backup-test", "archive", testHost, restUsername, restPassword,
		4, false, false)
	checkError(err, t)

	info, err := a.IncrBackupInfo("full-backup-test", name)
	checkError(err, t)

	count := info["saslbucket"].NumDocs
	if count != 2500 {
		t.Fatal("Expected to backup 2500 items, got " + strconv.Itoa(count))
	}
}
func TestBackupNoBucketsExist(t *testing.T) {
	defer cleanup()
	defer deleteAllBuckets(testHost, t)
	cleanup()
	deleteAllBuckets(testHost, t)

	config := value.CreateBackupConfig("", "", make([]string, 0),
		make([]string, 0), make([]string, 0), make([]string, 0),
		false, false, false, false, false, false, false, false)

	a, err := archive.MountArchive(testDir, true)
	checkError(err, t)

	checkError(a.CreateBackup("full-backup-test", config), t)

	name, err := executeBackup(a, "full-backup-test", "archive", testHost, restUsername, restPassword,
		4, false, false)
	checkError(err, t)

	info, err := a.IncrBackupInfo("full-backup-test", name)
	checkError(err, t)

	if len(info) != 0 {
		t.Fatal("Expected that no buckets were backed up")
	}
}
func TestBackupDeleteBucketBackupAgain(t *testing.T) {
	defer cleanup()
	defer deleteAllBuckets(testHost, t)
	cleanup()
	deleteAllBuckets(testHost, t)
	createCouchbaseBucket(testHost, "default", "", t)

	backupName := "backupdelbackup-test"

	loadData(testHost, "default", "", 5000, "one", t)

	config := value.CreateBackupConfig("", "", make([]string, 0),
		make([]string, 0), make([]string, 0), make([]string, 0),
		false, false, false, false, false, false, false, false)

	a, err := archive.MountArchive(testDir, true)
	checkError(err, t)

	checkError(a.CreateBackup(backupName, config), t)

	name, err := executeBackup(a, backupName, "archive", testHost, restUsername, restPassword,
		4, false, false)
	checkError(err, t)

	info, err := a.IncrBackupInfo(backupName, name)
	checkError(err, t)

	count := info["default"].NumDocs
	if count != 5000 {
		t.Fatal("Expected to backup 5000 items, got " + strconv.Itoa(count))
	}

	deleteAllBuckets(testHost, t)
	createCouchbaseBucket(testHost, "default", "", t)
	loadData(testHost, "default", "", 10000, "two", t)

	name, err = executeBackup(a, backupName, "archive", testHost, restUsername, restPassword,
		4, false, false)
	checkError(err, t)

	info, err = a.IncrBackupInfo(backupName, name)
	checkError(err, t)

	count = info["default"].NumDocs
	if count != 10000 {
		t.Fatal("Expected to backup 10000 items, got " + strconv.Itoa(count))
	}
}
func TestBackupBadPassword(t *testing.T) {
	defer cleanup()
	defer deleteAllBuckets(testHost, t)
	cleanup()
	deleteAllBuckets(testHost, t)
	createCouchbaseBucket(testHost, "default", "", t)

	loadData(testHost, "default", "", 5000, "full", t)

	backupName := "badpassword-test"
	config := value.CreateBackupConfig("", "", make([]string, 0),
		make([]string, 0), make([]string, 0), make([]string, 0),
		false, false, false, false, false, false, false, false)

	a, err := archive.MountArchive(testDir, true)
	checkError(err, t)

	checkError(a.CreateBackup(backupName, config), t)

	// Test bad password
	_, err = executeBackup(a, backupName, "archive", testHost, restUsername, "badpassword",
		4, false, false)
	if err == nil {
		t.Fatal("Backup succeeded, but expected failure")
	}

	if herr, ok := err.(couchbase.HttpError); !ok {
		t.Fatal("Expected error to be of type HttpError")
		if herr.Code() != 401 {
			t.Fatal("Expected HttpError to be an authentication error")
		}
	}

	// Test bad username
	_, err = executeBackup(a, backupName, "archive", testHost, "Adminiator", restPassword,
		4, false, false)
	if err == nil {
		t.Fatal("Backup succeeded, but expected failure")
	}

	if herr, ok := err.(couchbase.HttpError); !ok {
		t.Fatal("Expected error to be of type HttpError")
		if herr.Code() != 401 {
			t.Fatal("Expected HttpError to be an authentication error")
		}
	}
}
func TestBackupWithMemcachedBucket(t *testing.T) {
	defer cleanup()
	defer deleteAllBuckets(testHost, t)
	cleanup()
	deleteAllBuckets(testHost, t)
	createCouchbaseBucket(testHost, "default", "", t)
	createMemcachedBucket(testHost, "mcd", "", t)

	backupName := "skip-mcd-bucket-test"

	loadData(testHost, "default", "", 5000, "one", t)

	config := value.CreateBackupConfig("", "", make([]string, 0),
		make([]string, 0), make([]string, 0), make([]string, 0),
		false, false, false, false, false, false, false, false)

	a, err := archive.MountArchive(testDir, true)
	checkError(err, t)

	checkError(a.CreateBackup(backupName, config), t)

	name, err := executeBackup(a, backupName, "archive", testHost, restUsername, restPassword,
		4, false, false)
	checkError(err, t)

	info, err := a.IncrBackupInfo(backupName, name)
	checkError(err, t)

	if len(info) != 1 {
		t.Fatal("Expected only 1 bucket to be backed up")
	}

	if _, ok := info["default"]; !ok {
		t.Fatal("Expected default bucket to be backed up")
	}
}
func TestIncrementalBackup(t *testing.T) {
	defer cleanup()
	defer deleteAllBuckets(testHost, t)
	cleanup()
	deleteAllBuckets(testHost, t)
	createCouchbaseBucket(testHost, "default", "", t)

	setName := "incr-backup-test"

	config := value.CreateBackupConfig("", "", make([]string, 0),
		make([]string, 0), make([]string, 0), make([]string, 0),
		false, false, false, false, false, false, false, false)

	a, err := archive.MountArchive(testDir, true)
	checkError(err, t)

	checkError(a.CreateBackup(setName, config), t)

	// Do full backup
	loadData(testHost, "default", "", 5000, "full", t)

	name1, err := executeBackup(a, setName, "archive", testHost, restUsername, restPassword,
		4, false, false)

	info, err := a.IncrBackupInfo(setName, name1)
	checkError(err, t)

	count := info["default"].NumDocs
	if count != 5000 {
		t.Fatal("Expected to backup 5000 items, got " + strconv.Itoa(count))
	}

	// Do first incremental backup
	loadData(testHost, "default", "", 4000, "incr-1-", t)

	name2, err := executeBackup(a, setName, "archive", testHost, restUsername, restPassword,
		4, false, false)

	info, err = a.IncrBackupInfo(setName, name2)
	checkError(err, t)

	count = info["default"].NumDocs
	if count != 4000 {
		t.Fatal("Expected to backup 4000 items, got " + strconv.Itoa(count))
	}

	// Do second incremental backup
	loadData(testHost, "default", "", 3000, "incr-2-", t)

	name3, err := executeBackup(a, setName, "archive", testHost, restUsername, restPassword,
		4, false, false)

	info, err = a.IncrBackupInfo(setName, name3)
	checkError(err, t)

	count = info["default"].NumDocs
	if count != 3000 {
		t.Fatal("Expected to backup 3000 items, got " + strconv.Itoa(count))
	}

	// Do third incremental backup
	loadData(testHost, "default", "", 2000, "incr-3-", t)

	name4, err := executeBackup(a, setName, "archive", testHost, restUsername, restPassword,
		4, false, false)

	info, err = a.IncrBackupInfo(setName, name4)
	checkError(err, t)

	count = info["default"].NumDocs
	if count != 2000 {
		t.Fatal("Expected to backup 2000 items, got " + strconv.Itoa(count))
	}

	// Restore the data without explicitly setting the start/end point in
	// order to restore all backed up data.
	deleteBucket(testHost, "default", t, true)
	createCouchbaseBucket(testHost, "default", "", t)

	err = executeRestore(a, setName, testHost, restUsername, restPassword, "",
		"", 4, false, config)
	checkError(err, t)

	time.Sleep(5 * time.Second)
	items, err := getNumItems(testHost, restUsername, restPassword, "default")
	checkError(err, t)

	if items != 14000 {
		t.Fatalf("Expected 14000 items, got %d", items)
	}

	// Restore only the 2nd and 3rd backup
	deleteBucket(testHost, "default", t, true)
	createCouchbaseBucket(testHost, "default", "", t)

	err = executeRestore(a, setName, testHost, restUsername, restPassword, name2,
		name3, 4, false, config)
	checkError(err, t)

	time.Sleep(5 * time.Second)
	items, err = getNumItems(testHost, restUsername, restPassword, "default")
	checkError(err, t)

	if items != 7000 {
		t.Fatalf("Expected 7000 items, got %d", items)
	}

	// Restore everything after and including the 3rd backup, don't specify the end
	deleteBucket(testHost, "default", t, true)
	createCouchbaseBucket(testHost, "default", "", t)

	err = executeRestore(a, setName, testHost, restUsername, restPassword, name3,
		"", 4, false, config)
	checkError(err, t)

	time.Sleep(5 * time.Second)
	items, err = getNumItems(testHost, restUsername, restPassword, "default")
	checkError(err, t)

	if items != 5000 {
		t.Fatalf("Expected 5000 items, got %d", items)
	}

	// Restore everything before and including the 2nd backup, don't specify start
	deleteBucket(testHost, "default", t, true)
	createCouchbaseBucket(testHost, "default", "", t)

	err = executeRestore(a, setName, testHost, restUsername, restPassword, "",
		name2, 4, false, config)
	checkError(err, t)

	time.Sleep(5 * time.Second)
	items, err = getNumItems(testHost, restUsername, restPassword, "default")
	checkError(err, t)

	if items != 9000 {
		t.Fatalf("Expected 9000 items, got %d", items)
	}
}
func TestMerge(t *testing.T) {
	defer cleanup()
	defer deleteAllBuckets(testHost, t)
	cleanup()
	deleteAllBuckets(testHost, t)
	createCouchbaseBucket(testHost, "default", "", t)

	setName := "incr-backup-test"

	config := value.CreateBackupConfig("", "", make([]string, 0),
		make([]string, 0), make([]string, 0), make([]string, 0),
		false, false, false, false, false, false, false, false)

	a, err := archive.MountArchive(testDir, true)
	checkError(err, t)

	checkError(a.CreateBackup(setName, config), t)

	// Do full backup
	loadData(testHost, "default", "", 5000, "full", t)

	name1, err := executeBackup(a, setName, "archive", testHost, restUsername, restPassword,
		4, false, false)

	info, err := a.IncrBackupInfo(setName, name1)
	checkError(err, t)

	count := info["default"].NumDocs
	if count != 5000 {
		t.Fatal("Expected to backup 5000 items, got %d", count)
	}

	// Do first incremental backup
	loadData(testHost, "default", "", 4000, "incr-1-", t)

	name2, err := executeBackup(a, setName, "archive", testHost, restUsername, restPassword,
		4, false, false)

	info, err = a.IncrBackupInfo(setName, name2)
	checkError(err, t)

	count = info["default"].NumDocs
	if count != 4000 {
		t.Fatal("Expected to backup 4000 items, got %d", count)
	}

	// Do second incremental backup
	loadData(testHost, "default", "", 3000, "incr-2-", t)

	name3, err := executeBackup(a, setName, "archive", testHost, restUsername, restPassword,
		4, false, false)

	info, err = a.IncrBackupInfo(setName, name3)
	checkError(err, t)

	count = info["default"].NumDocs
	if count != 3000 {
		t.Fatal("Expected to backup 3000 items, got %d", count)
	}

	// Do third incremental backup
	loadData(testHost, "default", "", 2000, "incr-3-", t)

	name4, err := executeBackup(a, setName, "archive", testHost, restUsername, restPassword,
		4, false, false)

	info, err = a.IncrBackupInfo(setName, name4)
	checkError(err, t)

	count = info["default"].NumDocs
	if count != 2000 {
		t.Fatal("Expected to backup 2000 items, got %d", count)
	}

	// Merge the backups and make sure all the items show up in the merged backup
	_, err = a.MergeIncrBackups(setName, name1, name4)
	checkError(err, t)

	info, err = a.IncrBackupInfo(setName, name4)
	checkError(err, t)

	count = info["default"].NumDocs
	if count != 14000 {
		t.Fatalf("Expected to backup 14000 items, got %d", count)
	}

	binfo, err := a.BackupInfo(setName)
	if binfo.NumIncrBackups != 1 {
		t.Fatalf("Expected 1 incr backups after merge, got %d", count)
	}
}
// Tests all error cases when we don't have a bucket and try to restore. This
// means that we check that all restore configuratoins work no matter what is
// skipped during the restore.
func TestRestoreNoBucketNoBackupConfig(t *testing.T) {
	defer cleanup()
	defer deleteAllBuckets(testHost, t)
	cleanup()
	deleteAllBuckets(testHost, t)
	createCouchbaseBucket(testHost, "default", "", t)

	backupName := "bucket-config-test"

	loadData(testHost, "default", "", 5000, "full", t)
	loadViews(testHost, "default", "first", 12, 2, t)

	config := value.CreateBackupConfig("", "", make([]string, 0),
		make([]string, 0), make([]string, 0), make([]string, 0),
		false, true, false, false, false, false, false, false)

	a, err := archive.MountArchive(testDir, true)
	checkError(err, t)

	checkError(a.CreateBackup(backupName, config), t)

	// Backup the data
	name, err := executeBackup(a, backupName, "archive", testHost, restUsername, restPassword,
		4, false, false)
	checkError(err, t)

	info, err := a.IncrBackupInfo(backupName, name)
	checkError(err, t)

	count := info["default"].NumDocs
	if count != 5000 {
		t.Fatal("Expected to backup 5000 items, got " + strconv.Itoa(count))
	}

	deleteBucket(testHost, "default", t, true)

	// Do a restore where the views are the first thing to be restored, make sure
	// we fail to restore the views because no bucket exists
	err = executeRestore(a, backupName, testHost, restUsername, restPassword, "",
		"", 4, false, config)
	_, ok := err.(couchbase.BucketNotFoundError)
	if err == nil || !ok {
		t.Fatal("Expected BucketNotFoundError")
	}

	// Do a restore where the gsi indexes are the first thing to be restored, make
	// sure we fail to restore the gsi indexes because no bucket exists
	config = value.CreateBackupConfig("", "", make([]string, 0),
		make([]string, 0), make([]string, 0), make([]string, 0),
		false, true, true, false, false, false, false, false)
	err = executeRestore(a, backupName, testHost, restUsername, restPassword, "",
		"", 4, false, config)
	_, ok = err.(couchbase.BucketNotFoundError)
	if err == nil || !ok {
		t.Fatal("Expected BucketNotFoundError")
	}

	// Do a restore where the full text indexes are the first thing to be restored,
	// make sure we fail to restore the full text indexes because no bucket exists
	config = value.CreateBackupConfig("", "", make([]string, 0),
		make([]string, 0), make([]string, 0), make([]string, 0),
		false, true, true, true, false, false, false, false)
	err = executeRestore(a, backupName, testHost, restUsername, restPassword, "",
		"", 4, false, config)
	_, ok = err.(couchbase.BucketNotFoundError)
	if err == nil || !ok {
		t.Fatal("Expected BucketNotFoundError")
	}

	// Do a restore where data is the first thing to be restored, make sure we fail
	// to restore the data because no bucket exists
	config = value.CreateBackupConfig("", "", make([]string, 0),
		make([]string, 0), make([]string, 0), make([]string, 0),
		false, true, true, true, true, false, false, false)
	err = executeRestore(a, backupName, testHost, restUsername, restPassword, "",
		"", 4, false, config)
	_, ok = err.(couchbase.BucketNotFoundError)
	if err == nil || !ok {
		t.Fatal("Expected BucketNotFoundError")
	}
}
func TestBackupRestore(t *testing.T) {
	defer cleanup()
	defer deleteAllBuckets(testHost, t)
	cleanup()
	deleteAllBuckets(testHost, t)
	createCouchbaseBucket(testHost, "default", "", t)

	backupName := "restore-test"

	loadData(testHost, "default", "", 5000, "full", t)

	config := value.CreateBackupConfig("", "", make([]string, 0),
		make([]string, 0), make([]string, 0), make([]string, 0),
		false, false, false, false, false, false, false, false)

	a, err := archive.MountArchive(testDir, true)
	checkError(err, t)

	checkError(a.CreateBackup(backupName, config), t)

	// Test that restoring data when none exists gives an error
	err = executeRestore(a, backupName, testHost, restUsername, restPassword, "name",
		"name", 4, false, config)
	if err == nil {
		t.Fatal(err.Error())
	} else if _, ok := err.(archive.EmptyRangeError); !ok {
		t.Fatal(err.Error())
	}

	// Backup the data
	name, err := executeBackup(a, backupName, "archive", testHost, restUsername, restPassword,
		4, false, false)
	checkError(err, t)

	info, err := a.IncrBackupInfo(backupName, name)
	checkError(err, t)

	count := info["default"].NumDocs
	if count != 5000 {
		t.Fatal("Expected to backup 5000 items, got " + strconv.Itoa(count))
	}

	deleteBucket(testHost, "default", t, true)
	createCouchbaseBucket(testHost, "default", "", t)

	// Check that using an invalid start point causes an error
	err = executeRestore(a, backupName, testHost, restUsername, restPassword, "name",
		name, 4, false, config)
	if err == nil {
		t.Fatal(err.Error())
	} else if _, ok := err.(archive.RangePointError); !ok {
		t.Fatal(err.Error())
	}

	// Check that using an invalid end point causes an error
	err = executeRestore(a, backupName, testHost, restUsername, restPassword, name,
		"end", 4, false, config)
	if err == nil {
		t.Fatal(err.Error())
	} else if _, ok := err.(archive.RangePointError); !ok {
		t.Fatal(err.Error())
	}

	// Restore the data using explicit start/end specification
	err = executeRestore(a, backupName, testHost, restUsername, restPassword, name,
		name, 4, false, config)
	checkError(err, t)

	time.Sleep(5 * time.Second)
	items, err := getNumItems(testHost, restUsername, restPassword, "default")
	if err != nil {
		t.Fatalf("Error getting item count: %s", err.Error())
	}
	if items != 5000 {
		t.Fatalf("Expected 5000 items, got %d", items)
	}

	deleteBucket(testHost, "default", t, true)
	createCouchbaseBucket(testHost, "default", "", t)

	// Restore the data without explicitly setting the start/end point
	err = executeRestore(a, backupName, testHost, restUsername, restPassword, "",
		"", 4, false, config)
	checkError(err, t)

	time.Sleep(5 * time.Second)
	items, err = getNumItems(testHost, restUsername, restPassword, "default")
	checkError(err, t)

	if items != 5000 {
		t.Fatalf("Expected 5000 items, got %d", items)
	}
}