217 lines
7.1 KiB
Go
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)
|
|
}
|
|
}
|
|
}
|