package model import ( "bytes" "encoding/json" "errors" "fmt" "testing" ) func TestMeasurementTargetMarshalJSON(t *testing.T) { var mt MeasurementTarget data, err := json.Marshal(mt) if err != nil { t.Fatal(err) } if string(data) != "null" { t.Fatal("unexpected serialization") } mt = "xx" data, err = json.Marshal(mt) if err != nil { t.Fatal(err) } if string(data) != `"xx"` { t.Fatal("unexpected serialization") } } type fakeTestKeys struct { ClientResolver string `json:"client_resolver"` Body string `json:"body"` } func TestAddAnnotations(t *testing.T) { m := &Measurement{} m.AddAnnotations(map[string]string{ "foo": "bar", "f": "b", }) m.AddAnnotations(map[string]string{ "foobar": "bar", "f": "b", }) if len(m.Annotations) != 3 { t.Fatal("unexpected number of annotations") } if m.Annotations["foo"] != "bar" { t.Fatal("unexpected annotation") } if m.Annotations["f"] != "b" { t.Fatal("unexpected annotation") } if m.Annotations["foobar"] != "bar" { t.Fatal("unexpected annotation") } } type makeMeasurementConfig struct { Input string ProbeIP string ProbeASN string ProbeNetworkName string ProbeCC string ResolverIP string ResolverNetworkName string ResolverASN string } func makeMeasurement(config makeMeasurementConfig) *Measurement { return &Measurement{ DataFormatVersion: "0.3.0", ID: "bdd20d7a-bba5-40dd-a111-9863d7908572", Input: MeasurementTarget(config.Input), MeasurementStartTime: "2018-11-01 15:33:20", ProbeIP: config.ProbeIP, ProbeASN: config.ProbeASN, ProbeNetworkName: config.ProbeNetworkName, ProbeCC: config.ProbeCC, ReportID: "", ResolverIP: config.ResolverIP, ResolverNetworkName: config.ResolverNetworkName, ResolverASN: config.ResolverASN, SoftwareName: "probe-engine", SoftwareVersion: "0.1.0", TestKeys: &fakeTestKeys{ ClientResolver: config.ResolverIP, Body: fmt.Sprintf(` Your IP is %s

Hey you, I see your IP and it's %s!

`, config.ProbeIP, config.ProbeIP), }, TestName: "dummy", MeasurementRuntime: 5.0565230846405, TestStartTime: "2018-11-01 15:33:17", TestVersion: "0.1.0", } } func TestScrubMeasurementWeAreScrubbing(t *testing.T) { config := makeMeasurementConfig{ Input: "130.192.91.211", ProbeIP: "130.192.91.211", ProbeASN: "AS137", ProbeCC: "IT", ProbeNetworkName: "Vodafone Italia S.p.A.", ResolverIP: "8.8.8.8", ResolverNetworkName: "Google LLC", ResolverASN: "AS12345", } m := makeMeasurement(config) if err := ScrubMeasurement(m, config.ProbeIP); err != nil { t.Fatal(err) } if m.Input != Scrubbed { t.Fatal("Input HAS NOT been scrubbed") } if m.ProbeASN != config.ProbeASN { t.Fatal("ProbeASN has been scrubbed") } if m.ProbeCC != config.ProbeCC { t.Fatal("ProbeCC has been scrubbed") } if m.ProbeIP != DefaultProbeIP { t.Fatal("ProbeIP HAS NOT been scrubbed") } if m.ProbeNetworkName != config.ProbeNetworkName { t.Fatal("ProbeNetworkName has been scrubbed") } if m.ResolverIP != config.ResolverIP { t.Fatal("ResolverIP has been scrubbed") } if m.ResolverNetworkName != config.ResolverNetworkName { t.Fatal("ResolverNetworkName has been scrubbed") } if m.ResolverASN != config.ResolverASN { t.Fatal("ResolverASN has been scrubbed") } data, err := json.Marshal(m) if err != nil { t.Fatal(err) } if bytes.Count(data, []byte(config.ProbeIP)) != 0 { t.Fatal("ProbeIP not fully redacted") } // Note: ooniprobe requires the test keys to keep their original // type otherwise the summary extraction process fails testkeys, good := m.TestKeys.(*fakeTestKeys) if !good { t.Fatal("the underlying type of the test keys changed") } if testkeys.ClientResolver != config.ResolverIP { t.Fatal("it seems the test keys did not round trip") } } func TestScrubMeasurementCannotUnmarshalTopLevelKeys(t *testing.T) { saved := scrubJSONUnmarshalTopLevelKeys expected := errors.New("mocked err") scrubJSONUnmarshalTopLevelKeys = func(data []byte, v any) error { return expected } defer func() { scrubJSONUnmarshalTopLevelKeys = saved }() m := &Measurement{} err := ScrubMeasurement(m, "10.0.0.1") if !errors.Is(err, expected) { t.Fatal("unexpected error", err) } } func TestScrubMeasurementCannotUnmarshalTestKeys(t *testing.T) { saved := scrubJSONUnmarshalTestKeys expected := errors.New("mocked err") scrubJSONUnmarshalTestKeys = func(data []byte, v any) error { return expected } defer func() { scrubJSONUnmarshalTestKeys = saved }() m := &Measurement{} err := ScrubMeasurement(m, "10.0.0.1") if !errors.Is(err, expected) { t.Fatal("unexpected error", err) } } func TestScrubMeasurementInvalidIP(t *testing.T) { m := &Measurement{ ProbeASN: "AS1234", ProbeCC: "IT", } err := ScrubMeasurement(m, "") // invalid IP if !errors.Is(err, ErrInvalidProbeIP) { t.Fatal("not the error we expected") } }