github.com/rahart/packer@v0.12.2-0.20161229105310-282bb6ad370f/common/download_test.go (about)

     1  package common
     2  
     3  import (
     4  	"crypto/md5"
     5  	"encoding/hex"
     6  	"fmt"
     7  	"io/ioutil"
     8  	"net/http"
     9  	"net/http/httptest"
    10  	"os"
    11  	"runtime"
    12  	"testing"
    13  )
    14  
    15  func TestDownloadClientVerifyChecksum(t *testing.T) {
    16  	tf, err := ioutil.TempFile("", "packer")
    17  	if err != nil {
    18  		t.Fatalf("tempfile error: %s", err)
    19  	}
    20  	defer os.Remove(tf.Name())
    21  
    22  	// "foo"
    23  	checksum, err := hex.DecodeString("acbd18db4cc2f85cedef654fccc4a4d8")
    24  	if err != nil {
    25  		t.Fatalf("decode err: %s", err)
    26  	}
    27  
    28  	// Write the file
    29  	tf.Write([]byte("foo"))
    30  	tf.Close()
    31  
    32  	config := &DownloadConfig{
    33  		Hash:     md5.New(),
    34  		Checksum: checksum,
    35  	}
    36  
    37  	d := NewDownloadClient(config)
    38  	result, err := d.VerifyChecksum(tf.Name())
    39  	if err != nil {
    40  		t.Fatalf("Verify err: %s", err)
    41  	}
    42  
    43  	if !result {
    44  		t.Fatal("didn't verify")
    45  	}
    46  }
    47  
    48  func TestDownloadClient_basic(t *testing.T) {
    49  	tf, _ := ioutil.TempFile("", "packer")
    50  	tf.Close()
    51  	os.Remove(tf.Name())
    52  
    53  	ts := httptest.NewServer(http.FileServer(http.Dir("./test-fixtures/root")))
    54  	defer ts.Close()
    55  
    56  	client := NewDownloadClient(&DownloadConfig{
    57  		Url:        ts.URL + "/basic.txt",
    58  		TargetPath: tf.Name(),
    59  	})
    60  
    61  	path, err := client.Get()
    62  	if err != nil {
    63  		t.Fatalf("err: %s", err)
    64  	}
    65  
    66  	raw, err := ioutil.ReadFile(path)
    67  	if err != nil {
    68  		t.Fatalf("err: %s", err)
    69  	}
    70  
    71  	if string(raw) != "hello\n" {
    72  		t.Fatalf("bad: %s", string(raw))
    73  	}
    74  }
    75  
    76  func TestDownloadClient_checksumBad(t *testing.T) {
    77  	checksum, err := hex.DecodeString("b2946ac92492d2347c6235b4d2611184")
    78  	if err != nil {
    79  		t.Fatalf("err: %s", err)
    80  	}
    81  
    82  	tf, _ := ioutil.TempFile("", "packer")
    83  	tf.Close()
    84  	os.Remove(tf.Name())
    85  
    86  	ts := httptest.NewServer(http.FileServer(http.Dir("./test-fixtures/root")))
    87  	defer ts.Close()
    88  
    89  	client := NewDownloadClient(&DownloadConfig{
    90  		Url:        ts.URL + "/basic.txt",
    91  		TargetPath: tf.Name(),
    92  		Hash:       HashForType("md5"),
    93  		Checksum:   checksum,
    94  	})
    95  	if _, err := client.Get(); err == nil {
    96  		t.Fatal("should error")
    97  	}
    98  }
    99  
   100  func TestDownloadClient_checksumGood(t *testing.T) {
   101  	checksum, err := hex.DecodeString("b1946ac92492d2347c6235b4d2611184")
   102  	if err != nil {
   103  		t.Fatalf("err: %s", err)
   104  	}
   105  
   106  	tf, _ := ioutil.TempFile("", "packer")
   107  	tf.Close()
   108  	os.Remove(tf.Name())
   109  
   110  	ts := httptest.NewServer(http.FileServer(http.Dir("./test-fixtures/root")))
   111  	defer ts.Close()
   112  
   113  	client := NewDownloadClient(&DownloadConfig{
   114  		Url:        ts.URL + "/basic.txt",
   115  		TargetPath: tf.Name(),
   116  		Hash:       HashForType("md5"),
   117  		Checksum:   checksum,
   118  	})
   119  	path, err := client.Get()
   120  	if err != nil {
   121  		t.Fatalf("err: %s", err)
   122  	}
   123  
   124  	raw, err := ioutil.ReadFile(path)
   125  	if err != nil {
   126  		t.Fatalf("err: %s", err)
   127  	}
   128  
   129  	if string(raw) != "hello\n" {
   130  		t.Fatalf("bad: %s", string(raw))
   131  	}
   132  }
   133  
   134  func TestDownloadClient_checksumNoDownload(t *testing.T) {
   135  	checksum, err := hex.DecodeString("3740570a423feec44c2a759225a9fcf9")
   136  	if err != nil {
   137  		t.Fatalf("err: %s", err)
   138  	}
   139  
   140  	ts := httptest.NewServer(http.FileServer(http.Dir("./test-fixtures/root")))
   141  	defer ts.Close()
   142  
   143  	client := NewDownloadClient(&DownloadConfig{
   144  		Url:        ts.URL + "/basic.txt",
   145  		TargetPath: "./test-fixtures/root/another.txt",
   146  		Hash:       HashForType("md5"),
   147  		Checksum:   checksum,
   148  	})
   149  	path, err := client.Get()
   150  	if err != nil {
   151  		t.Fatalf("err: %s", err)
   152  	}
   153  
   154  	raw, err := ioutil.ReadFile(path)
   155  	if err != nil {
   156  		t.Fatalf("err: %s", err)
   157  	}
   158  
   159  	// If this says "hello" it means we downloaded it. We faked out
   160  	// the downloader above by giving it the checksum for "another", but
   161  	// requested the download of "hello"
   162  	if string(raw) != "another\n" {
   163  		t.Fatalf("bad: %s", string(raw))
   164  	}
   165  }
   166  
   167  func TestDownloadClient_resume(t *testing.T) {
   168  	tf, _ := ioutil.TempFile("", "packer")
   169  	tf.Write([]byte("w"))
   170  	tf.Close()
   171  
   172  	ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
   173  		if r.Method == "HEAD" {
   174  			rw.Header().Set("Accept-Ranges", "bytes")
   175  			rw.WriteHeader(204)
   176  			return
   177  		}
   178  
   179  		http.ServeFile(rw, r, "./test-fixtures/root/basic.txt")
   180  	}))
   181  	defer ts.Close()
   182  
   183  	client := NewDownloadClient(&DownloadConfig{
   184  		Url:        ts.URL,
   185  		TargetPath: tf.Name(),
   186  	})
   187  	path, err := client.Get()
   188  	if err != nil {
   189  		t.Fatalf("err: %s", err)
   190  	}
   191  
   192  	raw, err := ioutil.ReadFile(path)
   193  	if err != nil {
   194  		t.Fatalf("err: %s", err)
   195  	}
   196  
   197  	if string(raw) != "wello\n" {
   198  		t.Fatalf("bad: %s", string(raw))
   199  	}
   200  }
   201  
   202  func TestDownloadClient_usesDefaultUserAgent(t *testing.T) {
   203  	tf, err := ioutil.TempFile("", "packer")
   204  	if err != nil {
   205  		t.Fatalf("tempfile error: %s", err)
   206  	}
   207  	defer os.Remove(tf.Name())
   208  
   209  	defaultUserAgent := ""
   210  	asserted := false
   211  	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   212  		if defaultUserAgent == "" {
   213  			defaultUserAgent = r.UserAgent()
   214  		} else {
   215  			incomingUserAgent := r.UserAgent()
   216  			if incomingUserAgent != defaultUserAgent {
   217  				t.Fatalf("Expected user agent %s, got: %s", defaultUserAgent, incomingUserAgent)
   218  			}
   219  
   220  			asserted = true
   221  		}
   222  	}))
   223  
   224  	req, err := http.NewRequest("GET", server.URL, nil)
   225  	if err != nil {
   226  		t.Fatal(err)
   227  	}
   228  
   229  	httpClient := &http.Client{
   230  		Transport: &http.Transport{
   231  			Proxy: http.ProxyFromEnvironment,
   232  		},
   233  	}
   234  
   235  	_, err = httpClient.Do(req)
   236  	if err != nil {
   237  		t.Fatal(err)
   238  	}
   239  
   240  	config := &DownloadConfig{
   241  		Url:        server.URL,
   242  		TargetPath: tf.Name(),
   243  	}
   244  
   245  	client := NewDownloadClient(config)
   246  	_, err = client.Get()
   247  	if err != nil {
   248  		t.Fatal(err)
   249  	}
   250  
   251  	if !asserted {
   252  		t.Fatal("User-Agent never observed")
   253  	}
   254  }
   255  
   256  func TestDownloadClient_setsUserAgent(t *testing.T) {
   257  	tf, err := ioutil.TempFile("", "packer")
   258  	if err != nil {
   259  		t.Fatalf("tempfile error: %s", err)
   260  	}
   261  	defer os.Remove(tf.Name())
   262  
   263  	asserted := false
   264  	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
   265  		asserted = true
   266  		if r.UserAgent() != "fancy user agent" {
   267  			t.Fatalf("Expected useragent fancy user agent, got: %s", r.UserAgent())
   268  		}
   269  	}))
   270  	config := &DownloadConfig{
   271  		Url:        server.URL,
   272  		TargetPath: tf.Name(),
   273  		UserAgent:  "fancy user agent",
   274  	}
   275  
   276  	client := NewDownloadClient(config)
   277  	_, err = client.Get()
   278  	if err != nil {
   279  		t.Fatal(err)
   280  	}
   281  
   282  	if !asserted {
   283  		t.Fatal("HTTP request never made")
   284  	}
   285  }
   286  
   287  func TestHashForType(t *testing.T) {
   288  	if h := HashForType("md5"); h == nil {
   289  		t.Fatalf("md5 hash is nil")
   290  	} else {
   291  		h.Write([]byte("foo"))
   292  		result := h.Sum(nil)
   293  
   294  		expected := "acbd18db4cc2f85cedef654fccc4a4d8"
   295  		actual := hex.EncodeToString(result)
   296  		if actual != expected {
   297  			t.Fatalf("bad hash: %s", actual)
   298  		}
   299  	}
   300  
   301  	if h := HashForType("sha1"); h == nil {
   302  		t.Fatalf("sha1 hash is nil")
   303  	} else {
   304  		h.Write([]byte("foo"))
   305  		result := h.Sum(nil)
   306  
   307  		expected := "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"
   308  		actual := hex.EncodeToString(result)
   309  		if actual != expected {
   310  			t.Fatalf("bad hash: %s", actual)
   311  		}
   312  	}
   313  
   314  	if h := HashForType("sha256"); h == nil {
   315  		t.Fatalf("sha256 hash is nil")
   316  	} else {
   317  		h.Write([]byte("foo"))
   318  		result := h.Sum(nil)
   319  
   320  		expected := "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"
   321  		actual := hex.EncodeToString(result)
   322  		if actual != expected {
   323  			t.Fatalf("bad hash: %s", actual)
   324  		}
   325  	}
   326  
   327  	if h := HashForType("sha512"); h == nil {
   328  		t.Fatalf("sha512 hash is nil")
   329  	} else {
   330  		h.Write([]byte("foo"))
   331  		result := h.Sum(nil)
   332  
   333  		expected := "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7"
   334  		actual := hex.EncodeToString(result)
   335  		if actual != expected {
   336  			t.Fatalf("bad hash: %s", actual)
   337  		}
   338  	}
   339  
   340  	if HashForType("fake") != nil {
   341  		t.Fatalf("fake hash is not nil")
   342  	}
   343  }
   344  
   345  // TestDownloadFileUrl tests a special case where we use a local file for
   346  // iso_url. In this case we can still verify the checksum but we should not
   347  // delete the file if the checksum fails. Instead we'll just error and let the
   348  // user fix the checksum.
   349  func TestDownloadFileUrl(t *testing.T) {
   350  	cwd, err := os.Getwd()
   351  	if err != nil {
   352  		t.Fatalf("Unable to detect working directory: %s", err)
   353  	}
   354  
   355  	// source_path is a file path and source is a network path
   356  	sourcePath := fmt.Sprintf("%s/test-fixtures/fileurl/%s", cwd, "cake")
   357  
   358  	filePrefix := "file://"
   359  	if runtime.GOOS == "windows" {
   360  		filePrefix += "/"
   361  	}
   362  
   363  	source := fmt.Sprintf(filePrefix + sourcePath)
   364  	t.Logf("Trying to download %s", source)
   365  
   366  	config := &DownloadConfig{
   367  		Url: source,
   368  		// This should be wrong. We want to make sure we don't delete
   369  		Checksum: []byte("nope"),
   370  		Hash:     HashForType("sha256"),
   371  		CopyFile: false,
   372  	}
   373  
   374  	client := NewDownloadClient(config)
   375  
   376  	// Verify that we fail to match the checksum
   377  	_, err = client.Get()
   378  	if err.Error() != "checksums didn't match expected: 6e6f7065" {
   379  		t.Fatalf("Unexpected failure; expected checksum not to match")
   380  	}
   381  
   382  	if _, err = os.Stat(sourcePath); err != nil {
   383  		t.Errorf("Could not stat source file: %s", sourcePath)
   384  	}
   385  
   386  }