cadvisor/devicemapper/thin_pool_watcher_test.go
2017-08-25 13:42:26 -07:00

217 lines
7.1 KiB
Go

// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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 devicemapper
import (
"fmt"
"sync"
"testing"
"time"
"github.com/google/cadvisor/devicemapper/fake"
)
func TestRefresh(t *testing.T) {
usage := map[string]uint64{
"1": 12345,
"2": 23456,
"3": 34567,
}
cases := []struct {
name string
dmsetupCommands []fake.DmsetupCommand
thinLsOutput map[string]uint64
thinLsErr error
expectedError bool
deviceId string
expectedUsage uint64
}{
{
name: "check reservation fails",
dmsetupCommands: []fake.DmsetupCommand{
{Name: "status", Result: "", Err: fmt.Errorf("not gonna work")},
},
expectedError: true,
},
{
name: "no existing reservation - ok with minimum # of fields",
dmsetupCommands: []fake.DmsetupCommand{
{Name: "status", Result: "0 75497472 thin-pool 65 327/524288 14092/589824 -", Err: nil}, // status check
{Name: "message", Result: "", Err: nil}, // make reservation
{Name: "message", Result: "", Err: nil}, // release reservation
},
thinLsOutput: usage,
expectedError: false,
deviceId: "2",
expectedUsage: 23456,
},
{
name: "no existing reservation - ok",
dmsetupCommands: []fake.DmsetupCommand{
{Name: "status", Result: "0 75497472 thin-pool 65 327/524288 14092/589824 - rw no_discard_passdown error_if_no_space - ", Err: nil}, // status check
{Name: "message", Result: "", Err: nil}, // make reservation
{Name: "message", Result: "", Err: nil}, // release reservation
},
thinLsOutput: usage,
expectedError: false,
deviceId: "2",
expectedUsage: 23456,
},
{
name: "existing reservation - ok",
dmsetupCommands: []fake.DmsetupCommand{
// status check
{Name: "status", Result: "0 75497472 thin-pool 65 327/524288 14092/589824 39 rw no_discard_passdown error_if_no_space - ", Err: nil},
// release reservation
{Name: "message", Result: "", Err: nil},
// make reservation
{Name: "message", Result: "", Err: nil},
// release reservation
{Name: "message", Result: "", Err: nil},
},
thinLsOutput: usage,
expectedError: false,
deviceId: "3",
expectedUsage: 34567,
},
{
name: "failure releasing existing reservation",
dmsetupCommands: []fake.DmsetupCommand{
// status check
{Name: "status", Result: "0 75497472 thin-pool 65 327/524288 14092/589824 39 rw no_discard_passdown error_if_no_space - ", Err: nil},
// release reservation
{Name: "message", Result: "", Err: fmt.Errorf("not gonna work")},
},
expectedError: true,
},
{
name: "failure making reservation",
dmsetupCommands: []fake.DmsetupCommand{
// status check
{Name: "status", Result: "0 75497472 thin-pool 65 327/524288 14092/589824 39 rw no_discard_passdown error_if_no_space - ", Err: nil},
// release reservation
{Name: "message", Result: "", Err: nil},
// make reservation
{Name: "message", Result: "", Err: fmt.Errorf("not gonna work")},
},
expectedError: true,
},
{
name: "failure running thin_ls",
dmsetupCommands: []fake.DmsetupCommand{
// status check
{Name: "status", Result: "0 75497472 thin-pool 65 327/524288 14092/589824 39 rw no_discard_passdown error_if_no_space - ", Err: nil},
// release reservation
{Name: "message", Result: "", Err: nil},
// make reservation
{Name: "message", Result: "", Err: nil},
// release reservation
{Name: "message", Result: "", Err: nil},
},
thinLsErr: fmt.Errorf("not gonna work"),
expectedError: true,
},
}
for _, tc := range cases {
dmsetup := fake.NewFakeDmsetupClient(t, tc.dmsetupCommands...)
thinLsClient := fake.NewFakeThinLsClient(tc.thinLsOutput, tc.thinLsErr)
watcher := &ThinPoolWatcher{
poolName: "test pool name",
metadataDevice: "/dev/mapper/metadata-device",
lock: &sync.RWMutex{},
period: 15 * time.Second,
stopChan: make(chan struct{}),
dmsetup: dmsetup,
thinLsClient: thinLsClient,
}
err := watcher.Refresh()
if err != nil {
if !tc.expectedError {
t.Errorf("%v: unexpected error: %v", tc.name, err)
}
continue
} else if tc.expectedError {
t.Errorf("%v: unexpected success", tc.name)
continue
}
actualUsage, err := watcher.GetUsage(tc.deviceId)
if err != nil {
t.Errorf("%v: device ID not found: %v", tc.deviceId, err)
continue
}
if e, a := tc.expectedUsage, actualUsage; e != a {
t.Errorf("%v: actual usage did not match expected usage: expected: %v got: %v", tc.name, e, a)
}
}
}
func TestCheckReservation(t *testing.T) {
cases := []struct {
name string
statusResult string
statusErr error
expectedResult bool
expectedErr error
}{
{
name: "existing reservation 1",
statusResult: "0 75497472 thin-pool 65 327/524288 14092/589824 36 rw no_discard_passdown queue_if_no_space - ",
expectedResult: true,
},
{
name: "existing reservation 2",
statusResult: "0 12345 thin-pool 65 327/45678 14092/45678 36 rw discard_passdown error_if_no_space needs_check ",
expectedResult: true,
},
{
name: "no reservation 1",
statusResult: "0 75497472 thin-pool 65 327/524288 14092/589824 - rw no_discard_passdown error_if_no_space - ",
expectedResult: false,
},
{
name: "no reservation 2",
statusResult: "0 75 thin-pool 65 327/12345 14092/589824 - rw no_discard_passdown queue_if_no_space - ",
expectedResult: false,
},
{
name: "no reservation 2",
statusResult: "0 75 thin-pool 65 327/12345 14092/589824 - rw no_discard_passdown queue_if_no_space - ",
expectedResult: false,
},
}
for _, tc := range cases {
fakeDmsetupClient := fake.NewFakeDmsetupClient(t)
fakeDmsetupClient.AddCommand("status", tc.statusResult, tc.statusErr)
watcher := &ThinPoolWatcher{dmsetup: fakeDmsetupClient}
actualResult, err := watcher.checkReservation("test pool")
if err != nil {
if tc.expectedErr == nil {
t.Errorf("%v: unexpected error running checkReservation: %v", tc.name, err)
}
} else if tc.expectedErr != nil {
t.Errorf("%v: unexpected success running checkReservation", tc.name)
}
if e, a := tc.expectedResult, actualResult; e != a {
t.Errorf("%v: unexpected result from checkReservation: expected: %v got: %v", tc.name, e, a)
}
}
}