mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-22 02:47:48 +08:00
* chore: apply go fix modernizers from Go 1.26
automated refactoring: interface{} to any, slices.Contains,
and other idiomatic updates.
* feat(ci): add `go fix` check to Go analysis workflow
ensures Go 1.26 modernizers are applied, fails CI if `go fix ./...`
produces any changes (similar to existing `go fmt` enforcement)
171 lines
3.5 KiB
Go
171 lines
3.5 KiB
Go
package telemetry
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/cockroachdb/pebble/v2"
|
|
logging "github.com/ipfs/go-log/v2"
|
|
"github.com/ipfs/kubo/config"
|
|
"github.com/ipfs/kubo/core"
|
|
"github.com/ipfs/kubo/core/node/libp2p"
|
|
"github.com/ipfs/kubo/plugin"
|
|
"github.com/ipfs/kubo/plugin/plugins/pebbleds"
|
|
"github.com/ipfs/kubo/repo/fsrepo"
|
|
)
|
|
|
|
func mockServer(t *testing.T) (*httptest.Server, func() LogEvent) {
|
|
t.Helper()
|
|
|
|
var e LogEvent
|
|
|
|
// Create a mock HTTP test server
|
|
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
// Check if the request is POST to the correct endpoint
|
|
if r.Method != "POST" || r.URL.Path != "/" {
|
|
t.Log("invalid request")
|
|
http.Error(w, "invalid request", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Check content type
|
|
if r.Header.Get("Content-Type") != "application/json" {
|
|
t.Log("invalid content type")
|
|
http.Error(w, "invalid content type", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Check if the body is not empty
|
|
if r.Body == nil {
|
|
t.Log("empty body")
|
|
http.Error(w, "empty body", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Read the body
|
|
body, _ := io.ReadAll(r.Body)
|
|
if len(body) == 0 {
|
|
t.Log("zero-length body")
|
|
http.Error(w, "empty body", http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
t.Logf("Received telemetry:\n %s", string(body))
|
|
|
|
err := json.Unmarshal(body, &e)
|
|
if err != nil {
|
|
t.Log("error unmarshaling event", err)
|
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
// Return success
|
|
w.WriteHeader(http.StatusOK)
|
|
})), func() LogEvent { return e }
|
|
}
|
|
|
|
func makeNode(t *testing.T) (node *core.IpfsNode, repopath string) {
|
|
t.Helper()
|
|
|
|
// Create a Temporary Repo
|
|
repoPath, err := os.MkdirTemp("", "ipfs-shell")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
pebbledspli := pebbleds.Plugins[0]
|
|
pebbledspl, ok := pebbledspli.(plugin.PluginDatastore)
|
|
if !ok {
|
|
t.Fatal("bad datastore plugin")
|
|
}
|
|
|
|
err = fsrepo.AddDatastoreConfigHandler(pebbledspl.DatastoreTypeName(), pebbledspl.DatastoreConfigParser())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Create a config with default options and a 2048 bit key
|
|
cfg, err := config.Init(io.Discard, 2048)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
cfg.Datastore.Spec = map[string]any{
|
|
"type": "pebbleds",
|
|
"prefix": "pebble.datastore",
|
|
"path": "pebbleds",
|
|
"formatMajorVersion": int(pebble.FormatNewest),
|
|
}
|
|
|
|
// Create the repo with the config
|
|
err = fsrepo.Init(repoPath, cfg)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Open the repo
|
|
repo, err := fsrepo.Open(repoPath)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Construct the node
|
|
|
|
nodeOptions := &core.BuildCfg{
|
|
Online: true,
|
|
Routing: libp2p.NilRouterOption,
|
|
Repo: repo,
|
|
}
|
|
|
|
node, err = core.NewNode(context.Background(), nodeOptions)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
node.IsDaemon = true
|
|
return
|
|
}
|
|
|
|
func TestSendTelemetry(t *testing.T) {
|
|
if err := logging.SetLogLevel("telemetry", "DEBUG"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ts, eventGetter := mockServer(t)
|
|
defer ts.Close()
|
|
|
|
node, repoPath := makeNode(t)
|
|
|
|
// Create a plugin instance
|
|
p := &telemetryPlugin{
|
|
runOnce: true,
|
|
}
|
|
|
|
// Initialize the plugin
|
|
pe := &plugin.Environment{
|
|
Repo: repoPath,
|
|
Config: nil,
|
|
}
|
|
err := p.Init(pe)
|
|
if err != nil {
|
|
t.Fatalf("Init() failed: %v", err)
|
|
}
|
|
|
|
p.endpoint = ts.URL
|
|
|
|
// Start the plugin
|
|
err = p.Start(node)
|
|
if err != nil {
|
|
t.Fatalf("Start() failed: %v", err)
|
|
}
|
|
|
|
e := eventGetter()
|
|
if e.UUID != p.event.UUID {
|
|
t.Fatal("uuid mismatch")
|
|
}
|
|
}
|