main.go raw
1 package main
2
3 import (
4 "flag"
5 "fmt"
6 "os"
7 "strings"
8
9 "next.orly.dev/pkg/lol/log"
10 relaytester "next.orly.dev/relay-tester"
11 )
12
13 func main() {
14 var (
15 relayURL = flag.String("url", "", "relay websocket URL (required, e.g., ws://127.0.0.1:3334)")
16 testName = flag.String("test", "", "run specific test by name (default: run all tests)")
17 jsonOut = flag.Bool("json", false, "output results in JSON format")
18 verbose = flag.Bool("v", false, "verbose output")
19 listTests = flag.Bool("list", false, "list all available tests and exit")
20 )
21 flag.Parse()
22
23 if *listTests {
24 listAllTests()
25 return
26 }
27
28 if *relayURL == "" {
29 log.E.F("required flag: -url (relay websocket URL)")
30 flag.Usage()
31 os.Exit(1)
32 }
33
34 // Validate URL format
35 if !strings.HasPrefix(*relayURL, "ws://") && !strings.HasPrefix(*relayURL, "wss://") {
36 log.E.F("URL must start with ws:// or wss://")
37 os.Exit(1)
38 }
39
40 // Create test suite
41 if *verbose {
42 log.I.F("Creating test suite for %s...", *relayURL)
43 }
44 suite, err := relaytester.NewTestSuite(*relayURL)
45 if err != nil {
46 log.E.F("failed to create test suite: %v", err)
47 os.Exit(1)
48 }
49
50 // Run tests
51 var results []relaytester.TestResult
52 if *testName != "" {
53 if *verbose {
54 log.I.F("Running test: %s", *testName)
55 }
56 result, err := suite.RunTest(*testName)
57 if err != nil {
58 log.E.F("failed to run test %s: %v", *testName, err)
59 os.Exit(1)
60 }
61 results = []relaytester.TestResult{result}
62 } else {
63 if *verbose {
64 log.I.F("Running all tests...")
65 }
66 if results, err = suite.Run(); err != nil {
67 log.E.F("failed to run tests: %v", err)
68 os.Exit(1)
69 }
70 }
71
72 // Output results
73 if *jsonOut {
74 jsonOutput, err := relaytester.FormatJSON(results)
75 if err != nil {
76 log.E.F("failed to format JSON: %v", err)
77 os.Exit(1)
78 }
79 fmt.Println(jsonOutput)
80 } else {
81 outputResults(results, *verbose)
82 }
83
84 // Check exit code
85 hasRequiredFailures := false
86 for _, result := range results {
87 if result.Required && !result.Pass {
88 hasRequiredFailures = true
89 break
90 }
91 }
92
93 if hasRequiredFailures {
94 os.Exit(1)
95 }
96 }
97
98 func outputResults(results []relaytester.TestResult, verbose bool) {
99 passed := 0
100 failed := 0
101 requiredFailed := 0
102
103 for _, result := range results {
104 if result.Pass {
105 passed++
106 if verbose {
107 fmt.Printf("PASS: %s", result.Name)
108 if result.Info != "" {
109 fmt.Printf(" - %s", result.Info)
110 }
111 fmt.Println()
112 } else {
113 fmt.Printf("PASS: %s\n", result.Name)
114 }
115 } else {
116 failed++
117 if result.Required {
118 requiredFailed++
119 fmt.Printf("FAIL (required): %s", result.Name)
120 } else {
121 fmt.Printf("FAIL (optional): %s", result.Name)
122 }
123 if result.Info != "" {
124 fmt.Printf(" - %s", result.Info)
125 }
126 fmt.Println()
127 }
128 }
129
130 fmt.Println()
131 fmt.Println("Test Summary:")
132 fmt.Printf(" Total: %d\n", len(results))
133 fmt.Printf(" Passed: %d\n", passed)
134 fmt.Printf(" Failed: %d\n", failed)
135 fmt.Printf(" Required Failed: %d\n", requiredFailed)
136 }
137
138 func listAllTests() {
139 // Create a dummy test suite to get the list of tests
140 suite, err := relaytester.NewTestSuite("ws://127.0.0.1:0")
141 if err != nil {
142 log.E.F("failed to create test suite: %v", err)
143 os.Exit(1)
144 }
145
146 fmt.Println("Available tests:")
147 fmt.Println()
148
149 testNames := suite.ListTests()
150 testInfo := suite.GetTestNames()
151
152 for _, name := range testNames {
153 required := ""
154 if testInfo[name] {
155 required = " (required)"
156 }
157 fmt.Printf(" - %s%s\n", name, required)
158 }
159 }
160
161