Пример #1
0
func TestAreFastForkPackages(t *testing.T) {
	data := []struct {
		description string
		packages    []database.Package
		auth        *gddoexp.GithubAuth
		httpClient  httpClientMock
		expected    []gddoexp.FastForkResponse
	}{
		{
			description: "it should detect that all packages are fast fork (without authentication)",
			packages: []database.Package{
				{Path: "github.com/rafaeljusto/dns"},
				{Path: "github.com/rafaeljusto/go-testdb"},
				{Path: "github.com/rafaeljusto/mysql"},
				{Path: "github.com/rafaeljusto/handy"},
				{Path: "github.com/rafaeljusto/schema"},
			},
			httpClient: httpClientMock{
				getMock: func(url string) (*http.Response, error) {
					if strings.HasSuffix(url, "/commits") {
						return &http.Response{
							StatusCode: http.StatusOK,
							Body: ioutil.NopCloser(bytes.NewBufferString(`[
  {
    "commit": {
      "author": {
        "date": "2010-08-03T23:00:00Z"
      }
    }
  }
]`)),
						}, nil
					}

					return &http.Response{
						StatusCode: http.StatusOK,
						Body: ioutil.NopCloser(bytes.NewBufferString(`{
  "created_at": "2010-08-03T21:56:23Z",
  "fork": true
}`)),
					}, nil
				},
			},
			expected: []gddoexp.FastForkResponse{
				{
					Path:     "github.com/rafaeljusto/dns",
					FastFork: true,
				},
				{
					Path:     "github.com/rafaeljusto/go-testdb",
					FastFork: true,
				},
				{
					Path:     "github.com/rafaeljusto/handy",
					FastFork: true,
				},
				{
					Path:     "github.com/rafaeljusto/mysql",
					FastFork: true,
				},
				{
					Path:     "github.com/rafaeljusto/schema",
					FastFork: true,
				},
			},
		},
		{
			description: "it should detect that all packages are fast fork (authenticated)",
			packages: []database.Package{
				{Path: "github.com/rafaeljusto/dns"},
				{Path: "github.com/rafaeljusto/go-testdb"},
				{Path: "github.com/rafaeljusto/mysql"},
				{Path: "github.com/rafaeljusto/handy"},
				{Path: "github.com/rafaeljusto/schema"},
			},
			auth: &gddoexp.GithubAuth{
				ID:     "exampleuser",
				Secret: "abc123",
			},
			httpClient: httpClientMock{
				getMock: func(url string) (*http.Response, error) {
					if !strings.HasSuffix(url, "?client_id=exampleuser&client_secret=abc123") {
						return &http.Response{
							StatusCode: http.StatusBadRequest,
						}, nil
					}

					url = strings.TrimSuffix(url, "?client_id=exampleuser&client_secret=abc123")

					if strings.HasSuffix(url, "/commits") {
						return &http.Response{
							StatusCode: http.StatusOK,
							Body: ioutil.NopCloser(bytes.NewBufferString(`[
  {
    "commit": {
      "author": {
        "date": "2010-08-03T23:00:00Z"
      }
    }
  }
]`)),
						}, nil
					}

					return &http.Response{
						StatusCode: http.StatusOK,
						Body: ioutil.NopCloser(bytes.NewBufferString(`{
  "created_at": "2010-08-03T21:56:23Z",
  "fork": true
}`)),
					}, nil
				},
			},
			expected: []gddoexp.FastForkResponse{
				{
					Path:     "github.com/rafaeljusto/dns",
					FastFork: true,
				},
				{
					Path:     "github.com/rafaeljusto/go-testdb",
					FastFork: true,
				},
				{
					Path:     "github.com/rafaeljusto/handy",
					FastFork: true,
				},
				{
					Path:     "github.com/rafaeljusto/mysql",
					FastFork: true,
				},
				{
					Path:     "github.com/rafaeljusto/schema",
					FastFork: true,
				},
			},
		},
		{
			description: "it should detect that all packages are fast fork (cache hits)",
			packages: []database.Package{
				{Path: "github.com/rafaeljusto/dns"},
				{Path: "github.com/rafaeljusto/go-testdb"},
				{Path: "github.com/rafaeljusto/mysql"},
				{Path: "github.com/rafaeljusto/handy"},
				{Path: "github.com/rafaeljusto/schema"},
			},
			httpClient: httpClientMock{
				getMock: func(url string) (*http.Response, error) {
					if strings.HasSuffix(url, "/commits") {
						return &http.Response{
							StatusCode: http.StatusOK,
							Header: http.Header{
								"Cache": []string{"1"},
							},
							Body: ioutil.NopCloser(bytes.NewBufferString(`[
  {
    "commit": {
      "author": {
        "date": "2010-08-03T23:00:00Z"
      }
    }
  }
]`)),
						}, nil
					}

					return &http.Response{
						StatusCode: http.StatusOK,
						Header: http.Header{
							"Cache": []string{"1"},
						},
						Body: ioutil.NopCloser(bytes.NewBufferString(`{
  "created_at": "2010-08-03T21:56:23Z",
  "fork": true
}`)),
					}, nil
				},
			},
			expected: []gddoexp.FastForkResponse{
				{
					Path:     "github.com/rafaeljusto/dns",
					FastFork: true,
					Cache:    true,
				},
				{
					Path:     "github.com/rafaeljusto/go-testdb",
					FastFork: true,
					Cache:    true,
				},
				{
					Path:     "github.com/rafaeljusto/handy",
					FastFork: true,
					Cache:    true,
				},
				{
					Path:     "github.com/rafaeljusto/mysql",
					FastFork: true,
					Cache:    true,
				},
				{
					Path:     "github.com/rafaeljusto/schema",
					FastFork: true,
					Cache:    true,
				},
			},
		},
		{
			description: "it should detect that all packages are fast fork (partial cache hits)",
			packages: []database.Package{
				{Path: "github.com/rafaeljusto/dns"},
				{Path: "github.com/rafaeljusto/go-testdb"},
				{Path: "github.com/rafaeljusto/mysql"},
				{Path: "github.com/rafaeljusto/handy"},
				{Path: "github.com/rafaeljusto/schema"},
			},
			httpClient: httpClientMock{
				getMock: func(url string) (*http.Response, error) {
					if strings.HasSuffix(url, "/commits") {
						return &http.Response{
							StatusCode: http.StatusOK,
							Body: ioutil.NopCloser(bytes.NewBufferString(`[
  {
    "commit": {
      "author": {
        "date": "2010-08-03T23:00:00Z"
      }
    }
  }
]`)),
						}, nil
					}

					return &http.Response{
						StatusCode: http.StatusOK,
						Header: http.Header{
							"Cache": []string{"1"},
						},
						Body: ioutil.NopCloser(bytes.NewBufferString(`{
  "created_at": "2010-08-03T21:56:23Z",
  "fork": true
}`)),
					}, nil
				},
			},
			expected: []gddoexp.FastForkResponse{
				{
					Path:     "github.com/rafaeljusto/dns",
					FastFork: true,
				},
				{
					Path:     "github.com/rafaeljusto/go-testdb",
					FastFork: true,
				},
				{
					Path:     "github.com/rafaeljusto/handy",
					FastFork: true,
				},
				{
					Path:     "github.com/rafaeljusto/mysql",
					FastFork: true,
				},
				{
					Path:     "github.com/rafaeljusto/schema",
					FastFork: true,
				},
			},
		},
	}

	httpClientBkp := gddoexp.HTTPClient
	defer func() {
		gddoexp.HTTPClient = httpClientBkp
	}()

	isCacheResponseBkp := gddoexp.IsCacheResponse
	defer func() {
		gddoexp.IsCacheResponse = isCacheResponseBkp
	}()
	gddoexp.IsCacheResponse = func(r *http.Response) bool {
		return r.Header.Get("Cache") == "1"
	}

	for i, item := range data {
		gddoexp.HTTPClient = item.httpClient

		var responses []gddoexp.FastForkResponse
		for response := range gddoexp.AreFastForkPackages(item.packages, item.auth) {
			responses = append(responses, response)
		}

		sort.Sort(byFastForkResponsePath(responses))
		if !reflect.DeepEqual(item.expected, responses) {
			t.Errorf("[%d] %s: mismatch responses.\n%v", i, item.description, diff(item.expected, responses))
		}
	}
}
Пример #2
0
func main() {
	clientID := flag.String("id", "", "Github client ID")
	clientSecret := flag.String("secret", "", "Github client secret")
	file := flag.String("file", "", "File containing the list of packages")
	output := flag.String("output", "gddofork.out", "Output file")
	progress := flag.Bool("progress", false, "Show a progress bar")
	flag.Parse()

	var auth *gddoexp.GithubAuth
	if (clientID != nil && *clientID != "") || (clientSecret != nil && *clientSecret != "") {
		if *clientID == "" || *clientSecret == "" {
			fmt.Println("to enable Gthub authentication, you need to inform the id and secret")
			flag.PrintDefaults()
			return
		}

		auth = &gddoexp.GithubAuth{
			ID:     *clientID,
			Secret: *clientSecret,
		}
	}

	var pkgs []database.Package
	var err error

	if file != nil && *file != "" {
		pkgs, err = readFromFile(*file)
	} else {
		pkgs, err = readFromStdin()
	}

	if err != nil {
		fmt.Println(err)
		return
	}

	o, err := os.OpenFile(*output, os.O_RDWR|os.O_CREATE|os.O_APPEND, 0666)
	if err != nil {
		fmt.Println("error creating output file:", err)
		return
	}
	defer o.Close()

	log.SetOutput(o)
	log.Println("BEGIN")
	log.Printf("%d packages will be analyzed", len(pkgs))

	var progressBar *pb.ProgressBar
	if progress != nil && *progress {
		progressBar = pb.StartNew(len(pkgs))
	}

	var cache int

	for response := range gddoexp.AreFastForkPackages(pkgs, auth) {
		if progress != nil && *progress {
			progressBar.Increment()
		}

		if response.Cache {
			cache++
		}

		if response.Error != nil {
			log.Println(response.Error)
		} else if response.FastFork {
			log.Printf("package “%s” is a fast fork\n", response.Path)
			if progress != nil && !*progress {
				fmt.Println(response.Path)
			}
		} else {
			log.Printf("package “%s” is not a fast fork\n", response.Path)
		}
	}

	if progress != nil && *progress {
		progressBar.Finish()
	}

	log.Println("Cache hits:", cache)
	log.Println("END")
}