gps/maybe_source_test.go

Summary

Maintainability
A
0 mins
Test Coverage
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gps

import (
    "archive/tar"
    "compress/gzip"
    "context"
    "io"
    "io/ioutil"
    "net/url"
    "os"
    "path/filepath"
    "testing"

    "github.com/Masterminds/vcs"
)

func TestMaybeGitSource_try(t *testing.T) {
    t.Parallel()

    tempDir, err := ioutil.TempDir("", "go-try-happy-test")
    if err != nil {
        t.Fatal(err)
    }
    defer func() {
        err = os.RemoveAll(tempDir)
        if err != nil {
            t.Error(err)
        }
    }()

    url, err := url.Parse(gitRemoteTestRepo)
    if err != nil {
        t.Fatal(err)
    }
    var ms maybeSource = maybeGitSource{url: url}
    _, err = ms.try(context.Background(), tempDir)
    if err != nil {
        t.Fatal(err)
    }
}

func TestMaybeGitSource_try_recovery(t *testing.T) {
    t.Parallel()

    tempDir, err := ioutil.TempDir("", "go-try-recovery-test")
    if err != nil {
        t.Fatal(err)
    }
    defer func() {
        err = os.RemoveAll(tempDir)
        if err != nil {
            t.Error(err)
        }
    }()

    cwd, err := os.Getwd()
    if err != nil {
        t.Fatal(err)
    }

    src := filepath.Join(cwd, "_testdata", "badrepo", "corrupt_dot_git_directory.tar")
    f, err := os.Open(src)
    if err != nil {
        t.Fatal(err)
    }
    defer f.Close()

    dest := filepath.Join(tempDir, ".git")
    err = untar(dest, f)
    if err != nil {
        t.Fatalf("could not untar corrupt repo into temp folder: %v\n", err)
    }

    _, err = vcs.NewGitRepo(gitRemoteTestRepo, tempDir)
    if err != nil {
        if _, ok := err.(*vcs.LocalError); !ok {
            t.Fatalf("expected a local error but got: %v\n", err)
        }
    } else {
        t.Fatal("expected getVCSRepo to fail when pointing to a corrupt local path. It is possible that vcs.GitNewRepo updated to gracefully handle this test scenario. Check the return of vcs.GitNewRepo.")
    }

    url, err := url.Parse(gitRemoteTestRepo)
    if err != nil {
        t.Fatal(err)
    }
    var ms maybeSource = maybeGitSource{url: url}
    _, err = ms.try(context.Background(), tempDir)
    if err != nil {
        t.Fatal(err)
    }
}

func untar(dst string, r io.Reader) error {
    gzr, err := gzip.NewReader(r)
    if err != nil {
        return err
    }
    defer gzr.Close()

    tr := tar.NewReader(gzr)

    for {
        header, err := tr.Next()

        switch {
        case err == io.EOF:
            return nil
        case err != nil:
            return err
        case header == nil:
            continue
        }

        target := filepath.Join(dst, header.Name)
        switch header.Typeflag {
        case tar.TypeDir:
            if _, err := os.Stat(target); err != nil {
                if err := os.MkdirAll(target, 0755); err != nil {
                    return err
                }
            }
        case tar.TypeReg:
            f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
            if err != nil {
                return err
            }
            defer f.Close()

            if _, err := io.Copy(f, tr); err != nil {
                return err
            }
        }
    }
}