github.com/google/cadvisor@v0.49.1/devicemapper/thin_pool_watcher_test.go (about) 1 // Copyright 2016 Google Inc. All Rights Reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package devicemapper 16 17 import ( 18 "fmt" 19 "sync" 20 "testing" 21 "time" 22 23 "github.com/google/cadvisor/devicemapper/fake" 24 ) 25 26 func TestRefresh(t *testing.T) { 27 usage := map[string]uint64{ 28 "1": 12345, 29 "2": 23456, 30 "3": 34567, 31 } 32 33 cases := []struct { 34 name string 35 dmsetupCommands []fake.DmsetupCommand 36 thinLsOutput map[string]uint64 37 thinLsErr error 38 expectedError bool 39 deviceID string 40 expectedUsage uint64 41 }{ 42 { 43 name: "check reservation fails", 44 dmsetupCommands: []fake.DmsetupCommand{ 45 {Name: "status", Result: "", Err: fmt.Errorf("not gonna work")}, 46 }, 47 expectedError: true, 48 }, 49 { 50 name: "no existing reservation - ok with minimum # of fields", 51 dmsetupCommands: []fake.DmsetupCommand{ 52 {Name: "status", Result: "0 75497472 thin-pool 65 327/524288 14092/589824 -", Err: nil}, // status check 53 {Name: "message", Result: "", Err: nil}, // make reservation 54 {Name: "message", Result: "", Err: nil}, // release reservation 55 }, 56 thinLsOutput: usage, 57 expectedError: false, 58 deviceID: "2", 59 expectedUsage: 23456, 60 }, 61 { 62 name: "no existing reservation - ok", 63 dmsetupCommands: []fake.DmsetupCommand{ 64 {Name: "status", Result: "0 75497472 thin-pool 65 327/524288 14092/589824 - rw no_discard_passdown error_if_no_space - ", Err: nil}, // status check 65 {Name: "message", Result: "", Err: nil}, // make reservation 66 {Name: "message", Result: "", Err: nil}, // release reservation 67 }, 68 thinLsOutput: usage, 69 expectedError: false, 70 deviceID: "2", 71 expectedUsage: 23456, 72 }, 73 { 74 name: "existing reservation - ok", 75 dmsetupCommands: []fake.DmsetupCommand{ 76 // status check 77 {Name: "status", Result: "0 75497472 thin-pool 65 327/524288 14092/589824 39 rw no_discard_passdown error_if_no_space - ", Err: nil}, 78 // release reservation 79 {Name: "message", Result: "", Err: nil}, 80 // make reservation 81 {Name: "message", Result: "", Err: nil}, 82 // release reservation 83 {Name: "message", Result: "", Err: nil}, 84 }, 85 thinLsOutput: usage, 86 expectedError: false, 87 deviceID: "3", 88 expectedUsage: 34567, 89 }, 90 { 91 name: "failure releasing existing reservation", 92 dmsetupCommands: []fake.DmsetupCommand{ 93 // status check 94 {Name: "status", Result: "0 75497472 thin-pool 65 327/524288 14092/589824 39 rw no_discard_passdown error_if_no_space - ", Err: nil}, 95 // release reservation 96 {Name: "message", Result: "", Err: fmt.Errorf("not gonna work")}, 97 }, 98 expectedError: true, 99 }, 100 { 101 name: "failure making reservation", 102 dmsetupCommands: []fake.DmsetupCommand{ 103 // status check 104 {Name: "status", Result: "0 75497472 thin-pool 65 327/524288 14092/589824 39 rw no_discard_passdown error_if_no_space - ", Err: nil}, 105 // release reservation 106 {Name: "message", Result: "", Err: nil}, 107 // make reservation 108 {Name: "message", Result: "", Err: fmt.Errorf("not gonna work")}, 109 }, 110 expectedError: true, 111 }, 112 { 113 name: "failure running thin_ls", 114 dmsetupCommands: []fake.DmsetupCommand{ 115 // status check 116 {Name: "status", Result: "0 75497472 thin-pool 65 327/524288 14092/589824 39 rw no_discard_passdown error_if_no_space - ", Err: nil}, 117 // release reservation 118 {Name: "message", Result: "", Err: nil}, 119 // make reservation 120 {Name: "message", Result: "", Err: nil}, 121 // release reservation 122 {Name: "message", Result: "", Err: nil}, 123 }, 124 thinLsErr: fmt.Errorf("not gonna work"), 125 expectedError: true, 126 }, 127 } 128 129 for _, tc := range cases { 130 dmsetup := fake.NewFakeDmsetupClient(t, tc.dmsetupCommands...) 131 thinLsClient := fake.NewFakeThinLsClient(tc.thinLsOutput, tc.thinLsErr) 132 watcher := &ThinPoolWatcher{ 133 poolName: "test pool name", 134 metadataDevice: "/dev/mapper/metadata-device", 135 lock: &sync.RWMutex{}, 136 period: 15 * time.Second, 137 stopChan: make(chan struct{}), 138 dmsetup: dmsetup, 139 thinLsClient: thinLsClient, 140 } 141 142 err := watcher.Refresh() 143 if err != nil { 144 if !tc.expectedError { 145 t.Errorf("%v: unexpected error: %v", tc.name, err) 146 } 147 continue 148 } else if tc.expectedError { 149 t.Errorf("%v: unexpected success", tc.name) 150 continue 151 } 152 153 actualUsage, err := watcher.GetUsage(tc.deviceID) 154 if err != nil { 155 t.Errorf("%v: device ID not found: %v", tc.deviceID, err) 156 continue 157 } 158 159 if e, a := tc.expectedUsage, actualUsage; e != a { 160 t.Errorf("%v: actual usage did not match expected usage: expected: %v got: %v", tc.name, e, a) 161 } 162 } 163 } 164 165 func TestCheckReservation(t *testing.T) { 166 cases := []struct { 167 name string 168 statusResult string 169 statusErr error 170 expectedResult bool 171 expectedErr error 172 }{ 173 { 174 name: "existing reservation 1", 175 statusResult: "0 75497472 thin-pool 65 327/524288 14092/589824 36 rw no_discard_passdown queue_if_no_space - ", 176 expectedResult: true, 177 }, 178 { 179 name: "existing reservation 2", 180 statusResult: "0 12345 thin-pool 65 327/45678 14092/45678 36 rw discard_passdown error_if_no_space needs_check ", 181 expectedResult: true, 182 }, 183 { 184 name: "no reservation 1", 185 statusResult: "0 75497472 thin-pool 65 327/524288 14092/589824 - rw no_discard_passdown error_if_no_space - ", 186 expectedResult: false, 187 }, 188 { 189 name: "no reservation 2", 190 statusResult: "0 75 thin-pool 65 327/12345 14092/589824 - rw no_discard_passdown queue_if_no_space - ", 191 expectedResult: false, 192 }, 193 { 194 name: "no reservation 2", 195 statusResult: "0 75 thin-pool 65 327/12345 14092/589824 - rw no_discard_passdown queue_if_no_space - ", 196 expectedResult: false, 197 }, 198 } 199 200 for _, tc := range cases { 201 fakeDmsetupClient := fake.NewFakeDmsetupClient(t) 202 fakeDmsetupClient.AddCommand("status", tc.statusResult, tc.statusErr) 203 watcher := &ThinPoolWatcher{dmsetup: fakeDmsetupClient} 204 actualResult, err := watcher.checkReservation("test pool") 205 if err != nil { 206 if tc.expectedErr == nil { 207 t.Errorf("%v: unexpected error running checkReservation: %v", tc.name, err) 208 } 209 } else if tc.expectedErr != nil { 210 t.Errorf("%v: unexpected success running checkReservation", tc.name) 211 } 212 213 if e, a := tc.expectedResult, actualResult; e != a { 214 t.Errorf("%v: unexpected result from checkReservation: expected: %v got: %v", tc.name, e, a) 215 } 216 } 217 }