Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f6850b8c09 |
No files matched your search
@@ -489,8 +489,8 @@ provide:
|
||||
- `script/asupdate` — rebuild the AS list built into RouteWatch,
|
||||
`pkg/asinfo/asdata.json.gz`, from the `as.csv` file of
|
||||
[ipverse/as-metadata](https://github.com/ipverse/as-metadata). It needs the
|
||||
network. When the generator fails or finds no ASes, the old list stays and the
|
||||
script exits non-zero.
|
||||
network. It runs `cmd/asinfo-gen`, which fails when it finds no AS. When
|
||||
`cmd/asinfo-gen` fails, the old list stays and the script exits non-zero.
|
||||
|
||||
Tests and the linter run only in Docker, as the `test` and `lint` phases of the
|
||||
`Dockerfile`; the image cannot be built unless both pass. Every `docker build`
|
||||
|
||||
@@ -26,7 +26,10 @@ const (
|
||||
columnsRead = 3
|
||||
)
|
||||
|
||||
var errUnexpectedHeader = errors.New("unexpected CSV header")
|
||||
var (
|
||||
errUnexpectedHeader = errors.New("unexpected CSV header")
|
||||
errNoASes = errors.New("no AS in the CSV")
|
||||
)
|
||||
|
||||
// ASInfo represents information about an Autonomous System
|
||||
type ASInfo struct {
|
||||
@@ -82,7 +85,7 @@ func main() {
|
||||
// parseCSV reads as.csv from r and returns its ASes, with the handle and the
|
||||
// description as the file spells them. A header whose first columns are not
|
||||
// the AS number, the handle and the description is an error. A record that
|
||||
// does not parse is logged and skipped.
|
||||
// does not parse is logged and skipped. A file left with no AS is an error.
|
||||
func parseCSV(r io.Reader) ([]ASInfo, error) {
|
||||
reader := csv.NewReader(r)
|
||||
|
||||
@@ -126,5 +129,9 @@ func parseCSV(r io.Reader) ([]ASInfo, error) {
|
||||
})
|
||||
}
|
||||
|
||||
if len(asInfos) == 0 {
|
||||
return nil, errNoASes
|
||||
}
|
||||
|
||||
return asInfos, nil
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -53,3 +54,20 @@ func TestParseCSVRejectsAnotherHeader(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestParseCSVRejectsAFileWithNoASes parses files that hold no AS, one with
|
||||
// only the header and one whose only record has no valid AS number. It
|
||||
// expects errNoASes, so that make asupdate keeps the old list.
|
||||
func TestParseCSVRejectsAFileWithNoASes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, asCSV := range []string{
|
||||
"asn,handle,description,country-code\n",
|
||||
"asn,handle,description,country-code\nAS1,LVLT-1,Level 3,US\n",
|
||||
} {
|
||||
_, err := parseCSV(strings.NewReader(asCSV))
|
||||
if !errors.Is(err, errNoASes) {
|
||||
t.Errorf("parseCSV(%q) = %v, want %v", asCSV, err, errNoASes)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-11
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
# script/asupdate: rebuild the AS list built into RouteWatch from
|
||||
# as.csv with cmd/asinfo-gen. The new list replaces the old one only
|
||||
# when the generator succeeds and writes at least one AS. Otherwise
|
||||
# as.csv with cmd/asinfo-gen, which fails when it finds no AS. The new
|
||||
# list replaces the old one only when the generator succeeds. Otherwise
|
||||
# the old list stays as it was and the script exits non-zero.
|
||||
set -eu
|
||||
|
||||
@@ -25,15 +25,6 @@ main() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The generator writes a list of ASes with "[" alone on the first
|
||||
# line. An empty list is "[]", and no list at all is "null".
|
||||
first_line=""
|
||||
read -r first_line <"$json" || true
|
||||
if [ "$first_line" != "[" ]; then
|
||||
echo "asupdate: the generator wrote no ASes; $AS_DATA is unchanged" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# -n leaves the time out of the file, so an unchanged list gives the
|
||||
# same bytes.
|
||||
gzip -n -c <"$json" >"$AS_DATA_TMP"
|
||||
|
||||
Reference in new issue
Block a user