"Fossies" - the Fresh Open Source Software Archive

Member "geoipupdate-4.3.0/pkg/geoipupdate/database/http_reader_test.go" (16 Apr 2020, 6879 Bytes) of package /linux/misc/geoipupdate-4.3.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "http_reader_test.go": 4.1.5_vs_4.2.0.

    1 package database
    2 
    3 import (
    4     "bytes"
    5     "compress/gzip"
    6     "crypto/md5"
    7     "fmt"
    8     "io"
    9     "io/ioutil"
   10     "net/http"
   11     "net/http/httptest"
   12     "os"
   13     "path/filepath"
   14     "regexp"
   15     "testing"
   16     "time"
   17 
   18     "github.com/maxmind/geoipupdate/v4/pkg/geoipupdate"
   19     "github.com/stretchr/testify/assert"
   20     "github.com/stretchr/testify/require"
   21 )
   22 
   23 func TestHTTPDatabaseReader(t *testing.T) {
   24     tests := []struct {
   25         Description     string
   26         CreateDirectory bool
   27         DatabaseBefore  string
   28         DatabaseAfter   string
   29         DownloadStatus  int
   30         DownloadBody    string
   31         DownloadHeaders map[string]string
   32         ExpectedTime    time.Time
   33         Err             string
   34     }{
   35         {
   36             Description:     "Initial download, success",
   37             CreateDirectory: true,
   38             DatabaseAfter:   "database goes here",
   39             DownloadStatus:  http.StatusOK,
   40             DownloadBody:    "database goes here",
   41         },
   42         {
   43             Description:     "No update, success",
   44             CreateDirectory: true,
   45             DatabaseBefore:  "database goes here",
   46             DatabaseAfter:   "database goes here",
   47             DownloadStatus:  http.StatusNotModified,
   48             DownloadBody:    "database goes here",
   49         },
   50         {
   51             Description:     "Update, success",
   52             CreateDirectory: true,
   53             DatabaseBefore:  "database goes here",
   54             DatabaseAfter:   "new database goes here",
   55             DownloadStatus:  http.StatusOK,
   56             DownloadBody:    "new database goes here",
   57         },
   58         {
   59             Description:     "Update, success, and modification time is set",
   60             CreateDirectory: true,
   61             DatabaseBefore:  "new database goes here",
   62             DatabaseAfter:   "newer database goes here",
   63             DownloadStatus:  http.StatusOK,
   64             DownloadBody:    "newer database goes here",
   65             DownloadHeaders: map[string]string{
   66                 "Last-Modified": time.Date(2018, 7, 24, 0, 0, 0, 0, time.UTC).Format(time.RFC1123),
   67             },
   68             ExpectedTime: time.Date(2018, 7, 24, 0, 0, 0, 0, time.UTC),
   69         },
   70         {
   71             Description:     "Download request fails",
   72             CreateDirectory: true,
   73             DatabaseBefore:  "database goes here",
   74             DatabaseAfter:   "database goes here",
   75             DownloadStatus:  http.StatusBadRequest,
   76             Err:             "unexpected HTTP status code: 400 Bad Request",
   77         },
   78         {
   79             Description:     "Download request is missing X-Database-MD5",
   80             CreateDirectory: true,
   81             DatabaseBefore:  "database goes here",
   82             DatabaseAfter:   "database goes here",
   83             DownloadStatus:  http.StatusOK,
   84             DownloadBody:    "new database goes here",
   85             DownloadHeaders: map[string]string{
   86                 "X-Database-MD5": "",
   87             },
   88             Err: "no X-Database-MD5 header found",
   89         },
   90         {
   91             Description:     "Download fails because provided checksum does not match",
   92             CreateDirectory: true,
   93             DatabaseBefore:  "database goes here",
   94             DatabaseAfter:   "database goes here",
   95             DownloadStatus:  http.StatusOK,
   96             DownloadBody:    "new database goes here",
   97             DownloadHeaders: map[string]string{
   98                 "X-Database-MD5": "5d41402abc4b2a76b9719d911017c592", // "hello"
   99             },
  100             Err: `md5 of new database \(985ecf3d7959b146208b3dc0189b21a5\) does not match expected md5 \(5d41402abc4b2a76b9719d911017c592\)`,
  101         },
  102         {
  103             Description:     "Download request redirects are followed",
  104             CreateDirectory: true,
  105             DatabaseBefore:  "database goes here",
  106             DatabaseAfter:   "database goes here",
  107             DownloadStatus:  http.StatusMovedPermanently,
  108             DownloadHeaders: map[string]string{
  109                 "Location": "/go-here",
  110             },
  111         },
  112         {
  113             Description:     "MD5 sums are case insensitive",
  114             CreateDirectory: true,
  115             DatabaseBefore:  "database goes here",
  116             DatabaseAfter:   "new database goes here",
  117             DownloadStatus:  http.StatusOK,
  118             DownloadBody:    "new database goes here",
  119             DownloadHeaders: map[string]string{
  120                 "X-Database-MD5": "985ECF3D7959B146208B3DC0189B21A5",
  121             },
  122         },
  123     }
  124 
  125     updateRE := regexp.MustCompile(`\A/geoip/databases/\S+/update\z`)
  126 
  127     tempDir, err := ioutil.TempDir("", "gutest-")
  128     require.NoError(t, err)
  129     err = os.RemoveAll(tempDir)
  130     require.NoError(t, err)
  131 
  132     for _, test := range tests {
  133         t.Run(test.Description, func(t *testing.T) {
  134             server := httptest.NewServer(
  135                 http.HandlerFunc(
  136                     func(rw http.ResponseWriter, r *http.Request) {
  137                         if updateRE.MatchString(r.URL.Path) {
  138                             buf := &bytes.Buffer{}
  139                             gzWriter := gzip.NewWriter(buf)
  140                             md5Writer := md5.New()
  141                             multiWriter := io.MultiWriter(gzWriter, md5Writer)
  142                             _, err := multiWriter.Write([]byte(test.DownloadBody))
  143                             require.NoError(t, err)
  144                             err = gzWriter.Close()
  145                             require.NoError(t, err)
  146 
  147                             rw.Header().Set(
  148                                 "X-Database-MD5",
  149                                 fmt.Sprintf("%x", md5Writer.Sum(nil)),
  150                             )
  151                             if test.DownloadStatus == http.StatusOK {
  152                                 rw.Header().Set(
  153                                     "Last-Modified",
  154                                     time.Now().Format(time.RFC1123),
  155                                 )
  156                             }
  157                             for k, v := range test.DownloadHeaders {
  158                                 rw.Header().Set(k, v)
  159                             }
  160 
  161                             rw.WriteHeader(test.DownloadStatus)
  162 
  163                             if test.DownloadStatus == http.StatusOK {
  164                                 _, err := rw.Write(buf.Bytes())
  165                                 require.NoError(t, err)
  166                             }
  167 
  168                             return
  169                         }
  170 
  171                         if r.URL.Path == "/go-here" {
  172                             rw.WriteHeader(http.StatusNotModified)
  173                             return
  174                         }
  175 
  176                         rw.WriteHeader(http.StatusBadRequest)
  177                     },
  178                 ),
  179             )
  180 
  181             config := &geoipupdate.Config{
  182                 AccountID:         123,
  183                 DatabaseDirectory: tempDir,
  184                 EditionIDs:        []string{"GeoIP2-City"},
  185                 LicenseKey:        "testing",
  186                 LockFile:          filepath.Join(tempDir, ".geoipupdate.lock"),
  187                 URL:               server.URL,
  188             }
  189             if !test.ExpectedTime.IsZero() {
  190                 config.PreserveFileTimes = true
  191             }
  192 
  193             if test.CreateDirectory {
  194                 err := os.Mkdir(config.DatabaseDirectory, 0755) //nolint:gosec
  195                 require.NoError(t, err)
  196             }
  197 
  198             currentDatabasePath := filepath.Join(
  199                 config.DatabaseDirectory,
  200                 "GeoIP2-City.mmdb",
  201             )
  202             if test.DatabaseBefore != "" {
  203                 err := ioutil.WriteFile(
  204                     currentDatabasePath,
  205                     []byte(test.DatabaseBefore),
  206                     0644,
  207                 )
  208                 require.NoError(t, err)
  209             }
  210 
  211             client := geoipupdate.NewClient(config)
  212             dbReader := NewHTTPDatabaseReader(client, config)
  213             dbWriter, err := NewLocalFileDatabaseWriter(currentDatabasePath, config.LockFile, config.Verbose)
  214             assert.NoError(t, err, test.Description)
  215 
  216             err = dbReader.Get(dbWriter, config.EditionIDs[0])
  217             if test.Err == "" {
  218                 assert.NoError(t, err, test.Description)
  219             } else {
  220                 // regex because some errors have filenames.
  221                 assert.Regexp(t, test.Err, err.Error(), test.Description)
  222             }
  223 
  224             server.Close()
  225 
  226             if test.DatabaseAfter != "" {
  227                 buf, err := ioutil.ReadFile(filepath.Clean(currentDatabasePath))
  228                 require.NoError(t, err, test.Description)
  229                 assert.Equal(t, test.DatabaseAfter, string(buf))
  230             }
  231 
  232             if !test.ExpectedTime.IsZero() {
  233                 fi, err := os.Stat(currentDatabasePath)
  234                 require.NoError(t, err)
  235                 assert.WithinDuration(t, test.ExpectedTime, fi.ModTime(), 0)
  236             }
  237 
  238             if test.CreateDirectory {
  239                 err := os.RemoveAll(config.DatabaseDirectory)
  240                 require.NoError(t, err)
  241             }
  242         })
  243     }
  244 }