Exemple #1
0
func (s *testSuite) TestWatchVolumes(c *C) {
	entChan, errChan := s.client.WatchPrefix(&db.Volume{})
	select {
	case err := <-errChan:
		c.Assert(err, IsNil)
	default:
	}

	c.Assert(s.client.Set(testPolicies["basic"]), IsNil)
	vol, err := db.CreateVolume(&db.VolumeRequest{Policy: testPolicies["basic"], Name: "test"})
	c.Assert(err, IsNil)
	c.Assert(s.client.Set(vol), IsNil)

	select {
	case err := <-errChan:
		c.Assert(err, IsNil)
	case ent := <-entChan:
		vol2 := ent.(*db.Volume)
		c.Assert(vol, DeepEquals, vol2)
	}

	c.Assert(s.client.WatchPrefixStop(&db.Volume{}), IsNil)

	vol, err = db.CreateVolume(&db.VolumeRequest{Policy: testPolicies["basic"], Name: "test2"})
	c.Assert(err, IsNil)
	c.Assert(s.client.Set(vol), IsNil)

	select {
	case <-entChan:
		c.Assert(false, Equals, true, Commentf("received on a should-be-closed channel"))
	default:
	}
}
Exemple #2
0
func (s *testSuite) TestMountSource(c *C) {
	c.Assert(s.client.Set(testPolicies["nfs"]), IsNil)
	vol, err := db.CreateVolume(&db.VolumeRequest{Policy: testPolicies["nfs"], Name: "test", Options: map[string]string{"mount": "localhost:/mnt"}})
	c.Assert(err, IsNil)
	c.Assert(vol.MountSource, Equals, "localhost:/mnt")
	_, err = db.CreateVolume(&db.VolumeRequest{Policy: testPolicies["nfs"], Name: "test2"})
	c.Assert(err, NotNil)
	copy := testPolicies["basic"].Copy()
	copy.(*db.Policy).Name = "nfs"
	c.Assert(s.client.Set(testPolicies["basic"]), IsNil)
	vol, err = db.CreateVolume(&db.VolumeRequest{Policy: copy.(*db.Policy), Name: "test2"})
	c.Assert(err, IsNil)
	c.Assert(vol.MountSource, Equals, "")
}
Exemple #3
0
func (s *testSuite) TestWatchVolumes(c *C) {
	entChan, errChan := s.client.WatchPrefix(&db.Volume{})
	select {
	case err := <-errChan:
		c.Assert(err, IsNil)
	default:
	}

	c.Assert(s.client.Set(testPolicies["basic"]), IsNil)
	vol, err := db.CreateVolume(&db.VolumeRequest{Policy: testPolicies["basic"], Name: "test"})
	c.Assert(err, IsNil)

	for i := 0; i < 5; i++ {
		vol.VolumeName = fmt.Sprintf("test%d", i)
		c.Assert(s.client.Set(vol), IsNil)

		select {
		case err := <-errChan:
			c.Assert(err, IsNil)
		case ent := <-entChan:
			logrus.Infof("Received object for %v during prefix watch", ent)
			vol2 := ent.(*db.Volume)
			c.Assert(vol, DeepEquals, vol2)
		}

		c.Assert(s.client.Delete(vol), IsNil)
		time.Sleep(200 * time.Millisecond) // wait for watch
		select {
		case <-errChan:
			panic("error received after delete in watch")
		case <-entChan:
			panic("object received after delete in watch")
		default:
			logrus.Info("Watch delete was processed successfully")
		}
	}

	c.Assert(s.client.WatchPrefixStop(&db.Volume{}), IsNil)

	vol, err = db.CreateVolume(&db.VolumeRequest{Policy: testPolicies["basic"], Name: "test2"})
	c.Assert(err, IsNil)
	c.Assert(s.client.Set(vol), IsNil)

	select {
	case <-entChan:
		c.Assert(false, Equals, true, Commentf("received on a should-be-closed channel"))
	default:
	}
}
Exemple #4
0
func (s *testSuite) TestRuntimeWatch(c *C) {
	c.Assert(s.client.Set(testPolicies["basic"]), IsNil)
	policy := db.NewPolicy("basic")
	c.Assert(s.client.Get(policy), IsNil)

	vol, err := db.CreateVolume(&db.VolumeRequest{Policy: policy, Name: "bar"})
	c.Assert(err, IsNil)

	objChan, errChan := s.client.WatchPrefix(&db.RuntimeOptions{})
	defer s.client.WatchPrefixStop(&db.RuntimeOptions{})
	opts := db.NewRuntimeOptions(vol.PolicyName, vol.VolumeName)
	opts.RateLimit.ReadBPS = 1000
	c.Assert(s.client.Set(opts), IsNil)

	select {
	case err := <-errChan:
		c.Assert(err, IsNil)
	case obj := <-objChan:
		c.Assert(obj.(*db.RuntimeOptions).RateLimit.ReadBPS, Equals, uint64(1000))
		c.Assert(obj.(*db.RuntimeOptions).Policy(), Not(Equals), "")
		c.Assert(obj.(*db.RuntimeOptions).Policy(), Equals, vol.PolicyName)
		c.Assert(obj.(*db.RuntimeOptions).Volume(), Not(Equals), "")
		c.Assert(obj.(*db.RuntimeOptions).Volume(), Equals, vol.VolumeName)
	}
}
Exemple #5
0
func (s *testSuite) TestLockTTLRefresh(c *C) {
	copy := testPolicies["basic"].Copy()
	copy.(*db.Policy).Name = "policy1"
	c.Assert(s.client.Set(copy), IsNil)

	v, err := db.CreateVolume(&db.VolumeRequest{Policy: copy.(*db.Policy), Name: "test"})
	c.Assert(err, IsNil, Commentf("%v", v))
	c.Assert(s.client.Set(v), IsNil)

	lock := db.NewCreateOwner("mon0", v)
	s.client.Free(lock, true)

	stopChan, err := s.client.AcquireAndRefresh(lock, 15*time.Second)
	c.Assert(err, IsNil)

	sync := make(chan struct{})
	sync2 := make(chan struct{})

	// gocheck doesn't run very well in goroutines, so these panics are a
	// makeshift version of what gocheck actually does.
	go func(v *db.Volume) {
		for {
			select {
			case <-sync:
				lock := db.NewCreateOwner("mon1", v)

				time.Sleep(15 * time.Second)

				if err := s.client.Acquire(lock); err != nil {
					panic(err)
				}

				if err := s.client.Free(lock, false); err != nil {
					panic(err)
				}
				close(sync2)
				return
			default:
				lock := db.NewCreateOwner("mon1", v)
				if err := s.client.Acquire(lock); err == nil {
					panic("Acquired lock for mon1")
				}
			}
		}
	}(v)

	logrus.Infof("Creating contention in %s", Driver)
	time.Sleep(time.Minute)
	close(stopChan)
	close(sync)
	<-sync2
	logrus.Info("Lock successfully traded in background goroutine!")
}
Exemple #6
0
func (s *testSuite) TestLockBattery(c *C) {
	copy := testPolicies["basic"].Copy()
	copy.(*db.Policy).Name = "policy1"
	c.Assert(s.client.Set(copy), IsNil)

	v, err := db.CreateVolume(&db.VolumeRequest{Policy: copy.(*db.Policy), Name: "test"})
	c.Assert(err, IsNil, Commentf("%v", v))
	c.Assert(s.client.Set(v), IsNil)

	lock := db.NewCreateOwner("mon0", v)
	c.Assert(s.client.Acquire(lock), IsNil)

	// go routine A should never free the lock.
	// go routine B should never succeed at acquiring it.

	syncChan1 := make(chan struct{})
	syncChan2 := make(chan struct{}, 1)

	defer func() {
		syncChan2 <- struct{}{} // this relays to the first one to ensure the lock is freed
		syncChan1 <- struct{}{} // this relays to the second one to terminate it
	}()

	go func(v *db.Volume) {
		lock := db.NewCreateOwner("mon0", v)
		for {
			select {
			case <-syncChan1:
				s.client.Free(lock, true)
				return
			default:
				c.Assert(s.client.Acquire(lock), IsNil)
			}
		}
	}(v)

	go func(v *db.Volume) {
		lock := db.NewCreateOwner("mon1", v)
		for {
			select {
			case <-syncChan2:
				return
			default:
				logrus.Debug("Attempting to acquire lock (should fail)")
				c.Assert(s.client.Acquire(lock), NotNil)
			}
		}
	}(v)

	logrus.Infof("Creating contention in %s", Driver)
	time.Sleep(time.Minute)
}
Exemple #7
0
func (s *testSuite) TestLockAcquire(c *C) {
	copy := testPolicies["basic"].Copy()
	copy.(*db.Policy).Name = "policy1"
	c.Assert(s.client.Set(copy), IsNil)

	v, err := db.CreateVolume(&db.VolumeRequest{Policy: copy.(*db.Policy), Name: "test"})
	c.Assert(err, IsNil, Commentf("%v", v))
	c.Assert(s.client.Set(v), IsNil)

	lock := db.NewCreateOwner("mon0", v)

	path, err := lock.Path()
	c.Assert(err, IsNil)
	c.Assert(path, Equals, strings.Join([]string{lock.Prefix(), v.String()}, "/"))
	c.Assert(lock.Prefix(), Equals, "users/volume")
	c.Assert(s.client.Acquire(lock), IsNil)

	testUse := db.NewUse(v)
	c.Assert(s.client.Get(testUse), IsNil)

	// test that we can acquire the fetched lock.
	path, err = testUse.Path()
	c.Assert(err, IsNil)
	c.Assert(path, Equals, strings.Join([]string{lock.Prefix(), v.String()}, "/"))
	c.Assert(lock.Prefix(), Equals, "users/volume")
	c.Assert(s.client.Acquire(lock), IsNil)

	lock2 := db.NewCreateOwner("mon1", v)
	c.Assert(s.client.Acquire(lock2), NotNil)
	c.Assert(s.client.Free(lock2, false), NotNil)

	c.Assert(s.client.Free(lock, false), IsNil)
	c.Assert(s.client.Acquire(lock2), IsNil)
	c.Assert(s.client.Free(lock2, false), IsNil)

	c.Assert(s.client.Acquire(lock), IsNil)
	c.Assert(s.client.Free(lock2, true), IsNil)
}
Exemple #8
0
func (s *testSuite) TestLockTTL(c *C) {
	copy := testPolicies["basic"].Copy()
	copy.(*db.Policy).Name = "policy1"
	c.Assert(s.client.Set(copy), IsNil)

	v, err := db.CreateVolume(&db.VolumeRequest{Policy: copy.(*db.Policy), Name: "test"})
	c.Assert(err, IsNil, Commentf("%v", v))
	c.Assert(s.client.Set(v), IsNil)

	lock := db.NewCreateOwner("mon0", v)
	lock2 := db.NewCreateOwner("mon1", v)

	s.client.Free(lock, true)
	c.Assert(s.client.AcquireWithTTL(lock, 15*time.Second), IsNil)
	c.Assert(s.client.AcquireWithTTL(lock2, 15*time.Second), NotNil)

	time.Sleep(5 * time.Second)                                   // wait for ttl to expire. minimum timeout is 10s so we're testing that.
	c.Assert(s.client.AcquireWithTTL(lock2, time.Second), NotNil) // test in the middle so we're sure the lock isn't freed yet.
	time.Sleep(11 * time.Second)

	c.Assert(s.client.AcquireWithTTL(lock2, time.Second), IsNil)
	c.Assert(s.client.Free(lock2, false), IsNil)
}
Exemple #9
0
func (s *testSuite) TestToDriverOptions(c *C) {
	c.Assert(s.client.Set(testPolicies["basic"]), IsNil)
	vol, err := db.CreateVolume(&db.VolumeRequest{Policy: testPolicies["basic"], Name: "test"})
	c.Assert(err, IsNil)

	do, err := vol.ToDriverOptions(1)
	c.Assert(err, IsNil)

	expected := storage.DriverOptions{
		Volume: storage.Volume{
			Name:   "basic/test",
			Size:   0xa,
			Params: storage.Params{"pool": "rbd"},
		},
		FSOptions: storage.FSOptions{
			Type:          "ext4",
			CreateCommand: "",
		},
		Timeout: 1,
		Options: nil,
	}

	c.Assert(do, DeepEquals, expected)
}
Exemple #10
0
func (s *testSuite) TestVolumeCRUD(c *C) {
	policyNames := []string{"foo", "bar"}
	volumeNames := []string{"baz", "quux"}

	c.Assert(s.client.Set(&db.Volume{}), NotNil)

	_, err := db.CreateVolume(&db.VolumeRequest{Policy: nil})
	c.Assert(err, NotNil)

	// populate the policies so the next few tests don't give false positives
	for _, policy := range policyNames {
		copy := testPolicies["basic"].Copy()
		copy.(*db.Policy).Name = policy
		err := s.client.Set(copy)
		c.Assert(err, IsNil, Commentf("%v", err))
	}

	_, err = db.CreateVolume(&db.VolumeRequest{Policy: db.NewPolicy("foo"), Name: "bar", Options: map[string]string{"quux": "derp"}})
	c.Assert(err, NotNil)

	_, err = db.CreateVolume(&db.VolumeRequest{Policy: db.NewPolicy("foo"), Name: ""})
	c.Assert(err, NotNil)

	vol := db.NewVolume("foo", "bar")
	c.Assert(s.client.Get(vol).(*errored.Error).Contains(errors.NotExists), Equals, true)

	// _, err = s.client.ListVolumes("quux")
	// c.Assert(err, NotNil)

	for _, policyName := range policyNames {
		for _, volumeName := range volumeNames {
			policy := db.NewPolicy(policyName)
			c.Assert(s.client.Get(policy), IsNil)
			vcfg, err := db.CreateVolume(&db.VolumeRequest{Policy: policy, Name: volumeName, Options: map[string]string{"filesystem": ""}})
			c.Assert(err, IsNil)
			err = s.client.Set(vcfg)
			c.Assert(err, IsNil, Commentf("%v", err))
			err = s.client.Set(vcfg)
			c.Assert(err.(*errored.Error).Contains(errors.Exists), Equals, true)

			c.Assert(vcfg.CreateOptions.FileSystem, Equals, "ext4")

			defer func() { c.Assert(s.client.Delete(vcfg), IsNil) }()

			c.Assert(vcfg.VolumeName, Equals, volumeName)

			vcfg2 := db.NewVolume(policyName, volumeName)
			c.Assert(s.client.Get(vcfg2), IsNil)
			c.Assert(vcfg, DeepEquals, vcfg2)

			runtime := db.NewRuntimeOptions(policyName, volumeName)
			c.Assert(s.client.Get(runtime), IsNil)
			c.Assert(runtime, DeepEquals, vcfg.RuntimeOptions)

			vcfg.CreateOptions.Size = "0"
			c.Assert(s.client.Set(vcfg), NotNil)
		}

		volumes, err := s.client.ListPrefix(policyName, &db.Volume{})
		c.Assert(err, IsNil)

		volumeKeys := []string{}
		for _, volume := range volumes {
			volumeKeys = append(volumeKeys, volume.(*db.Volume).VolumeName)
		}

		sort.Strings(volumeKeys)

		c.Assert(volumeNames, DeepEquals, volumeKeys)
		for _, entity := range volumes {
			vol := entity.(*db.Volume)
			testPolicies["basic"].RuntimeOptions.SetKey(vol.String())
			c.Assert(vol.CreateOptions, DeepEquals, testPolicies["basic"].CreateOptions)
			c.Assert(vol.RuntimeOptions, DeepEquals, testPolicies["basic"].RuntimeOptions)
		}
	}

	allVols, err := s.client.List(&db.Volume{})
	c.Assert(err, IsNil)

	for _, policy := range policyNames {
		for _, volume := range volumeNames {
			found := false
			for _, ent := range allVols {
				vol := ent.(*db.Volume)
				if vol.PolicyName == policy && vol.VolumeName == volume {
					found = true
				}

				c.Assert(vol.CreateOptions, DeepEquals, testPolicies["basic"].CreateOptions)
				// Cannot use deepequals because of the private members in runtimeoptions now.
				c.Assert(vol.RuntimeOptions.UseSnapshots, Equals, testPolicies["basic"].RuntimeOptions.UseSnapshots)
				c.Assert(vol.RuntimeOptions.Snapshot, DeepEquals, testPolicies["basic"].RuntimeOptions.Snapshot)
				c.Assert(vol.RuntimeOptions.RateLimit, DeepEquals, testPolicies["basic"].RuntimeOptions.RateLimit)
			}

			c.Assert(found, Equals, true, Commentf("%s/%s", policy, volume))
		}
	}
}