@@ -2,9 +2,14 @@ package main
22
33import (
44 "context"
5+ "fmt"
6+ "net"
57 "os"
68 "path/filepath"
79 "testing"
10+ "time"
11+
12+ gossh "golang.org/x/crypto/ssh"
813
914 "github.com/tbotnz/cisshgo/utils"
1015)
@@ -30,6 +35,123 @@ platforms:
3035 return tmpFile
3136}
3237
38+ func freePort (t * testing.T ) int {
39+ t .Helper ()
40+ ln , err := net .Listen ("tcp" , "127.0.0.1:0" )
41+ if err != nil {
42+ t .Fatal (err )
43+ }
44+ port := ln .Addr ().(* net.TCPAddr ).Port
45+ ln .Close ()
46+ return port
47+ }
48+
49+ func waitReady (t * testing.T , addr string ) {
50+ t .Helper ()
51+ for i := 0 ; i < 20 ; i ++ {
52+ conn , err := net .DialTimeout ("tcp" , addr , 100 * time .Millisecond )
53+ if err == nil {
54+ conn .Close ()
55+ return
56+ }
57+ time .Sleep (50 * time .Millisecond )
58+ }
59+ t .Fatalf ("server at %s never became ready" , addr )
60+ }
61+
62+ func sshDial (t * testing.T , addr string ) {
63+ t .Helper ()
64+ cfg := & gossh.ClientConfig {
65+ User : "admin" ,
66+ Auth : []gossh.AuthMethod {gossh .Password ("admin" )},
67+ HostKeyCallback : gossh .InsecureIgnoreHostKey (),
68+ Timeout : 2 * time .Second ,
69+ }
70+ client , err := gossh .Dial ("tcp" , addr , cfg )
71+ if err != nil {
72+ t .Fatalf ("ssh dial: %v" , err )
73+ }
74+ client .Close ()
75+ }
76+
77+ func TestRun_PlatformListener (t * testing.T ) {
78+ port := freePort (t )
79+ addr := net .JoinHostPort ("127.0.0.1" , fmt .Sprintf ("%d" , port ))
80+
81+ ctx , cancel := context .WithCancel (context .Background ())
82+ defer cancel ()
83+
84+ cli := utils.CLI {Listeners : 1 , StartingPort : port , Platform : "csr1000v" , TranscriptMap : validTranscriptMap (t )}
85+ done := make (chan error , 1 )
86+ go func () { done <- run (ctx , cli ) }()
87+
88+ waitReady (t , addr )
89+ sshDial (t , addr )
90+
91+ cancel ()
92+ if err := <- done ; err != nil {
93+ t .Errorf ("run() returned error: %v" , err )
94+ }
95+ }
96+
97+ func TestRun_ScenarioListener (t * testing.T ) {
98+ dir := t .TempDir ()
99+
100+ // Write transcript files
101+ transcriptFile := filepath .Join (dir , "show_version.txt" )
102+ os .WriteFile (transcriptFile , []byte ("version output\n " ), 0644 )
103+ seqFile := filepath .Join (dir , "seq_step.txt" )
104+ os .WriteFile (seqFile , []byte ("seq output\n " ), 0644 )
105+
106+ tmContent := `---
107+ platforms:
108+ csr1000v:
109+ vendor: "cisco"
110+ hostname: "testhost"
111+ password: "admin"
112+ command_transcripts:
113+ "show version": "show_version.txt"
114+ context_search:
115+ base: ">"
116+ context_hierarchy:
117+ ">": "exit"
118+ scenarios:
119+ test-scenario:
120+ platform: csr1000v
121+ sequence:
122+ - command: "show running-config"
123+ transcript: "seq_step.txt"
124+ `
125+ tmFile := filepath .Join (dir , "transcript_map.yaml" )
126+ os .WriteFile (tmFile , []byte (tmContent ), 0644 )
127+
128+ invContent := `---
129+ devices:
130+ - scenario: test-scenario
131+ count: 1
132+ `
133+ invFile := filepath .Join (dir , "inventory.yaml" )
134+ os .WriteFile (invFile , []byte (invContent ), 0644 )
135+
136+ port := freePort (t )
137+ addr := net .JoinHostPort ("127.0.0.1" , fmt .Sprintf ("%d" , port ))
138+
139+ ctx , cancel := context .WithCancel (context .Background ())
140+ defer cancel ()
141+
142+ cli := utils.CLI {StartingPort : port , Platform : "csr1000v" , TranscriptMap : tmFile , Inventory : invFile }
143+ done := make (chan error , 1 )
144+ go func () { done <- run (ctx , cli ) }()
145+
146+ waitReady (t , addr )
147+ sshDial (t , addr )
148+
149+ cancel ()
150+ if err := <- done ; err != nil {
151+ t .Errorf ("run() returned error: %v" , err )
152+ }
153+ }
154+
33155func TestRun_ZeroListeners (t * testing.T ) {
34156 cli := utils.CLI {Listeners : 0 , StartingPort : 10000 , Platform : "csr1000v" , TranscriptMap : validTranscriptMap (t )}
35157 if err := run (context .Background (), cli ); err != nil {
0 commit comments