github.com/uber/kraken@v0.1.4/lib/store/cleanup_test.go (about)

     1  // Copyright (c) 2016-2019 Uber Technologies, Inc.
     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  package store
    15  
    16  import (
    17  	"io/ioutil"
    18  	"os"
    19  	"testing"
    20  	"time"
    21  
    22  	"github.com/uber/kraken/core"
    23  	"github.com/uber/kraken/lib/store/base"
    24  	"github.com/uber/kraken/lib/store/metadata"
    25  	"github.com/uber/kraken/utils/testutil"
    26  
    27  	"github.com/andres-erbsen/clock"
    28  	"github.com/stretchr/testify/require"
    29  	"github.com/uber-go/tally"
    30  )
    31  
    32  func fileOpFixture(clk clock.Clock) (base.FileState, base.FileOp, func()) {
    33  	var cleanup testutil.Cleanup
    34  	defer cleanup.Recover()
    35  
    36  	dir, err := ioutil.TempDir("/tmp", "cleanup_test")
    37  	if err != nil {
    38  		panic(err)
    39  	}
    40  	cleanup.Add(func() { os.RemoveAll(dir) })
    41  
    42  	state := base.NewFileState(dir)
    43  
    44  	store := base.NewLocalFileStore(clk)
    45  
    46  	return state, store.NewFileOp().AcceptState(state), cleanup.Run
    47  }
    48  
    49  func TestCleanupManagerAddJob(t *testing.T) {
    50  	require := require.New(t)
    51  
    52  	clk := clock.New()
    53  
    54  	m, err := newCleanupManager(clk, tally.NoopScope)
    55  	require.NoError(err)
    56  	defer m.stop()
    57  
    58  	state, op, cleanup := fileOpFixture(clk)
    59  	defer cleanup()
    60  
    61  	config := CleanupConfig{
    62  		Interval: time.Second,
    63  		TTI:      time.Second,
    64  	}
    65  	m.addJob("test_cleanup", config, op)
    66  
    67  	name := "test_file"
    68  
    69  	require.NoError(op.CreateFile(name, state, 0))
    70  
    71  	time.Sleep(2 * time.Second)
    72  
    73  	_, err = op.GetFileStat(name)
    74  	require.True(os.IsNotExist(err))
    75  }
    76  
    77  func TestCleanupManagerDeleteIdleFiles(t *testing.T) {
    78  	require := require.New(t)
    79  
    80  	clk := clock.NewMock()
    81  	clk.Set(time.Now())
    82  	tti := 6 * time.Hour
    83  	ttl := 24 * time.Hour
    84  
    85  	m, err := newCleanupManager(clk, tally.NoopScope)
    86  	require.NoError(err)
    87  	defer m.stop()
    88  
    89  	state, op, cleanup := fileOpFixture(clk)
    90  	defer cleanup()
    91  
    92  	var names []string
    93  	for i := 0; i < 100; i++ {
    94  		names = append(names, core.DigestFixture().Hex())
    95  	}
    96  
    97  	idle := names[:50]
    98  	for _, name := range idle {
    99  		require.NoError(op.CreateFile(name, state, 0))
   100  	}
   101  
   102  	clk.Add(tti + 1)
   103  
   104  	active := names[50:]
   105  	for _, name := range active {
   106  		require.NoError(op.CreateFile(name, state, 0))
   107  	}
   108  
   109  	_, err = m.scan(op, tti, ttl)
   110  	require.NoError(err)
   111  
   112  	for _, name := range idle {
   113  		_, err := op.GetFileStat(name)
   114  		require.True(os.IsNotExist(err))
   115  	}
   116  	for _, name := range active {
   117  		_, err := op.GetFileStat(name)
   118  		require.NoError(err)
   119  	}
   120  }
   121  
   122  func TestCleanupManagerDeleteExpiredFiles(t *testing.T) {
   123  	require := require.New(t)
   124  
   125  	clk := clock.NewMock()
   126  	clk.Set(time.Now())
   127  	tti := 6 * time.Hour
   128  	ttl := 24 * time.Hour
   129  
   130  	m, err := newCleanupManager(clk, tally.NoopScope)
   131  	require.NoError(err)
   132  	defer m.stop()
   133  
   134  	state, op, cleanup := fileOpFixture(clk)
   135  	defer cleanup()
   136  
   137  	var names []string
   138  	for i := 0; i < 10; i++ {
   139  		names = append(names, core.DigestFixture().Hex())
   140  	}
   141  	for _, name := range names {
   142  		require.NoError(op.CreateFile(name, state, 0))
   143  	}
   144  
   145  	_, err = m.scan(op, tti, ttl)
   146  	require.NoError(err)
   147  
   148  	for _, name := range names {
   149  		_, err := op.GetFileStat(name)
   150  		require.NoError(err)
   151  	}
   152  
   153  	clk.Add(ttl + 1)
   154  
   155  	_, err = m.scan(op, tti, ttl)
   156  	require.NoError(err)
   157  
   158  	for _, name := range names {
   159  		_, err := op.GetFileStat(name)
   160  		require.True(os.IsNotExist(err))
   161  	}
   162  }
   163  
   164  func TestCleanupManagerSkipsPersistedFiles(t *testing.T) {
   165  	require := require.New(t)
   166  
   167  	clk := clock.NewMock()
   168  	clk.Set(time.Now())
   169  	tti := 48 * time.Hour
   170  	ttl := 24 * time.Hour
   171  
   172  	m, err := newCleanupManager(clk, tally.NoopScope)
   173  	require.NoError(err)
   174  	defer m.stop()
   175  
   176  	state, op, cleanup := fileOpFixture(clk)
   177  	defer cleanup()
   178  
   179  	var names []string
   180  	for i := 0; i < 100; i++ {
   181  		names = append(names, core.DigestFixture().Hex())
   182  	}
   183  
   184  	idle := names[:50]
   185  	for _, name := range idle {
   186  		require.NoError(op.CreateFile(name, state, 0))
   187  	}
   188  
   189  	persisted := names[50:]
   190  	for _, name := range persisted {
   191  		require.NoError(op.CreateFile(name, state, 0))
   192  		_, err := op.SetFileMetadata(name, metadata.NewPersist(true))
   193  		require.NoError(err)
   194  	}
   195  
   196  	clk.Add(tti + 1)
   197  
   198  	_, err = m.scan(op, tti, ttl)
   199  	require.NoError(err)
   200  
   201  	for _, name := range idle {
   202  		_, err := op.GetFileStat(name)
   203  		require.True(os.IsNotExist(err))
   204  	}
   205  	for _, name := range persisted {
   206  		_, err := op.GetFileStat(name)
   207  		require.NoError(err)
   208  	}
   209  }
   210  
   211  func TestCleanupManageDiskUsage(t *testing.T) {
   212  	require := require.New(t)
   213  
   214  	clk := clock.New()
   215  
   216  	m, err := newCleanupManager(clk, tally.NoopScope)
   217  	require.NoError(err)
   218  	defer m.stop()
   219  
   220  	state, op, cleanup := fileOpFixture(clk)
   221  	defer cleanup()
   222  
   223  	for i := 0; i < 100; i++ {
   224  		require.NoError(op.CreateFile(core.DigestFixture().Hex(), state, 5))
   225  	}
   226  
   227  	usage, err := m.scan(op, time.Hour, time.Hour)
   228  	require.NoError(err)
   229  	require.Equal(int64(500), usage)
   230  }