Skip to content
Snippets Groups Projects
Commit 71a5a6c2 authored by Jono Wenger's avatar Jono Wenger
Browse files

XX-4707 / tag disk json

parent a30c17dc
Branches
Tags
2 merge requests!34XX-4707 / tag disk json,!24Release Updates for Channels
......@@ -14,25 +14,29 @@ before_script:
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan -t rsa $GITLAB_SERVER > ~/.ssh/known_hosts
- rm -rf ~/.gitconfig
- git config --global url."git@$GITLAB_SERVER:".insteadOf "https://gitlab.com/"
- git config --global url."git@$GITLAB_SERVER:".insteadOf "https://git.xx.network/" --add
- export PATH=$HOME/go/bin:$PATH
stages:
- test
- build
- trigger_integration
build:
stage: build
test:
stage: test
image: $DOCKER_IMAGE
script:
- git clean -ffdx
- go mod vendor -v
- go build ./...
- go mod tidy
- go build ./...
- mkdir -p testdata
# Test coverage
- go-acc --covermode atomic --output testdata/coverage.out ./... -- -v
# Exclude some specific packages and files
- cat testdata/coverage.out | grep -v pb[.]go > testdata/coverage-real.out
- go tool cover -func=testdata/coverage-real.out
- go tool cover -html=testdata/coverage-real.out -o testdata/coverage.html
......@@ -41,15 +45,25 @@ build:
- go tool cover -func=testdata/coverage-real.out | grep "total:" | awk '{print $3}' | sed 's/\%//g' > testdata/coverage-percentage.txt
- export CODE_CHECK=$(echo "$(cat testdata/coverage-percentage.txt) >= $MIN_CODE_COVERAGE" | bc -l)
- (if [ "$CODE_CHECK" == "1" ]; then echo "Minimum coverage of $MIN_CODE_COVERAGE succeeded"; else echo "Minimum coverage of $MIN_CODE_COVERAGE failed"; exit 1; fi);
artifacts:
paths:
- vendor/
- testdata/
build:
stage: build
image: $DOCKER_IMAGE
script:
- go mod vendor -v
- go build ./...
- mkdir -p release
- GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-w -s' ./...
- cd release
artifacts:
paths:
- vendor/
- testdata/
- release/
trigger-integration:
stage: trigger_integration
trigger:
......
.PHONY: update master release update_master update_release build clean
setup:
git config --global --add url."git@gitlab.com:".insteadOf "https://gitlab.com/"
clean:
rm -rf vendor/
go mod vendor
go mod tidy
go mod vendor -e
update:
-GOFLAGS="" go get all
build:
go build ./...
go mod tidy
update_release:
GOFLAGS="" go get -u gitlab.com/xx_network/primitives@release
GOFLAGS="" go get gitlab.com/xx_network/primitives@release
update_master:
GOFLAGS="" go get -u gitlab.com/xx_network/primitives@master
GOFLAGS="" go get gitlab.com/xx_network/primitives@master
master: update_master clean build
......
......@@ -9,7 +9,6 @@ package authorizer
import (
"encoding/hex"
"fmt"
)
const (
......@@ -32,5 +31,5 @@ func GetGatewayDns(gwID []byte) string {
if len(encoded) > maxGwIdLength {
encoded = encoded[:maxGwIdLength]
}
return fmt.Sprintf("%s.%s", encoded, DomainName)
return encoded + "." + DomainName
}
......@@ -8,7 +8,7 @@
package current
import (
"fmt"
"strconv"
"github.com/pkg/errors"
......@@ -55,7 +55,7 @@ func (a Activity) String() string {
case CRASH:
return "CRASH"
default:
return fmt.Sprintf("UNKNOWN STATE: %d", a)
return "UNKNOWN ACTIVITY: " + strconv.FormatUint(uint64(a), 10)
}
}
......@@ -78,6 +78,6 @@ func (a Activity) ConvertToRoundState() (states.Round, error) {
default:
// Unsupported conversion. Return an arbitrary round and error
return states.Round(99), errors.Errorf(
"unable to convert activity %+v to valid state", a)
"unable to convert activity %s (%d) to a valid state", a, a)
}
}
......@@ -18,7 +18,7 @@ import (
// Consistency test of Activity.String.
func TestActivity_String(t *testing.T) {
expected := []string{"NOT_STARTED", "WAITING", "PRECOMPUTING", "STANDBY",
"REALTIME", "COMPLETED", "ERROR", "CRASH", "UNKNOWN STATE: 8"}
"REALTIME", "COMPLETED", "ERROR", "CRASH", "UNKNOWN ACTIVITY: 8"}
for st := NOT_STARTED; st <= NUM_STATES; st++ {
if st.String() != expected[st] {
......
......@@ -111,7 +111,7 @@ func ValidateFact(fact Fact) error {
case Nickname:
return validateNickname(fact.Fact)
default:
return errors.Errorf("Unknown fact type: %v", fact.T)
return errors.Errorf("Unknown fact type: %d", fact.T)
}
}
......@@ -130,8 +130,7 @@ func extractNumberInfo(fact string) (number, countryCode string) {
func validateEmail(email string) error {
// Check that the input is validly formatted
if err := checkmail.ValidateFormat(email); err != nil {
return errors.Errorf(
"Could not validate format for email [%s]: %v", email, err)
return errors.Wrapf(err, "Could not validate format for email %q", email)
}
return nil
......@@ -140,30 +139,32 @@ func validateEmail(email string) error {
// Checks if the number and country code passed in is parse-able
// and is a valid phone number with that information
func validateNumber(number, countryCode string) error {
errCh := make(chan error)
go func() {
catchPanic := func(number, countryCode string) (err error) {
defer func() {
if r := recover(); r != nil {
errCh <- errors.Errorf("Crash occured on phone "+
"validation of: number: %s, country code: %s", number,
countryCode)
err = errors.Errorf("Crash occured on phone validation of: "+
"number: %s, country code: %s: %+v", number, countryCode, r)
}
}()
if len(number) == 0 || len(countryCode) == 0 {
errCh <- errors.New("Number or input are of length 0")
err = errors.New("Number or input are of length 0")
return err
}
num, err := libphonenumber.Parse(number, countryCode)
if err != nil || num == nil {
errCh <- errors.Errorf("Could not parse number [%s]: %v", number, err)
err = errors.Wrapf(err, "Could not parse number %q", number)
return err
}
if !libphonenumber.IsValidNumber(num) {
errCh <- errors.Errorf("Could not validate number [%s]: %v", number, err)
err = errors.Errorf("Could not validate number %q", number)
return err
}
errCh <- nil
}()
return <-errCh
return nil
}
return catchPanic(number, countryCode)
}
func validateNickname(nickname string) error {
......
......@@ -37,14 +37,17 @@ func UnstringifyFactList(s string) (FactList, string, error) {
parts := strings.SplitN(s, factBreak, 2)
if len(parts) != 2 {
return nil, "", errors.New("Invalid fact string passed")
} else if parts[0] == "" {
return nil, parts[1], nil
}
factStrings := strings.Split(parts[0], factDelimiter)
var factList []Fact
factList := make([]Fact, 0, len(factStrings))
for _, fString := range factStrings {
fact, err := UnstringifyFact(fString)
if err != nil {
jww.WARN.Printf("Fact failed to unstringify, dropped: %s", err)
jww.WARN.Printf(
"Fact %q failed to unstringify, dropped: %s", fString, err)
} else {
factList = append(factList, fact)
}
......
......@@ -35,6 +35,23 @@ func TestFactList_Stringify_UnstringifyFactList(t *testing.T) {
}
}
// Tests that a nil FactList marshalled by FactList.Stringify and unmarshalled
// by UnstringifyFactList matches the original.
func TestUnstringifyFactList_NilFactList(t *testing.T) {
var expected FactList
flString := expected.Stringify()
factList, _, err := UnstringifyFactList(flString)
if err != nil {
t.Fatalf("Failed to unstringify %q: %+v", flString, err)
}
if !reflect.DeepEqual(factList, expected) {
t.Errorf("Unexpected unstringified FactList."+
"\nexpected: %v\nreceived: %v", expected, factList)
}
}
// Error path: Tests that UnstringifyFactList returns an error for a malformed
// stringified FactList.
func Test_UnstringifyFactList_MissingFactBreakError(t *testing.T) {
......
......@@ -221,8 +221,8 @@ func Test_validateNumber_Error(t *testing.T) {
{"5", "", "Number or input are of length 0"},
{"", "US", "Number or input are of length 0"},
// {"020 8743 8000135", "UK", `Could not parse number "020 8743 8000135"`},
{"8005559486", "UK", `Could not parse number [8005559486]`},
{"+343511234567", "ES", `Could not validate number [+343511234567]`},
{"8005559486", "UK", `Could not parse number "8005559486"`},
{"+343511234567", "ES", `Could not validate number "+343511234567"`},
}
for i, tt := range tests {
......
......@@ -8,7 +8,7 @@
package fact
import (
"fmt"
"strconv"
"github.com/pkg/errors"
jww "github.com/spf13/jwalterweatherman"
......@@ -36,7 +36,7 @@ func (t FactType) String() string {
case Nickname:
return "Nickname"
default:
return fmt.Sprintf("Unknown Fact FactType: %d", t)
return "Unknown Fact FactType: " + strconv.FormatUint(uint64(t), 10)
}
}
......@@ -68,10 +68,15 @@ func UnstringifyFactType(s string) (FactType, error) {
case "N":
return Nickname, nil
}
return 3, errors.Errorf("Unknown Fact FactType: %s", s)
return 99, errors.Errorf("Unknown Fact FactType: %s", s)
}
// IsValid determines if the FactType is one of the defined types.
func (t FactType) IsValid() bool {
return t == Username || t == Email || t == Phone || t == Nickname
switch t {
case Username, Email, Phone, Nickname:
return true
default:
return false
}
}
......@@ -9,6 +9,9 @@ package format
import (
"encoding/base64"
"encoding/json"
"github.com/pkg/errors"
)
type Fingerprint [KeyFPLen]byte
......@@ -30,3 +33,25 @@ func (fp Fingerprint) Bytes() []byte {
func (fp Fingerprint) String() string {
return base64.StdEncoding.EncodeToString(fp.Bytes())
}
// MarshalJSON adheres to the json.Marshaler interface.
func (fp Fingerprint) MarshalJSON() ([]byte, error) {
return json.Marshal(fp[:])
}
// UnmarshalJSON adheres to the json.Unmarshaler interface.
func (fp *Fingerprint) UnmarshalJSON(data []byte) error {
var fpBytes []byte
err := json.Unmarshal(data, &fpBytes)
if err != nil {
return err
}
if len(fpBytes) != KeyFPLen {
return errors.Errorf("length of fingerprint must be %d", KeyFPLen)
}
copy(fp[:], fpBytes[:])
return nil
}
......@@ -10,6 +10,7 @@ package format
import (
"bytes"
"encoding/base64"
"encoding/json"
"math/rand"
"testing"
)
......@@ -66,3 +67,26 @@ func TestFingerprint_String(t *testing.T) {
"\nexpected: %s\nreceived: %s", expectedString, fp.String())
}
}
func Test_Fingerprint_JSON_Marshal_Unmarshal(t *testing.T) {
prng := rand.New(rand.NewSource(74043))
fpBytes := make([]byte, KeyFPLen)
prng.Read(fpBytes)
expected := NewFingerprint(fpBytes)
data, err := json.Marshal(expected)
if err != nil {
t.Errorf("Failed to marshal %T: %+v", expected, err)
}
var fp Fingerprint
if err = json.Unmarshal(data, &fp); err != nil {
t.Errorf("Failed to unmarshal %T: %+v", fp, err)
}
if expected != fp {
t.Errorf("Unexpected fingerprint.\nexpected: %s\nreceived: %s",
expected, fp)
}
}
......@@ -8,15 +8,13 @@ require (
github.com/pkg/errors v0.9.1
github.com/spf13/jwalterweatherman v1.1.0
github.com/ttacon/libphonenumber v1.2.1
gitlab.com/xx_network/primitives v0.0.4-0.20230203173415-81c2cb07da44
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad
gitlab.com/xx_network/primitives v0.0.4-0.20230724185812-bc6fc6e5341b
golang.org/x/crypto v0.5.0
)
require (
github.com/golang/protobuf v1.5.2 // indirect
github.com/stretchr/testify v1.6.1 // indirect
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 // indirect
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 // indirect
golang.org/x/sys v0.10.0 // indirect
google.golang.org/protobuf v1.26.0 // indirect
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect
)
github.com/badoux/checkmail v1.2.1 h1:TzwYx5pnsV6anJweMx2auXdekBwGr/yt1GgalIx9nBQ=
github.com/badoux/checkmail v1.2.1/go.mod h1:XroCOBU5zzZJcLvgwU15I+2xXyCdTWXyR9MGfRhBYy0=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3 h1:zN2lZNZRflqFyxVaTIU61KNKQ9C0055u9CAfpmqUvo4=
......@@ -16,32 +15,21 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 h1:5u+EJUQiosu3JFX0XS0qTf5FznsMOzTjGqavBGuCbo0=
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2/go.mod h1:4kyMkleCiLkgY6z8gK5BkI01ChBtxR0ro3I1ZDcGM3w=
github.com/ttacon/libphonenumber v1.2.1 h1:fzOfY5zUADkCkbIafAed11gL1sW+bJ26p6zWLBMElR4=
github.com/ttacon/libphonenumber v1.2.1/go.mod h1:E0TpmdVMq5dyVlQ7oenAkhsLu86OkUl+yR4OAxyEg/M=
gitlab.com/xx_network/primitives v0.0.4-0.20230203173415-81c2cb07da44 h1:vNm76SCeKZiCaVL0rCIcqDxMzSVL50g3XO6dQYN8r3Q=
gitlab.com/xx_network/primitives v0.0.4-0.20230203173415-81c2cb07da44/go.mod h1:wUxbEBGOBJZ/RkAiVAltlC1uIlIrU0dE113Nq7HiOhw=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad h1:DN0cp81fZ3njFcrLCytUHRSUkqBjfTo4Tx9RJTWs0EY=
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4=
golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gitlab.com/xx_network/primitives v0.0.4-0.20230724185812-bc6fc6e5341b h1:oymmRpA+5/SeBp+MgFeYyuB8S9agfetGDnxBXXq9utE=
gitlab.com/xx_network/primitives v0.0.4-0.20230724185812-bc6fc6e5341b/go.mod h1:vI6JXexgqihcIVFGsZAwGlHWGT14XC24NwEB2c6q9nc=
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
......@@ -291,7 +291,7 @@ func (kr *KnownRounds) Forward(rid id.Round) {
// unknown and ending with
func (kr *KnownRounds) RangeUnchecked(oldestUnknown id.Round, threshold uint,
roundCheck func(id id.Round) bool, maxPickups int) (
id.Round, []id.Round, []id.Round) {
earliestRound id.Round, has, unknown []id.Round) {
newestRound := kr.lastChecked
......@@ -303,10 +303,8 @@ func (kr *KnownRounds) RangeUnchecked(oldestUnknown id.Round, threshold uint,
oldestPossibleEarliestRound = newestRound - id.Round(threshold)
}
earliestRound := kr.lastChecked + 1
var unknown []id.Round
has := make([]id.Round, 0, maxPickups)
earliestRound = kr.lastChecked + 1
has = make([]id.Round, 0, maxPickups)
// If the oldest unknown round is outside the range we are attempting to
// check, then skip checking
......@@ -368,16 +366,9 @@ func (kr *KnownRounds) RangeUncheckedMaskedRange(mask *KnownRounds,
numChecked := 0
if mask.firstUnchecked != mask.lastChecked {
jww.TRACE.Printf("mask (before Forward()) {\n\tbitStream: %064b\n\tfirstUnchecked: %d\n\tlastChecked: %d\n\tfuPos: %d\n}", mask.bitStream, mask.firstUnchecked, mask.lastChecked, mask.fuPos)
mask.Forward(kr.firstUnchecked)
subSample, delta := kr.subSample(mask.firstUnchecked, mask.lastChecked)
// FIXME: it is inefficient to make a copy of the mask here.
jww.TRACE.Printf("mask (after Forward()) {\n\tbitStream: %064b\n\tfirstUnchecked: %d\n\tlastChecked: %d\n\tfuPos: %d\n}", mask.bitStream, mask.firstUnchecked, mask.lastChecked, mask.fuPos)
jww.TRACE.Printf("kr {\n\tbitStream: %064b\n\tfirstUnchecked: %d\n\tlastChecked: %d\n\tfuPos: %d\n}", kr.bitStream, kr.firstUnchecked, kr.lastChecked, kr.fuPos)
jww.TRACE.Printf("delta: %d", delta)
jww.TRACE.Printf("subSample: %064b", subSample)
// jww.TRACE.Printf("maskSubSample: %064b", maskSubSample)
result := subSample.implies(mask.bitStream)
for i := mask.firstUnchecked + id.Round(delta) - 1; i >= mask.firstUnchecked && numChecked < maxChecked; i, numChecked = i-1, numChecked+1 {
......
......@@ -27,7 +27,7 @@ var ErrNicknameTooLong = errors.Errorf("nicknames must be %d "+
func IsValid(nick string) error {
if nick == "" {
jww.INFO.Printf(
"empty nickname passed, treating like no nickname")
"Empty nickname passed; treating it as if no nickname was set.")
return nil
}
......
......@@ -11,6 +11,7 @@ import (
"bytes"
"encoding/base64"
"encoding/csv"
"strconv"
"strings"
"github.com/pkg/errors"
......@@ -24,6 +25,16 @@ type Data struct {
MessageHash []byte
}
func (d *Data) String() string {
fields := []string{
strconv.FormatInt(d.EphemeralID, 10),
strconv.FormatUint(d.RoundID, 10),
base64.StdEncoding.EncodeToString(d.IdentityFP),
base64.StdEncoding.EncodeToString(d.MessageHash),
}
return "{" + strings.Join(fields, " ") + "}"
}
// BuildNotificationCSV converts the [Data] list into a CSV of the specified max
// size and return it along with the included [Data] entries. Any [Data] entries
// over that size are excluded.
......@@ -35,7 +46,7 @@ func BuildNotificationCSV(ndList []*Data, maxSize int) ([]byte, []*Data) {
var buf bytes.Buffer
var numWritten int
for _, nd := range ndList {
for i, nd := range ndList {
var line bytes.Buffer
w := csv.NewWriter(&line)
output := []string{
......@@ -43,7 +54,8 @@ func BuildNotificationCSV(ndList []*Data, maxSize int) ([]byte, []*Data) {
base64.StdEncoding.EncodeToString(nd.IdentityFP)}
if err := w.Write(output); err != nil {
jww.FATAL.Printf("Failed to write notificationsCSV line: %+v", err)
jww.FATAL.Printf("Failed to write record %d of %d to "+
"notifications CSV line buffer: %+v", i, len(ndList), err)
}
w.Flush()
......@@ -52,7 +64,8 @@ func BuildNotificationCSV(ndList []*Data, maxSize int) ([]byte, []*Data) {
}
if _, err := buf.Write(line.Bytes()); err != nil {
jww.FATAL.Printf("Failed to write to notificationsCSV: %+v", err)
jww.FATAL.Printf("Failed to write record %d of %d to "+
"notifications CSV: %+v", i, len(ndList), err)
}
numWritten++
......@@ -66,21 +79,25 @@ func DecodeNotificationsCSV(data string) ([]*Data, error) {
r := csv.NewReader(strings.NewReader(data))
records, err := r.ReadAll()
if err != nil {
return nil, errors.WithMessage(err, "Failed to decode notifications CSV")
return nil, errors.Wrapf(err, "Failed to read notifications CSV records.")
}
list := make([]*Data, len(records))
for i, tuple := range records {
messageHash, err := base64.StdEncoding.DecodeString(tuple[0])
if err != nil {
return nil, errors.WithMessage(err, "Failed decode an element")
return nil, errors.Wrapf(err,
"Failed to decode MessageHash for record %d of %d",
i, len(records))
}
identityFP, err := base64.StdEncoding.DecodeString(tuple[1])
if err != nil {
return nil, errors.WithMessage(err, "Failed decode an element")
return nil, errors.Wrapf(err,
"Failed to decode IdentityFP for record %d of %d",
i, len(records))
}
list[i] = &Data{
EphemeralID: 0,
IdentityFP: identityFP,
MessageHash: messageHash,
}
......
......@@ -141,7 +141,7 @@ GsvgcJsHWAg/YdN1vAK0HfT5GSnhj9qeb4LlTnSOgec=,nku9b+NM3LqEPujWPoxP/hzr6lRtj6wT3Q=
func TestDecodeNotificationsCSV_InvalidMessageHashError(t *testing.T) {
invalidCSV := `U4x/lrFkvxuXu59LtHLonnZND6SugndnVI=,39ebTXZCm2F6DJ+fDTulWwzA1hRMiIU1hA==
`
expectedErr := "Failed decode an element"
expectedErr := "Failed to decode MessageHash for record 0 of 1"
_, err := DecodeNotificationsCSV(invalidCSV)
if err == nil || !strings.Contains(err.Error(), expectedErr) {
t.Errorf("Unexpected error for invalid MessageHash."+
......@@ -154,7 +154,7 @@ func TestDecodeNotificationsCSV_InvalidMessageHashError(t *testing.T) {
func TestDecodeNotificationsCSV_InvalididentityFPError(t *testing.T) {
invalidCSV := `U4x/lrFkvxuXu59LtHLon1sUhPJSCcnZND6SugndnVI=,39ebTXZCm2F6DJ1hRMiIU1hA==
`
expectedErr := "Failed decode an element"
expectedErr := "Failed to decode IdentityFP for record 0 of 1"
_, err := DecodeNotificationsCSV(invalidCSV)
if err == nil || !strings.Contains(err.Error(), expectedErr) {
t.Errorf("Unexpected error for invalid identityFP."+
......@@ -166,7 +166,7 @@ func TestDecodeNotificationsCSV_InvalididentityFPError(t *testing.T) {
// an invalid identityFP.
func TestDecodeNotificationsCSV_NoEofError(t *testing.T) {
invalidCSV := `U4x/lrFkvxuXu59LtHLon1sUhPJSCcnZND6SugndnVI=,39ebTXZCm2F6DJ+fDTulWwzA1hRMiIU1hA==,"`
expectedErr := "Failed to decode notifications CSV"
expectedErr := "Failed to read notifications CSV records."
_, err := DecodeNotificationsCSV(invalidCSV)
if err == nil || !strings.Contains(err.Error(), expectedErr) {
t.Errorf("Unexpected error for invalid identityFP."+
......
......@@ -7,9 +7,7 @@
package states
import (
"fmt"
)
import "strconv"
// This holds the enum for the states of a round. It is in primitives so
// other repos such as registration/permissioning, gateway, and client can
......@@ -49,6 +47,6 @@ func (r Round) String() string {
case FAILED:
return "FAILED"
default:
return fmt.Sprintf("UNKNOWN STATE: %d", r)
return "UNKNOWN STATE: " + strconv.FormatUint(uint64(r), 10)
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment