github.com/mika/distribution@v2.2.2-0.20160108133430-a75790e3d8e0+incompatible/registry/proxy/scheduler/scheduler_test.go (about)

     1  package scheduler
     2  
     3  import (
     4  	"encoding/json"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/docker/distribution/context"
     9  	"github.com/docker/distribution/registry/storage/driver/inmemory"
    10  )
    11  
    12  func TestSchedule(t *testing.T) {
    13  	timeUnit := time.Millisecond
    14  	remainingRepos := map[string]bool{
    15  		"testBlob1": true,
    16  		"testBlob2": true,
    17  		"ch00":      true,
    18  	}
    19  
    20  	s := New(context.Background(), inmemory.New(), "/ttl")
    21  	deleteFunc := func(repoName string) error {
    22  		if len(remainingRepos) == 0 {
    23  			t.Fatalf("Incorrect expiry count")
    24  		}
    25  		_, ok := remainingRepos[repoName]
    26  		if !ok {
    27  			t.Fatalf("Trying to remove nonexistant repo: %s", repoName)
    28  		}
    29  		t.Log("removing", repoName)
    30  		delete(remainingRepos, repoName)
    31  
    32  		return nil
    33  	}
    34  	s.onBlobExpire = deleteFunc
    35  	err := s.Start()
    36  	if err != nil {
    37  		t.Fatalf("Error starting ttlExpirationScheduler: %s", err)
    38  	}
    39  
    40  	s.add("testBlob1", 3*timeUnit, entryTypeBlob)
    41  	s.add("testBlob2", 1*timeUnit, entryTypeBlob)
    42  
    43  	func() {
    44  		s.add("ch00", 1*timeUnit, entryTypeBlob)
    45  
    46  	}()
    47  
    48  	// Ensure all repos are deleted
    49  	<-time.After(50 * timeUnit)
    50  	if len(remainingRepos) != 0 {
    51  		t.Fatalf("Repositories remaining: %#v", remainingRepos)
    52  	}
    53  }
    54  
    55  func TestRestoreOld(t *testing.T) {
    56  	remainingRepos := map[string]bool{
    57  		"testBlob1": true,
    58  		"oldRepo":   true,
    59  	}
    60  
    61  	deleteFunc := func(repoName string) error {
    62  		if repoName == "oldRepo" && len(remainingRepos) == 3 {
    63  			t.Errorf("oldRepo should be removed first")
    64  		}
    65  		_, ok := remainingRepos[repoName]
    66  		if !ok {
    67  			t.Fatalf("Trying to remove nonexistant repo: %s", repoName)
    68  		}
    69  		delete(remainingRepos, repoName)
    70  		return nil
    71  	}
    72  
    73  	timeUnit := time.Millisecond
    74  	serialized, err := json.Marshal(&map[string]schedulerEntry{
    75  		"testBlob1": {
    76  			Expiry:    time.Now().Add(1 * timeUnit),
    77  			Key:       "testBlob1",
    78  			EntryType: 0,
    79  		},
    80  		"oldRepo": {
    81  			Expiry:    time.Now().Add(-3 * timeUnit), // TTL passed, should be removed first
    82  			Key:       "oldRepo",
    83  			EntryType: 0,
    84  		},
    85  	})
    86  	if err != nil {
    87  		t.Fatalf("Error serializing test data: %s", err.Error())
    88  	}
    89  
    90  	ctx := context.Background()
    91  	pathToStatFile := "/ttl"
    92  	fs := inmemory.New()
    93  	err = fs.PutContent(ctx, pathToStatFile, serialized)
    94  	if err != nil {
    95  		t.Fatal("Unable to write serialized data to fs")
    96  	}
    97  	s := New(context.Background(), fs, "/ttl")
    98  	s.onBlobExpire = deleteFunc
    99  	err = s.Start()
   100  	if err != nil {
   101  		t.Fatalf("Error starting ttlExpirationScheduler: %s", err)
   102  	}
   103  
   104  	<-time.After(50 * timeUnit)
   105  	if len(remainingRepos) != 0 {
   106  		t.Fatalf("Repositories remaining: %#v", remainingRepos)
   107  	}
   108  }
   109  
   110  func TestStopRestore(t *testing.T) {
   111  	timeUnit := time.Millisecond
   112  	remainingRepos := map[string]bool{
   113  		"testBlob1": true,
   114  		"testBlob2": true,
   115  	}
   116  	deleteFunc := func(repoName string) error {
   117  		delete(remainingRepos, repoName)
   118  		return nil
   119  	}
   120  
   121  	fs := inmemory.New()
   122  	pathToStateFile := "/ttl"
   123  	s := New(context.Background(), fs, pathToStateFile)
   124  	s.onBlobExpire = deleteFunc
   125  
   126  	err := s.Start()
   127  	if err != nil {
   128  		t.Fatalf(err.Error())
   129  	}
   130  	s.add("testBlob1", 300*timeUnit, entryTypeBlob)
   131  	s.add("testBlob2", 100*timeUnit, entryTypeBlob)
   132  
   133  	// Start and stop before all operations complete
   134  	// state will be written to fs
   135  	s.Stop()
   136  	time.Sleep(10 * time.Millisecond)
   137  
   138  	// v2 will restore state from fs
   139  	s2 := New(context.Background(), fs, pathToStateFile)
   140  	s2.onBlobExpire = deleteFunc
   141  	err = s2.Start()
   142  	if err != nil {
   143  		t.Fatalf("Error starting v2: %s", err.Error())
   144  	}
   145  
   146  	<-time.After(500 * timeUnit)
   147  	if len(remainingRepos) != 0 {
   148  		t.Fatalf("Repositories remaining: %#v", remainingRepos)
   149  	}
   150  
   151  }
   152  
   153  func TestDoubleStart(t *testing.T) {
   154  	s := New(context.Background(), inmemory.New(), "/ttl")
   155  	err := s.Start()
   156  	if err != nil {
   157  		t.Fatalf("Unable to start scheduler")
   158  	}
   159  	err = s.Start()
   160  	if err == nil {
   161  		t.Fatalf("Scheduler started twice without error")
   162  	}
   163  }