| 
									
										
										
										
											2021-11-12 00:45:25 +08:00
										 |  |  | // Copyright 2021 The Prometheus Authors
 | 
					
						
							|  |  |  | // 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 tsdbutil | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							|  |  |  | 	"fmt" | 
					
						
							|  |  |  | 	"os" | 
					
						
							|  |  |  | 	"testing" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/go-kit/log" | 
					
						
							|  |  |  | 	prom_testutil "github.com/prometheus/client_golang/prometheus/testutil" | 
					
						
							|  |  |  | 	"github.com/stretchr/testify/require" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	"github.com/prometheus/prometheus/util/testutil" | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // TestDirLockerUsage performs a set of tests which guarantee correct usage of
 | 
					
						
							|  |  |  | // DirLocker. open should use data as the storage directory, and createLock
 | 
					
						
							|  |  |  | // to determine if a lock file should be used.
 | 
					
						
							|  |  |  | func TestDirLockerUsage(t *testing.T, open func(t *testing.T, data string, createLock bool) (*DirLocker, testutil.Closer)) { | 
					
						
							|  |  |  | 	t.Helper() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	cases := []struct { | 
					
						
							|  |  |  | 		fileAlreadyExists bool | 
					
						
							|  |  |  | 		lockFileDisabled  bool | 
					
						
							|  |  |  | 		expectedValue     int | 
					
						
							|  |  |  | 	}{ | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			fileAlreadyExists: false, | 
					
						
							|  |  |  | 			lockFileDisabled:  false, | 
					
						
							|  |  |  | 			expectedValue:     lockfileCreatedCleanly, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			fileAlreadyExists: true, | 
					
						
							|  |  |  | 			lockFileDisabled:  false, | 
					
						
							|  |  |  | 			expectedValue:     lockfileReplaced, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			fileAlreadyExists: true, | 
					
						
							|  |  |  | 			lockFileDisabled:  true, | 
					
						
							|  |  |  | 			expectedValue:     lockfileDisabled, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			fileAlreadyExists: false, | 
					
						
							|  |  |  | 			lockFileDisabled:  true, | 
					
						
							|  |  |  | 			expectedValue:     lockfileDisabled, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for _, c := range cases { | 
					
						
							|  |  |  | 		t.Run(fmt.Sprintf("%+v", c), func(t *testing.T) { | 
					
						
							| 
									
										
										
										
											2022-04-27 17:24:36 +08:00
										 |  |  | 			tmpdir, err := os.MkdirTemp("", "test") | 
					
						
							| 
									
										
										
										
											2021-11-12 00:45:25 +08:00
										 |  |  | 			require.NoError(t, err) | 
					
						
							|  |  |  | 			t.Cleanup(func() { | 
					
						
							|  |  |  | 				require.NoError(t, os.RemoveAll(tmpdir)) | 
					
						
							|  |  |  | 			}) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// Test preconditions (file already exists + lockfile option)
 | 
					
						
							|  |  |  | 			if c.fileAlreadyExists { | 
					
						
							|  |  |  | 				tmpLocker, err := NewDirLocker(tmpdir, "tsdb", log.NewNopLogger(), nil) | 
					
						
							|  |  |  | 				require.NoError(t, err) | 
					
						
							| 
									
										
										
										
											2022-04-27 17:24:36 +08:00
										 |  |  | 				err = os.WriteFile(tmpLocker.path, []byte{}, 0o644) | 
					
						
							| 
									
										
										
										
											2021-11-12 00:45:25 +08:00
										 |  |  | 				require.NoError(t, err) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			locker, closer := open(t, tmpdir, !c.lockFileDisabled) | 
					
						
							|  |  |  | 			require.Equal(t, float64(c.expectedValue), prom_testutil.ToFloat64(locker.createdCleanly)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// Close the client. This should delete the lockfile.
 | 
					
						
							|  |  |  | 			closer.Close() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			// Check that the lockfile is always deleted
 | 
					
						
							|  |  |  | 			if !c.lockFileDisabled { | 
					
						
							|  |  |  | 				_, err = os.Stat(locker.path) | 
					
						
							|  |  |  | 				require.True(t, os.IsNotExist(err), "lockfile was not deleted") | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		}) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |