-
Notifications
You must be signed in to change notification settings - Fork 5k
Expand file tree
/
Copy pathjamf_test.go
More file actions
154 lines (134 loc) · 4.56 KB
/
Copy pathjamf_test.go
File metadata and controls
154 lines (134 loc) · 4.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
// or more contributor license agreements. Licensed under the Elastic License;
// you may not use this file except in compliance with the Elastic License.
package jamf
import (
"context"
"encoding/json"
"flag"
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"testing"
"time"
_ "embed"
"github.com/gofrs/uuid/v5"
"github.com/google/go-cmp/cmp"
"github.com/elastic/beats/v7/x-pack/filebeat/input/entityanalytics/provider/jamf/internal/jamf"
"github.com/elastic/elastic-agent-libs/logp"
"github.com/elastic/lumberjack"
)
var trace = flag.Bool("request_trace", false, "enable request tracing during tests")
//go:embed internal/jamf/testdata/computers.json
var computers []byte
func TestJamfDoFetch(t *testing.T) {
dbFilename := t.Name() + ".db"
store := testSetupStore(t, dbFilename)
t.Cleanup(func() {
testCleanupStore(store, dbFilename)
})
var rawComputers jamf.Computers
err := json.Unmarshal(computers, &rawComputers)
if err != nil {
t.Fatalf("failed to unmarshal device data: %v", err)
}
wantComputers := make([]*Computer, 0, len(rawComputers.Results))
for _, c := range rawComputers.Results {
wantComputers = append(wantComputers, &Computer{
Computer: c,
State: Discovered,
})
}
// Set the number of repeats.
tenant, username, password, client, cleanup, err := testContext()
if err != nil {
t.Fatalf("unexpected error getting env context: %v", err)
}
defer cleanup()
a := jamfInput{
cfg: conf{
JamfTenant: tenant,
JamfUsername: username,
JamfPassword: password,
},
client: client,
logger: logp.L(),
}
if *trace {
// Use legacy behaviour; nil enabled setting.
a.cfg.Tracer = &tracerConfig{Logger: lumberjack.Logger{
Filename: "test_trace.ndjson",
}}
}
a.client = requestTrace(context.Background(), a.client, a.cfg, a.logger)
ss, err := newStateStore(store)
if err != nil {
t.Fatalf("unexpected error making state store: %v", err)
}
defer ss.close(false)
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
defer cancel()
t.Run("devices", func(t *testing.T) {
got, err := a.doFetchComputers(ctx, ss, false)
if err != nil {
t.Fatalf("unexpected error from doFetch: %v", err)
}
if wantComputers != nil && !cmp.Equal(wantComputers, got) {
t.Errorf("unexpected result\n--- want\n+++ got\n%s", cmp.Diff(wantComputers, got))
}
})
}
func testContext() (tenant string, username string, password string, client *http.Client, cleanup func(), err error) {
username = "testuser"
password = "testuser_password"
var tok jamf.Token
mux := http.NewServeMux()
mux.Handle("/api/v1/auth/token", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
user, pass, ok := r.BasicAuth()
if !ok || user != username || pass != password {
w.WriteHeader(http.StatusUnauthorized)
w.Header().Set("content-type", "application/json;charset=UTF-8")
//nolint:errcheck // ignore
w.Write([]byte("{\n \"httpStatus\" : 401,\n \"errors\" : [ ]\n}"))
return
}
if r.Method != http.MethodPost {
w.WriteHeader(http.StatusMethodNotAllowed)
w.Header().Set("content-type", "application/json;charset=UTF-8")
//nolint:errcheck // ignore
w.Write([]byte("{\n \"httpStatus\" : 405,\n \"errors\" : [ ]\n}"))
return
}
tok.Token = uuid.Must(uuid.NewV4()).String()
tok.Expires = time.Now().In(time.UTC).Add(time.Hour)
fmt.Fprintf(w, "{\n \"token\" : \"%s\",\n \"expires\" : \"%s\"\n}", tok.Token, tok.Expires.Format(time.RFC3339))
}))
mux.Handle("/api/preview/computers", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("Authorization") != "Bearer "+tok.Token || !tok.IsValidFor(0) {
w.WriteHeader(http.StatusUnauthorized)
w.Header().Set("content-type", "application/json;charset=UTF-8")
//nolint:errcheck // ignore
w.Write([]byte("{\n \"httpStatus\" : 401,\n \"errors\" : [ {\n \"code\" : \"INVALID_TOKEN\",\n \"description\" : \"Unauthorized\",\n \"id\" : \"0\",\n \"field\" : null\n } ]\n}"))
return
}
if r.Method != http.MethodGet {
w.WriteHeader(http.StatusMethodNotAllowed)
w.Header().Set("content-type", "application/json;charset=UTF-8")
//nolint:errcheck // ignore
w.Write([]byte("{\n \"httpStatus\" : 405,\n \"errors\" : [ ]\n}"))
return
}
//nolint:errcheck // ignore
w.Write(computers)
}))
srv := httptest.NewTLSServer(mux)
u, err := url.Parse(srv.URL)
if err != nil {
srv.Close()
return "", "", "", nil, func() {}, err
}
tenant = u.Host
cli := srv.Client()
return tenant, username, password, cli, srv.Close, nil
}