Repository: replicatedhq/troubleshoot
Pull request #128 (2020-01-30 22:48:17)

Add scope test instrumentation


Patch:
diff --git a/.gitignore b/.gitignore
index 63055be1..6fcce5ba 100644
--- a/.gitignore
+++ b/.gitignore
@@ -26,4 +26,7 @@ vendor
 *.swo
 *~
 
+# scope test logs
+scope-go-*.log
+
 dist
diff --git a/examples/preflight/node-resources.yaml b/examples/preflight/node-resources.yaml
deleted file mode 100644
index 50d7e2cd..00000000
--- a/examples/preflight/node-resources.yaml
+++ /dev/null
@@ -1,38 +0,0 @@
-apiVersion: troubleshoot.replicated.com/v1beta1
-kind: Preflight
-metadata:
-  name: sample
-spec:
-  analyzers:
-    - nodeResources:
-        checkName: Must have at least 3 nodes in the cluster
-        outcomes:
-          - fail:
-              when: "< 3"
-              message: This application requires at least 3 nodes
-          - warn:
-              when: "< 5"
-              message: This application recommends at last 5 nodes.
-          - pass:
-              message: This cluster has enough nodes.
-    - nodeResources:
-        checkName: Must have 3 nodes with at least 6 cores
-        filters:
-          cpuCapacity: "6"
-        outcomes:
-          - fail:
-              when: "< 3"
-              message: This application requires at least 3 nodes with 6 cores each
-          - pass:
-              message: This cluster has enough nodes with enough codes
-    - nodeResources:
-        checkName: Must have 1 node with 16 GB (available) memory and 5 cores (on a single node)
-        filters:
-          allocatableMemory: 16Gi
-          cpuCapacity: "5"
-        outcomes:
-          - fail:
-              when: "< 1"
-              message: This application requires at least 1 node with 16GB available memory
-          - pass:
-              message: This cluster has a node with enough memory.
diff --git a/ffi/main.go b/ffi/main.go
index 21241b41..22fe48f8 100644
--- a/ffi/main.go
+++ b/ffi/main.go
@@ -3,17 +3,18 @@ package main
 import "C"
 
 import (
-	"encoding/json"
 	"fmt"
-
+	"encoding/json"
+	
+	"gopkg.in/yaml.v2"
 	analyzer "github.com/replicatedhq/troubleshoot/pkg/analyze"
-	"github.com/replicatedhq/troubleshoot/pkg/convert"
 	"github.com/replicatedhq/troubleshoot/pkg/logger"
-	"gopkg.in/yaml.v2"
+	"github.com/replicatedhq/troubleshoot/pkg/convert"
+
 )
 
 //export Analyze
-func Analyze(bundleURL string, analyzers string, outputFormat string, compatibility string) *C.char {
+func Analyze(bundleURL string, analyzers string, outputFormat string, compatibility string) *C.char { 
 	logger.SetQuiet(true)
 
 	result, err := analyzer.DownloadAndAnalyze(bundleURL, analyzers)
diff --git a/go.mod b/go.mod
index 89910b37..98cc05ba 100644
--- a/go.mod
+++ b/go.mod
@@ -29,7 +29,9 @@ require (
 	github.com/tj/go-spin v1.1.0
 	github.com/ugorji/go v1.1.7 // indirect
 	github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
+	go.undefinedlabs.com/scopeagent v0.1.6
 	gopkg.in/yaml.v2 v2.2.4
+	honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc // indirect
 	k8s.io/api v0.17.0
 	k8s.io/apiextensions-apiserver v0.0.0-20190918161926-8f644eb6e783
 	k8s.io/apimachinery v0.17.0
diff --git a/go.sum b/go.sum
index c81535d0..28330aae 100644
--- a/go.sum
+++ b/go.sum
@@ -40,6 +40,8 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l
 github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
 github.com/aws/aws-sdk-go v1.22.0 h1:e88V6+dSEyBibUy0ekOydtTfNWzqG3hrtCR8SF6UqqY=
 github.com/aws/aws-sdk-go v1.22.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
+github.com/beevik/ntp v0.2.0 h1:sGsd+kAXzT0bfVfzJfce04g+dSRfrs+tbQW8lweuYgw=
+github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
@@ -49,6 +51,7 @@ github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnweb
 github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
 github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
+github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/cheggaaa/pb v1.0.27/go.mod h1:pQciLPpbU0oxA0h+VJYYLxO+XeDQb5pZijXscXHm81s=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
@@ -91,6 +94,8 @@ github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb
 github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
 github.com/emicklei/go-restful v2.9.6+incompatible h1:tfrHha8zJ01ywiOEC1miGY8st1/igzWB8OmvPgoYX7w=
 github.com/emicklei/go-restful v2.9.6+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs=
+github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
+github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
 github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
 github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
@@ -113,6 +118,8 @@ github.com/gizak/termui/v3 v3.1.0/go.mod h1:bXQEBkJpzxUAKf0+xq9MSWAvWZlE7c+aidmy
 github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
 github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
 github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
+github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w=
+github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
@@ -169,6 +176,8 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
 github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
 github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
 github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
+github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
+github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -339,6 +348,9 @@ github.com/onsi/gomega v1.3.0/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5
 github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
 github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
+github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74=
+github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
+github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
 github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
 github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
 github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
@@ -362,6 +374,8 @@ github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDf
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
 github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
+github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
 github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
 github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
 github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro=
@@ -445,6 +459,10 @@ github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLY
 github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
 github.com/ulikunitz/xz v0.5.6 h1:jGHAfXawEGZQ3blwU5wnWKQJvAraT7Ftq9EXjnXYgt8=
 github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
+github.com/undefinedlabs/go-mpatch v0.0.0-20200122175732-0044123dbb98 h1:Z/megzdoMbuZ0H/oLmfTw92PAEfyTi1DkvAr8AUzFgw=
+github.com/undefinedlabs/go-mpatch v0.0.0-20200122175732-0044123dbb98/go.mod h1:TyJZDQ/5AgyN7FSLiBJ8RO9u2c6wbtRvK827b6AVqY4=
+github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI=
+github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
 github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo=
 github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
 github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
@@ -465,6 +483,8 @@ go.uber.org/zap v0.0.0-20180814183419-67bc79d13d15/go.mod h1:vwi/ZaCAaUcBkycHslx
 go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 go.uber.org/zap v1.10.0 h1:ORx85nbTijNz8ljznvCMR1ZBIPKFn3jQrag10X2AsuM=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
+go.undefinedlabs.com/scopeagent v0.1.6 h1:AEUAbwBh7g0XXFVMHyTJqrJOTNjKehcNBL+qWAbth70=
+go.undefinedlabs.com/scopeagent v0.1.6/go.mod h1:4QeO91RRdKn2G+KyTqou6dZTWkUS+L0tnJIk0cbrQjM=
 go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
 golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
@@ -504,11 +524,14 @@ golang.org/x/net v0.0.0-20190320064053-1272bf9dcd53/go.mod h1:t9HGtf8HONx5eT2rtn
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190812203447-cdfb69ac37fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191004110552-13f9640d40b9 h1:rjwSpXsdiK0dV8/Naq3kAw9ymfAeJIyd0upUIElB+lI=
 golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA=
+golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -542,6 +565,8 @@ golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg=
 golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82 h1:ywK/j/KkyTHcdyYSZNXGjMwgmDSfjglYZ3vStQ/gSCU=
+golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20171227012246-e19ae1496984/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -586,6 +611,7 @@ google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20181029155118-b69ba1387ce2/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
@@ -595,6 +621,8 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn
 google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
 google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873 h1:nfPFGzJkUDX6uBmpN/pSw7MbOAWegH5QDQuoXFHedLg=
 google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
+google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
 google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio=
 google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
@@ -602,6 +630,8 @@ google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZi
 google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
 google.golang.org/grpc v1.23.0 h1:AzbTB6ux+okLTzP8Ru1Xs41C303zdcfEht7MQnYJt5A=
 google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
+google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
+google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -622,6 +652,8 @@ gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637 h1:yiW+nvdHb9LVqSHQBXfZCieqV4fzYhNBql77zY0ykqs=
+gopkg.in/tomb.v2 v2.0.0-20161208151619-d5d1b5820637/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk=
 gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
 gopkg.in/yaml.v2 v2.0.0/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/pkg/analyze/analyzer.go b/pkg/analyze/analyzer.go
index cddfab5f..8e219c28 100644
--- a/pkg/analyze/analyzer.go
+++ b/pkg/analyze/analyzer.go
@@ -79,12 +79,6 @@ func Analyze(analyzer *troubleshootv1beta1.Analyze, getFile getCollectedFileCont
 		}
 		return analyzeDistribution(analyzer.Distribution, getFile)
 	}
-	if analyzer.NodeResources != nil {
-		if analyzer.NodeResources.Exclude {
-			return nil, nil
-		}
-		return analyzeNodeResources(analyzer.NodeResources, getFile)
-	}
 	if analyzer.TextAnalyze != nil {
 		return analyzeTextAnalyze(analyzer.TextAnalyze, getFile)
 	}
diff --git a/pkg/analyze/node_resources.go b/pkg/analyze/node_resources.go
deleted file mode 100644
index f23afa3f..00000000
--- a/pkg/analyze/node_resources.go
+++ /dev/null
@@ -1,218 +0,0 @@
-package analyzer
-
-import (
-	"encoding/json"
-	"strconv"
-	"strings"
-
-	"github.com/pkg/errors"
-	troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
-	corev1 "k8s.io/api/core/v1"
-	"k8s.io/apimachinery/pkg/api/resource"
-)
-
-func analyzeNodeResources(analyzer *troubleshootv1beta1.NodeResources, getCollectedFileContents func(string) ([]byte, error)) (*AnalyzeResult, error) {
-	collected, err := getCollectedFileContents("cluster-resources/nodes.json")
-	if err != nil {
-		return nil, errors.Wrap(err, "failed to get contents of nodes.json")
-	}
-
-	var nodes []corev1.Node
-	if err := json.Unmarshal(collected, &nodes); err != nil {
-		return nil, errors.Wrap(err, "failed to unmarshal node list")
-	}
-
-	matchingNodeCount := 0
-
-	for _, node := range nodes {
-		isMatch, err := nodeMatchesFilters(node, analyzer.Filters)
-		if err != nil {
-			return nil, errors.Wrap(err, "failed to check if node matches filter")
-		}
-
-		if isMatch {
-			matchingNodeCount++
-		}
-	}
-
-	title := analyzer.CheckName
-	if title == "" {
-		title = "Node Resources"
-	}
-
-	result := &AnalyzeResult{
-		Title: title,
-	}
-
-	for _, outcome := range analyzer.Outcomes {
-		if outcome.Fail != nil {
-			isWhenMatch, err := compareNodeResourceConditionalToActual(outcome.Fail.When, matchingNodeCount)
-			if err != nil {
-				return nil, errors.Wrap(err, "failed to parse when")
-			}
-
-			if isWhenMatch {
-				result.IsFail = true
-				result.Message = outcome.Fail.Message
-				result.URI = outcome.Fail.URI
-
-				return result, nil
-			}
-		} else if outcome.Warn != nil {
-			isWhenMatch, err := compareNodeResourceConditionalToActual(outcome.Warn.When, matchingNodeCount)
-			if err != nil {
-				return nil, errors.Wrap(err, "failed to parse when")
-			}
-
-			if isWhenMatch {
-				result.IsWarn = true
-				result.Message = outcome.Warn.Message
-				result.URI = outcome.Warn.URI
-
-				return result, nil
-			}
-		} else if outcome.Pass != nil {
-			isWhenMatch, err := compareNodeResourceConditionalToActual(outcome.Pass.When, matchingNodeCount)
-			if err != nil {
-				return nil, errors.Wrap(err, "failed to parse when")
-			}
-
-			if isWhenMatch {
-				result.IsPass = true
-				result.Message = outcome.Pass.Message
-				result.URI = outcome.Pass.URI
-
-				return result, nil
-			}
-		}
-	}
-
-	return result, nil
-}
-
-func compareNodeResourceConditionalToActual(conditional string, actual int) (bool, error) {
-	if conditional == "" {
-		return true, nil
-	}
-
-	parts := strings.Split(strings.TrimSpace(conditional), " ")
-
-	if len(parts) != 2 {
-		return false, errors.New("unable to parse nodeResources conditional")
-	}
-
-	operator := parts[0]
-	desiredValue, err := strconv.Atoi(parts[1])
-	if err != nil {
-		return false, errors.Wrap(err, "failed to parse nodeResource value")
-	}
-
-	switch operator {
-	case "=", "==", "===":
-		return desiredValue == actual, nil
-	case "<":
-		return actual < desiredValue, nil
-	case "<=":
-		return actual <= desiredValue, nil
-	case ">":
-		return actual > desiredValue, nil
-	case ">=":
-		return actual >= desiredValue, nil
-	}
-
-	return false, errors.New("unexpected conditional in nodeResources")
-}
-
-func nodeMatchesFilters(node corev1.Node, filters *troubleshootv1beta1.NodeResourceFilters) (bool, error) {
-	if filters == nil {
-		return true, nil
-	}
-
-	// all filters must pass for this to pass
-
-	if filters.CPUCapacity != "" {
-		parsed, err := resource.ParseQuantity(filters.CPUCapacity)
-		if err != nil {
-			return false, errors.Wrap(err, "failed to parse cpu capacity")
-		}
-
-		if node.Status.Capacity.Cpu().Cmp(parsed) == -1 {
-			return false, nil
-		}
-	}
-	if filters.CPUAllocatable != "" {
-		parsed, err := resource.ParseQuantity(filters.CPUAllocatable)
-		if err != nil {
-			return false, errors.Wrap(err, "failed to parse cpu allocatable")
-		}
-
-		if node.Status.Allocatable.Cpu().Cmp(parsed) == -1 {
-			return false, nil
-		}
-	}
-
-	if filters.MemoryCapacity != "" {
-		parsed, err := resource.ParseQuantity(filters.MemoryCapacity)
-		if err != nil {
-			return false, errors.Wrap(err, "failed to parse memory capacity")
-		}
-
-		if node.Status.Capacity.Memory().Cmp(parsed) == -1 {
-			return false, nil
-		}
-	}
-	if filters.MemoryAllocatable != "" {
-		parsed, err := resource.ParseQuantity(filters.MemoryAllocatable)
-		if err != nil {
-			return false, errors.Wrap(err, "failed to parse memory allocatable")
-		}
-
-		if node.Status.Allocatable.Memory().Cmp(parsed) == -1 {
-			return false, nil
-		}
-	}
-
-	if filters.PodCapacity != "" {
-		parsed, err := resource.ParseQuantity(filters.PodCapacity)
-		if err != nil {
-			return false, errors.Wrap(err, "failed to parse pod capacity")
-		}
-
-		if node.Status.Capacity.Pods().Cmp(parsed) == -1 {
-			return false, nil
-		}
-	}
-	if filters.PodAllocatable != "" {
-		parsed, err := resource.ParseQuantity(filters.PodAllocatable)
-		if err != nil {
-			return false, errors.Wrap(err, "failed to parse pod allocatable")
-		}
-
-		if node.Status.Allocatable.Pods().Cmp(parsed) == -1 {
-			return false, nil
-		}
-	}
-
-	if filters.EphemeralStorageCapacity != "" {
-		parsed, err := resource.ParseQuantity(filters.EphemeralStorageCapacity)
-		if err != nil {
-			return false, errors.Wrap(err, "failed to parse ephemeralstorage capacity")
-		}
-
-		if node.Status.Capacity.StorageEphemeral().Cmp(parsed) == -1 {
-			return false, nil
-		}
-	}
-	if filters.EphemeralStorageAllocatable != "" {
-		parsed, err := resource.ParseQuantity(filters.EphemeralStorageAllocatable)
-		if err != nil {
-			return false, errors.Wrap(err, "failed to parse ephemeralstorage allocatable")
-		}
-
-		if node.Status.Allocatable.StorageEphemeral().Cmp(parsed) == -1 {
-			return false, nil
-		}
-	}
-
-	return true, nil
-}
diff --git a/pkg/apis/troubleshoot/v1beta1/analyzer_shared.go b/pkg/apis/troubleshoot/v1beta1/analyzer_shared.go
index ab437495..7ee57364 100644
--- a/pkg/apis/troubleshoot/v1beta1/analyzer_shared.go
+++ b/pkg/apis/troubleshoot/v1beta1/analyzer_shared.go
@@ -74,23 +74,6 @@ type Distribution struct {
 	Outcomes    []*Outcome `json:"outcomes" yaml:"outcomes"`
 }
 
-type NodeResources struct {
-	AnalyzeMeta `json:",inline" yaml:",inline"`
-	Outcomes    []*Outcome           `json:"outcomes" yaml:"outcomes"`
-	Filters     *NodeResourceFilters `json:"filters,omitempty" yaml:"filters,omitempty"`
-}
-
-type NodeResourceFilters struct {
-	CPUCapacity                 string `json:"cpuCapacity,omitempty" yaml:"cpuCapacity,omitempty"`
-	CPUAllocatable              string `json:"cpuAllocatable,omitempty" yaml:"cpuAllocatable,omitempty"`
-	MemoryCapacity              string `json:"memoryCapacity,omitempty" yaml:"memoryCapacity,omitempty"`
-	MemoryAllocatable           string `json:"memoryAllocatable,omitempty" yaml:"memoryAllocatable,omitempty"`
-	PodCapacity                 string `json:"podCapacity,omitempty" yaml:"podCapacity,omitempty"`
-	PodAllocatable              string `json:"podAllocatable,omitempty" yaml:"podAllocatable,omitempty"`
-	EphemeralStorageCapacity    string `json:"ephemeralStorageCapacity,omitempty" yaml:"ephemeralStorageCapacity,omitempty"`
-	EphemeralStorageAllocatable string `json:"ephemeralStorageAllocatable,omitempty" yaml:"ephemeralStorageAllocatable,omitempty"`
-}
-
 type TextAnalyze struct {
 	AnalyzeMeta   `json:",inline" yaml:",inline"`
 	CollectorName string     `json:"collectorName,omitempty" yaml:"collectorName,omitempty"`
@@ -116,6 +99,5 @@ type Analyze struct {
 	StatefulsetStatus        *StatefulsetStatus        `json:"statefulsetStatus,omitempty" yaml:"statefulsetStatus,omitempty"`
 	ContainerRuntime         *ContainerRuntime         `json:"containerRuntime,omitempty" yaml:"containerRuntime,omitempty"`
 	Distribution             *Distribution             `json:"distribution,omitempty" yaml:"distribution,omitempty"`
-	NodeResources            *NodeResources            `json:"nodeResources,omitempty" yaml:"nodeResources,omitempty"`
 	TextAnalyze              *TextAnalyze              `json:"textAnalyze,omitempty" yaml:"textAnalyze,omitempty"`
 }
diff --git a/pkg/apis/troubleshoot/v1beta1/zz_generated.deepcopy.go b/pkg/apis/troubleshoot/v1beta1/zz_generated.deepcopy.go
index b7af7d4d..5123659f 100644
--- a/pkg/apis/troubleshoot/v1beta1/zz_generated.deepcopy.go
+++ b/pkg/apis/troubleshoot/v1beta1/zz_generated.deepcopy.go
@@ -102,11 +102,6 @@ func (in *Analyze) DeepCopyInto(out *Analyze) {
 		*out = new(Distribution)
 		(*in).DeepCopyInto(*out)
 	}
-	if in.NodeResources != nil {
-		in, out := &in.NodeResources, &out.NodeResources
-		*out = new(NodeResources)
-		(*in).DeepCopyInto(*out)
-	}
 	if in.TextAnalyze != nil {
 		in, out := &in.TextAnalyze, &out.TextAnalyze
 		*out = new(TextAnalyze)
@@ -1049,53 +1044,6 @@ func (in *Logs) DeepCopy() *Logs {
 	return out
 }
 
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *NodeResourceFilters) DeepCopyInto(out *NodeResourceFilters) {
-	*out = *in
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResourceFilters.
-func (in *NodeResourceFilters) DeepCopy() *NodeResourceFilters {
-	if in == nil {
-		return nil
-	}
-	out := new(NodeResourceFilters)
-	in.DeepCopyInto(out)
-	return out
-}
-
-// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
-func (in *NodeResources) DeepCopyInto(out *NodeResources) {
-	*out = *in
-	out.AnalyzeMeta = in.AnalyzeMeta
-	if in.Outcomes != nil {
-		in, out := &in.Outcomes, &out.Outcomes
-		*out = make([]*Outcome, len(*in))
-		for i := range *in {
-			if (*in)[i] != nil {
-				in, out := &(*in)[i], &(*out)[i]
-				*out = new(Outcome)
-				(*in).DeepCopyInto(*out)
-			}
-		}
-	}
-	if in.Filters != nil {
-		in, out := &in.Filters, &out.Filters
-		*out = new(NodeResourceFilters)
-		**out = **in
-	}
-}
-
-// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NodeResources.
-func (in *NodeResources) DeepCopy() *NodeResources {
-	if in == nil {
-		return nil
-	}
-	out := new(NodeResources)
-	in.DeepCopyInto(out)
-	return out
-}
-
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *Outcome) DeepCopyInto(out *Outcome) {
 	*out = *in


Test patch:
diff --git a/pkg/analyze/cluster_version_test.go b/pkg/analyze/cluster_version_test.go
index 739548f0..64b05291 100644
--- a/pkg/analyze/cluster_version_test.go
+++ b/pkg/analyze/cluster_version_test.go
@@ -6,6 +6,7 @@ import (
 
 	"github.com/blang/semver"
 	troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func Test_analyzeClusterVersionResult(t *testing.T) {
@@ -86,6 +87,8 @@ func Test_analyzeClusterVersionResult(t *testing.T) {
 	}
 	for _, tt := range tests {
 		t.Run(tt.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			got, err := analyzeClusterVersionResult(tt.args.k8sVersion, tt.args.outcomes, tt.args.checkName)
 			if (err != nil) != tt.wantErr {
 				t.Errorf("analyzeClusterVersionResult() error = %v, wantErr %v", err, tt.wantErr)
diff --git a/pkg/analyze/container_runtime_test.go b/pkg/analyze/container_runtime_test.go
index 1119e921..5e81b7eb 100644
--- a/pkg/analyze/container_runtime_test.go
+++ b/pkg/analyze/container_runtime_test.go
@@ -6,6 +6,7 @@ import (
 	troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func Test_compareRuntimeConditionalToActual(t *testing.T) {
@@ -55,6 +56,8 @@ func Test_compareRuntimeConditionalToActual(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			actual, err := compareRuntimeConditionalToActual(test.conditional, test.actual)
@@ -105,6 +108,8 @@ func Test_containerRuntime(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			getFiles := func(n string) ([]byte, error) {
diff --git a/pkg/analyze/deployment_status_test.go b/pkg/analyze/deployment_status_test.go
index 6b58f034..08b7e8da 100644
--- a/pkg/analyze/deployment_status_test.go
+++ b/pkg/analyze/deployment_status_test.go
@@ -6,6 +6,7 @@ import (
 	troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func Test_deploymentStatus(t *testing.T) {
@@ -115,6 +116,8 @@ func Test_deploymentStatus(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			getFiles := func(n string) ([]byte, error) {
diff --git a/pkg/analyze/distribution_test.go b/pkg/analyze/distribution_test.go
index d6353748..42de3de0 100644
--- a/pkg/analyze/distribution_test.go
+++ b/pkg/analyze/distribution_test.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func Test_compareDistributionConditionalToActual(t *testing.T) {
@@ -41,6 +42,8 @@ func Test_compareDistributionConditionalToActual(t *testing.T) {
 	}
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			actual, err := compareDistributionConditionalToActual(test.conditional, test.input)
@@ -49,7 +52,6 @@ func Test_compareDistributionConditionalToActual(t *testing.T) {
 			assert.Equal(t, test.expected, actual)
 		})
 	}
-
 }
 
 func Test_mustNormalizeDistributionName(t *testing.T) {
@@ -77,6 +79,8 @@ func Test_mustNormalizeDistributionName(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.raw, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			actual := mustNormalizeDistributionName(test.raw)
 
 			assert.Equal(t, test.expected, actual)
diff --git a/pkg/analyze/main_test.go b/pkg/analyze/main_test.go
new file mode 100644
index 00000000..fc50edad
--- /dev/null
+++ b/pkg/analyze/main_test.go
@@ -0,0 +1,12 @@
+package analyzer
+
+import (
+	"os"
+	"testing"
+
+	"go.undefinedlabs.com/scopeagent"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(scopeagent.Run(m))
+}
diff --git a/pkg/analyze/node_resources_test.go b/pkg/analyze/node_resources_test.go
deleted file mode 100644
index 9353c271..00000000
--- a/pkg/analyze/node_resources_test.go
+++ /dev/null
@@ -1,196 +0,0 @@
-package analyzer
-
-import (
-	"testing"
-
-	troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
-	"github.com/stretchr/testify/assert"
-	"github.com/stretchr/testify/require"
-	corev1 "k8s.io/api/core/v1"
-	"k8s.io/apimachinery/pkg/api/resource"
-)
-
-func Test_compareNodeResourceConditionalToActual(t *testing.T) {
-	tests := []struct {
-		name        string
-		conditional string
-		actual      int
-		expected    bool
-	}{
-		{
-			name:        "=",
-			conditional: "= 5",
-			actual:      5,
-			expected:    true,
-		},
-		{
-			name:        "<= (pass)",
-			conditional: "<= 5",
-			actual:      4,
-			expected:    true,
-		},
-		{
-			name:        "<= (fail)",
-			conditional: "<= 5",
-			actual:      6,
-			expected:    false,
-		},
-		{
-			name:        "> (pass)",
-			conditional: "> 5",
-			actual:      6,
-			expected:    true,
-		},
-		{
-			name:        ">=(fail)",
-			conditional: ">= 5",
-			actual:      4,
-			expected:    false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			req := require.New(t)
-
-			actual, err := compareNodeResourceConditionalToActual(test.conditional, test.actual)
-			req.NoError(err)
-
-			assert.Equal(t, test.expected, actual)
-
-		})
-	}
-}
-
-func Test_nodeMatchesFilters(t *testing.T) {
-	tests := []struct {
-		name         string
-		node         corev1.Node
-		filters      *troubleshootv1beta1.NodeResourceFilters
-		expectResult bool
-	}{
-		{
-			name: "true when empty filters",
-			node: corev1.Node{
-				Status: corev1.NodeStatus{
-					Capacity: corev1.ResourceList{
-						"attachable-volumes-aws-ebs": resource.MustParse("25"),
-						"cpu":                        resource.MustParse("2"),
-						"ephemeral-storage":          resource.MustParse("20959212Ki"),
-						"hugepages-1Gi":              resource.MustParse("0"),
-						"hugepages-2Mi":              resource.MustParse("0"),
-						"memory":                     resource.MustParse("7951376Ki"),
-						"pods":                       resource.MustParse("29"),
-					},
-					Allocatable: corev1.ResourceList{
-						"attachable-volumes-aws-ebs": resource.MustParse("25"),
-						"cpu":                        resource.MustParse("2"),
-						"ephemeral-storage":          resource.MustParse("19316009748"),
-						"hugepages-1Gi":              resource.MustParse("0"),
-						"hugepages-2Mi":              resource.MustParse("0"),
-						"memory":                     resource.MustParse("7848976Ki"),
-						"pods":                       resource.MustParse("29"),
-					},
-				},
-			},
-			filters:      &troubleshootv1beta1.NodeResourceFilters{},
-			expectResult: true,
-		},
-		{
-			name: "true while nil/missing filters",
-			node: corev1.Node{
-				Status: corev1.NodeStatus{
-					Capacity: corev1.ResourceList{
-						"attachable-volumes-aws-ebs": resource.MustParse("25"),
-						"cpu":                        resource.MustParse("2"),
-						"ephemeral-storage":          resource.MustParse("20959212Ki"),
-						"hugepages-1Gi":              resource.MustParse("0"),
-						"hugepages-2Mi":              resource.MustParse("0"),
-						"memory":                     resource.MustParse("7951376Ki"),
-						"pods":                       resource.MustParse("29"),
-					},
-					Allocatable: corev1.ResourceList{
-						"attachable-volumes-aws-ebs": resource.MustParse("25"),
-						"cpu":                        resource.MustParse("2"),
-						"ephemeral-storage":          resource.MustParse("19316009748"),
-						"hugepages-1Gi":              resource.MustParse("0"),
-						"hugepages-2Mi":              resource.MustParse("0"),
-						"memory":                     resource.MustParse("7848976Ki"),
-						"pods":                       resource.MustParse("29"),
-					},
-				},
-			},
-			expectResult: true,
-		},
-		{
-			name: "false when allocatable memory is too high",
-			node: corev1.Node{
-				Status: corev1.NodeStatus{
-					Capacity: corev1.ResourceList{
-						"attachable-volumes-aws-ebs": resource.MustParse("25"),
-						"cpu":                        resource.MustParse("2"),
-						"ephemeral-storage":          resource.MustParse("20959212Ki"),
-						"hugepages-1Gi":              resource.MustParse("0"),
-						"hugepages-2Mi":              resource.MustParse("0"),
-						"memory":                     resource.MustParse("7951376Ki"),
-						"pods":                       resource.MustParse("29"),
-					},
-					Allocatable: corev1.ResourceList{
-						"attachable-volumes-aws-ebs": resource.MustParse("25"),
-						"cpu":                        resource.MustParse("2"),
-						"ephemeral-storage":          resource.MustParse("19316009748"),
-						"hugepages-1Gi":              resource.MustParse("0"),
-						"hugepages-2Mi":              resource.MustParse("0"),
-						"memory":                     resource.MustParse("7848976Ki"),
-						"pods":                       resource.MustParse("29"),
-					},
-				},
-			},
-			filters: &troubleshootv1beta1.NodeResourceFilters{
-				MemoryAllocatable: "16Gi",
-			},
-			expectResult: false,
-		},
-		{
-			name: "true when allocatable memory is available",
-			node: corev1.Node{
-				Status: corev1.NodeStatus{
-					Capacity: corev1.ResourceList{
-						"attachable-volumes-aws-ebs": resource.MustParse("25"),
-						"cpu":                        resource.MustParse("2"),
-						"ephemeral-storage":          resource.MustParse("20959212Ki"),
-						"hugepages-1Gi":              resource.MustParse("0"),
-						"hugepages-2Mi":              resource.MustParse("0"),
-						"memory":                     resource.MustParse("7951376Ki"),
-						"pods":                       resource.MustParse("29"),
-					},
-					Allocatable: corev1.ResourceList{
-						"attachable-volumes-aws-ebs": resource.MustParse("25"),
-						"cpu":                        resource.MustParse("2"),
-						"ephemeral-storage":          resource.MustParse("19316009748"),
-						"hugepages-1Gi":              resource.MustParse("0"),
-						"hugepages-2Mi":              resource.MustParse("0"),
-						"memory":                     resource.MustParse("7848976Ki"),
-						"pods":                       resource.MustParse("29"),
-					},
-				},
-			},
-			filters: &troubleshootv1beta1.NodeResourceFilters{
-				MemoryAllocatable: "8Gi",
-			},
-			expectResult: false,
-		},
-	}
-
-	for _, test := range tests {
-		t.Run(test.name, func(t *testing.T) {
-			req := require.New(t)
-
-			actual, err := nodeMatchesFilters(test.node, test.filters)
-			req.NoError(err)
-
-			assert.Equal(t, test.expectResult, actual)
-
-		})
-	}
-}
diff --git a/pkg/analyze/text_analyze_test.go b/pkg/analyze/text_analyze_test.go
index 3bdb8f9c..eaeecdd3 100644
--- a/pkg/analyze/text_analyze_test.go
+++ b/pkg/analyze/text_analyze_test.go
@@ -7,6 +7,7 @@ import (
 	troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func Test_textAnalyze(t *testing.T) {
@@ -200,6 +201,8 @@ func Test_textAnalyze(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			getFiles := func(n string) ([]byte, error) {
@@ -255,6 +258,8 @@ func Test_compareRegex(t *testing.T) {
 	}
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			actual, err := compareRegex(test.conditional, test.foundMatches)
@@ -263,5 +268,4 @@ func Test_compareRegex(t *testing.T) {
 			assert.Equal(t, test.expected, actual)
 		})
 	}
-
 }
diff --git a/pkg/apis/troubleshoot/v1beta1/analyzer_shared_test.go b/pkg/apis/troubleshoot/v1beta1/analyzer_shared_test.go
index 85e48d35..fbd9caea 100644
--- a/pkg/apis/troubleshoot/v1beta1/analyzer_shared_test.go
+++ b/pkg/apis/troubleshoot/v1beta1/analyzer_shared_test.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
+	"go.undefinedlabs.com/scopeagent"
 	"gopkg.in/yaml.v2"
 )
 
@@ -43,6 +44,8 @@ func TestAnalyze_Unmarshal(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			req := require.New(t)
 
 			a := Analyze{}
diff --git a/pkg/apis/troubleshoot/v1beta1/v1beta1_suite_test.go b/pkg/apis/troubleshoot/v1beta1/v1beta1_suite_test.go
index e6f04157..73616aa1 100644
--- a/pkg/apis/troubleshoot/v1beta1/v1beta1_suite_test.go
+++ b/pkg/apis/troubleshoot/v1beta1/v1beta1_suite_test.go
@@ -22,6 +22,7 @@ import (
 	"path/filepath"
 	"testing"
 
+	"go.undefinedlabs.com/scopeagent"
 	"k8s.io/client-go/kubernetes/scheme"
 	"k8s.io/client-go/rest"
 	"sigs.k8s.io/controller-runtime/pkg/client"
@@ -49,7 +50,7 @@ func TestMain(m *testing.M) {
 		log.Fatal(err)
 	}
 
-	code := m.Run()
+	code := scopeagent.Run(m)
 	t.Stop()
 	os.Exit(code)
 }
diff --git a/pkg/collect/collector_test.go b/pkg/collect/collector_test.go
index 0dbf8c6a..f06a7613 100644
--- a/pkg/collect/collector_test.go
+++ b/pkg/collect/collector_test.go
@@ -5,6 +5,7 @@ import (
 
 	troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
 	"github.com/stretchr/testify/assert"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func Test_ParseSpec(t *testing.T) {
@@ -26,6 +27,8 @@ func Test_ParseSpec(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			c, err := ParseSpec(test.spec)
 
 			if test.expectError {
diff --git a/pkg/collect/main_test.go b/pkg/collect/main_test.go
new file mode 100644
index 00000000..976ad72e
--- /dev/null
+++ b/pkg/collect/main_test.go
@@ -0,0 +1,12 @@
+package collect
+
+import (
+	"os"
+	"testing"
+
+	"go.undefinedlabs.com/scopeagent"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(scopeagent.Run(m))
+}
diff --git a/pkg/collect/util_test.go b/pkg/collect/util_test.go
index ea7efd8a..a56e6793 100644
--- a/pkg/collect/util_test.go
+++ b/pkg/collect/util_test.go
@@ -5,6 +5,7 @@ import (
 
 	troubleshootv1beta1 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta1"
 	"github.com/stretchr/testify/assert"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func Test_selectorToString(t *testing.T) {
@@ -22,6 +23,8 @@ func Test_selectorToString(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			actual := selectorToString(test.selector)
 			assert.Equal(t, test.expect, actual)
 		})
@@ -72,6 +75,8 @@ func Test_DeterministicIDForCollector(t *testing.T) {
 
 	for _, test := range tests {
 		t.Run(test.name, func(t *testing.T) {
+			scopetest := scopeagent.StartTest(t)
+			defer scopetest.End()
 			actual := DeterministicIDForCollector(test.collector)
 			assert.Equal(t, test.expect, actual)
 		})
diff --git a/pkg/redact/main_test.go b/pkg/redact/main_test.go
new file mode 100644
index 00000000..a51c19e3
--- /dev/null
+++ b/pkg/redact/main_test.go
@@ -0,0 +1,12 @@
+package redact
+
+import (
+	"os"
+	"testing"
+
+	"go.undefinedlabs.com/scopeagent"
+)
+
+func TestMain(m *testing.M) {
+	os.Exit(scopeagent.Run(m))
+}
diff --git a/pkg/redact/redact_test.go b/pkg/redact/redact_test.go
index 16f88786..8e28899e 100644
--- a/pkg/redact/redact_test.go
+++ b/pkg/redact/redact_test.go
@@ -7,6 +7,7 @@ import (
 	"testing"
 
 	"github.com/stretchr/testify/assert"
+	"go.undefinedlabs.com/scopeagent"
 )
 
 func Test_Redactors(t *testing.T) {
@@ -1619,6 +1620,8 @@ func Test_Redactors(t *testing.T) {
 	  ]`
 
 	t.Run("test default redactors", func(t *testing.T) {
+		scopetest := scopeagent.StartTest(t)
+		defer scopetest.End()
 		redactors, err := GetRedactors()
 		assert.NoError(t, err)