github.com/nilium/gitlab-runner@v12.5.0+incompatible/commands/helpers/cache_extractor_test.go (about)

     1  package helpers
     2  
     3  import (
     4  	"archive/zip"
     5  	"bytes"
     6  	"net/http"
     7  	"net/http/httptest"
     8  	"os"
     9  	"testing"
    10  	"time"
    11  
    12  	"github.com/sirupsen/logrus"
    13  	"github.com/stretchr/testify/assert"
    14  
    15  	"gitlab.com/gitlab-org/gitlab-runner/helpers"
    16  )
    17  
    18  const cacheExtractorArchive = "archive.zip"
    19  const cacheExtractorTestArchivedFile = "archive_file"
    20  
    21  func TestCacheExtractorValidArchive(t *testing.T) {
    22  	file, err := os.Create(cacheExtractorArchive)
    23  	assert.NoError(t, err)
    24  	defer file.Close()
    25  	defer os.Remove(file.Name())
    26  	defer os.Remove(cacheExtractorTestArchivedFile)
    27  
    28  	archive := zip.NewWriter(file)
    29  	_, err = archive.Create(cacheExtractorTestArchivedFile)
    30  	assert.NoError(t, err)
    31  
    32  	archive.Close()
    33  
    34  	_, err = os.Stat(cacheExtractorTestArchivedFile)
    35  	assert.Error(t, err)
    36  
    37  	cmd := CacheExtractorCommand{
    38  		File: cacheExtractorArchive,
    39  	}
    40  	assert.NotPanics(t, func() {
    41  		cmd.Execute(nil)
    42  	})
    43  
    44  	_, err = os.Stat(cacheExtractorTestArchivedFile)
    45  	assert.NoError(t, err)
    46  }
    47  
    48  func TestCacheExtractorForInvalidArchive(t *testing.T) {
    49  	removeHook := helpers.MakeFatalToPanic()
    50  	defer removeHook()
    51  	writeTestFile(t, cacheExtractorArchive)
    52  	defer os.Remove(cacheExtractorArchive)
    53  
    54  	cmd := CacheExtractorCommand{
    55  		File: cacheExtractorArchive,
    56  	}
    57  	assert.Panics(t, func() {
    58  		cmd.Execute(nil)
    59  	})
    60  }
    61  
    62  func TestCacheExtractorForIfNoFileDefined(t *testing.T) {
    63  	removeHook := helpers.MakeFatalToPanic()
    64  	defer removeHook()
    65  	cmd := CacheExtractorCommand{}
    66  	assert.Panics(t, func() {
    67  		cmd.Execute(nil)
    68  	})
    69  }
    70  
    71  func TestCacheExtractorForNotExistingFile(t *testing.T) {
    72  	removeHook := helpers.MakeFatalToPanic()
    73  	defer removeHook()
    74  	cmd := CacheExtractorCommand{
    75  		File: "/../../../test.zip",
    76  	}
    77  	assert.NotPanics(t, func() {
    78  		cmd.Execute(nil)
    79  	})
    80  }
    81  
    82  func testServeCache(w http.ResponseWriter, r *http.Request) {
    83  	if r.Method != "GET" {
    84  		http.Error(w, "408 Method not allowed", 408)
    85  		return
    86  	}
    87  	if r.URL.Path != "/cache.zip" {
    88  		if r.URL.Path == "/timeout" {
    89  			time.Sleep(50 * time.Millisecond)
    90  		}
    91  		http.NotFound(w, r)
    92  		return
    93  	}
    94  
    95  	w.Header().Set("Last-Modified", time.Now().Format(http.TimeFormat))
    96  	archive := zip.NewWriter(w)
    97  	archive.Create(cacheExtractorTestArchivedFile)
    98  	archive.Close()
    99  }
   100  
   101  func TestCacheExtractorRemoteServerNotFound(t *testing.T) {
   102  	ts := httptest.NewServer(http.HandlerFunc(testServeCache))
   103  	defer ts.Close()
   104  
   105  	removeHook := helpers.MakeFatalToPanic()
   106  	defer removeHook()
   107  	cmd := CacheExtractorCommand{
   108  		File:    "non-existing-test.zip",
   109  		URL:     ts.URL + "/invalid-file.zip",
   110  		Timeout: 0,
   111  	}
   112  	assert.Panics(t, func() {
   113  		cmd.Execute(nil)
   114  	})
   115  	_, err := os.Stat(cacheExtractorTestArchivedFile)
   116  	assert.Error(t, err)
   117  }
   118  
   119  func TestCacheExtractorRemoteServerTimedOut(t *testing.T) {
   120  	ts := httptest.NewServer(http.HandlerFunc(testServeCache))
   121  	defer ts.Close()
   122  
   123  	output := logrus.StandardLogger().Out
   124  	var buf bytes.Buffer
   125  	logrus.SetOutput(&buf)
   126  	defer logrus.SetOutput(output)
   127  	removeHook := helpers.MakeFatalToPanic()
   128  	defer removeHook()
   129  
   130  	cmd := CacheExtractorCommand{
   131  		File: "non-existing-test.zip",
   132  		URL:  ts.URL + "/timeout",
   133  	}
   134  	cmd.getClient().Timeout = 1 * time.Millisecond
   135  
   136  	assert.Panics(t, func() {
   137  		cmd.Execute(nil)
   138  	})
   139  	assert.Contains(t, buf.String(), "Client.Timeout")
   140  
   141  	_, err := os.Stat(cacheExtractorTestArchivedFile)
   142  	assert.Error(t, err)
   143  }
   144  
   145  func TestCacheExtractorRemoteServer(t *testing.T) {
   146  	ts := httptest.NewServer(http.HandlerFunc(testServeCache))
   147  	defer ts.Close()
   148  
   149  	defer os.Remove(cacheExtractorArchive)
   150  	defer os.Remove(cacheExtractorTestArchivedFile)
   151  	os.Remove(cacheExtractorArchive)
   152  	os.Remove(cacheExtractorTestArchivedFile)
   153  
   154  	removeHook := helpers.MakeFatalToPanic()
   155  	defer removeHook()
   156  	cmd := CacheExtractorCommand{
   157  		File:    cacheExtractorArchive,
   158  		URL:     ts.URL + "/cache.zip",
   159  		Timeout: 0,
   160  	}
   161  	assert.NotPanics(t, func() {
   162  		cmd.Execute(nil)
   163  	})
   164  
   165  	_, err := os.Stat(cacheExtractorTestArchivedFile)
   166  	assert.NoError(t, err)
   167  
   168  	err = os.Chtimes(cacheExtractorArchive, time.Now().Add(time.Hour), time.Now().Add(time.Hour))
   169  	assert.NoError(t, err)
   170  
   171  	assert.NotPanics(t, func() {
   172  		cmd.Execute(nil)
   173  	}, "archive is up to date")
   174  }
   175  
   176  func TestCacheExtractorRemoteServerFailOnInvalidServer(t *testing.T) {
   177  	removeHook := helpers.MakeFatalToPanic()
   178  	defer removeHook()
   179  	os.Remove(cacheExtractorArchive)
   180  	cmd := CacheExtractorCommand{
   181  		File:    cacheExtractorArchive,
   182  		URL:     "http://localhost:65333/cache.zip",
   183  		Timeout: 0,
   184  	}
   185  	assert.Panics(t, func() {
   186  		cmd.Execute(nil)
   187  	})
   188  
   189  	_, err := os.Stat(cacheExtractorTestArchivedFile)
   190  	assert.Error(t, err)
   191  }