serve_test.go 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656
  1. package main
  2. import (
  3. "bufio"
  4. "crypto/tls"
  5. "encoding/json"
  6. "errors"
  7. "io"
  8. "io/ioutil"
  9. "math"
  10. "os"
  11. "os/exec"
  12. "runtime"
  13. "strconv"
  14. "strings"
  15. "sync"
  16. "testing"
  17. "time"
  18. "github.com/flashmob/go-guerrilla"
  19. "github.com/flashmob/go-guerrilla/backends"
  20. "github.com/flashmob/go-guerrilla/log"
  21. test "github.com/flashmob/go-guerrilla/tests"
  22. "github.com/flashmob/go-guerrilla/tests/testcert"
  23. "github.com/spf13/cobra"
  24. )
  25. var configJsonA = `
  26. {
  27. "log_file" : "../../tests/testlog",
  28. "log_level" : "debug",
  29. "pid_file" : "pidfile.pid",
  30. "allowed_hosts": [
  31. "guerrillamail.com",
  32. "guerrillamailblock.com",
  33. "sharklasers.com",
  34. "guerrillamail.net",
  35. "guerrillamail.org"
  36. ],
  37. "backend" : {
  38. "processors" : {
  39. "debugger" : {
  40. "log_received_mails" : true
  41. }
  42. },
  43. "gateways" : {
  44. "default" : {
  45. "save_workers_size" : 1,
  46. "save_process": "HeadersParser|Debugger"
  47. }
  48. }
  49. },
  50. "servers" : [
  51. {
  52. "is_enabled" : true,
  53. "host_name":"mail.test.com",
  54. "max_size": 1000000,
  55. "timeout":180,
  56. "listen_interface":"127.0.0.1:3536",
  57. "max_clients": 200,
  58. "log_file" : "../../tests/testlog",
  59. "tls" : {
  60. "private_key_file":"../../tests/mail2.guerrillamail.com.key.pem",
  61. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  62. "start_tls_on":true,
  63. "tls_always_on":false
  64. }
  65. },
  66. {
  67. "is_enabled" : false,
  68. "host_name":"enable.test.com",
  69. "max_size": 1000000,
  70. "timeout":180,
  71. "listen_interface":"127.0.0.1:2228",
  72. "max_clients": 200,
  73. "log_file" : "../../tests/testlog",
  74. "tls" : {
  75. "private_key_file":"../../tests/mail2.guerrillamail.com.key.pem",
  76. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  77. "start_tls_on":true,
  78. "tls_always_on":false
  79. }
  80. }
  81. ]
  82. }
  83. `
  84. // backend config changed, log_received_mails is false
  85. var configJsonB = `
  86. {
  87. "log_file" : "../../tests/testlog",
  88. "log_level" : "debug",
  89. "pid_file" : "./pidfile2.pid",
  90. "allowed_hosts": [
  91. "guerrillamail.com",
  92. "guerrillamailblock.com",
  93. "sharklasers.com",
  94. "guerrillamail.net",
  95. "guerrillamail.org"
  96. ],
  97. "backend" : {
  98. "processors" : {
  99. "debugger" : {
  100. "log_received_mails" : false
  101. }
  102. },
  103. "gateways" : {
  104. "default" : {
  105. "save_workers_size" : 1,
  106. "save_process": "HeadersParser|Debugger"
  107. }
  108. }
  109. },
  110. "servers" : [
  111. {
  112. "is_enabled" : true,
  113. "host_name":"mail.test.com",
  114. "max_size": 1000000,
  115. "timeout":180,
  116. "listen_interface":"127.0.0.1:3536",
  117. "max_clients": 200,
  118. "log_file" : "../../tests/testlog",
  119. "tls" : {
  120. "private_key_file":"../../tests/mail2.guerrillamail.com.key.pem",
  121. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  122. "start_tls_on":true,
  123. "tls_always_on":false
  124. }
  125. }
  126. ]
  127. }
  128. `
  129. // added a server
  130. var configJsonC = `
  131. {
  132. "log_file" : "../../tests/testlog",
  133. "log_level" : "debug",
  134. "pid_file" : "./pidfile.pid",
  135. "allowed_hosts": [
  136. "guerrillamail.com",
  137. "guerrillamailblock.com",
  138. "sharklasers.com",
  139. "guerrillamail.net",
  140. "guerrillamail.org"
  141. ],
  142. "backend" : {
  143. "processors" : {
  144. "debugger" : {
  145. "log_received_mails" : true
  146. },
  147. "sql" : {
  148. "sql_dsn": "root:ok@tcp(127.0.0.1:3306)/gmail_mail?readTimeout=10s&writeTimeout=10s",
  149. "mail_table":"new_mail",
  150. "primary_mail_host":"sharklasers.com"
  151. }
  152. },
  153. "gateways" : {
  154. "default" : {
  155. "save_workers_size" : 3,
  156. "save_process": "HeadersParser|Debugger"
  157. }
  158. }
  159. },
  160. "servers" : [
  161. {
  162. "is_enabled" : true,
  163. "host_name":"mail.test.com",
  164. "max_size": 1000000,
  165. "timeout":180,
  166. "listen_interface":"127.0.0.1:25",
  167. "max_clients": 200,
  168. "log_file" : "../../tests/testlog",
  169. "tls" : {
  170. "private_key_file":"../../tests/mail2.guerrillamail.com.key.pem",
  171. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  172. "start_tls_on":true,
  173. "tls_always_on":false
  174. }
  175. },
  176. {
  177. "is_enabled" : true,
  178. "host_name":"mail.test.com",
  179. "max_size":1000000,
  180. "timeout":180,
  181. "listen_interface":"127.0.0.1:465",
  182. "max_clients":200,
  183. "log_file" : "../../tests/testlog",
  184. "tls" : {
  185. "private_key_file":"../../tests/mail2.guerrillamail.com.key.pem",
  186. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  187. "start_tls_on":false,
  188. "tls_always_on":true
  189. }
  190. }
  191. ]
  192. }
  193. `
  194. // adds 127.0.0.1:4655, a secure server
  195. var configJsonD = `
  196. {
  197. "log_file" : "../../tests/testlog",
  198. "log_level" : "debug",
  199. "pid_file" : "./pidfile.pid",
  200. "allowed_hosts": [
  201. "guerrillamail.com",
  202. "guerrillamailblock.com",
  203. "sharklasers.com",
  204. "guerrillamail.net",
  205. "guerrillamail.org"
  206. ],
  207. "backend" : {
  208. "processors" : {
  209. "debugger" : {
  210. "log_received_mails" : false
  211. }
  212. },
  213. "gateways" : {
  214. "default" : {
  215. "save_workers_size" : 1,
  216. "save_process": "HeadersParser|Debugger"
  217. }
  218. }
  219. },
  220. "servers" : [
  221. {
  222. "is_enabled" : true,
  223. "host_name":"mail.test.com",
  224. "max_size": 1000000,
  225. "timeout":180,
  226. "listen_interface":"127.0.0.1:2552",
  227. "max_clients": 200,
  228. "log_file" : "../../tests/testlog",
  229. "tls" : {
  230. "private_key_file":"../../tests/mail2.guerrillamail.com.key.pem",
  231. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  232. "start_tls_on":true,
  233. "tls_always_on":false
  234. }
  235. },
  236. {
  237. "is_enabled" : true,
  238. "host_name":"secure.test.com",
  239. "max_size":1000000,
  240. "timeout":180,
  241. "listen_interface":"127.0.0.1:4655",
  242. "max_clients":200,
  243. "log_file" : "../../tests/testlog",
  244. "tls" : {
  245. "private_key_file":"../../tests/mail2.guerrillamail.com.key.pem",
  246. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  247. "start_tls_on":false,
  248. "tls_always_on":true
  249. }
  250. }
  251. ]
  252. }
  253. `
  254. // adds 127.0.0.1:4655, a secure server
  255. var configJsonE = `
  256. {
  257. "log_file" : "../../tests/testlog",
  258. "log_level" : "debug",
  259. "pid_file" : "./pidfile2.pid",
  260. "allowed_hosts": [
  261. "guerrillamail.com",
  262. "guerrillamailblock.com",
  263. "sharklasers.com",
  264. "guerrillamail.net",
  265. "guerrillamail.org"
  266. ],
  267. "backend" : {
  268. "processors" : {
  269. "debugger" : {
  270. "log_received_mails" : true
  271. },
  272. "sql" : {
  273. "sql_dsn": "root:secret@tcp(127.0.0.1:3306)/gmail_mail?readTimeout=10s&writeTimeout=10s",
  274. "mail_table":"new_mail",
  275. "sql_driver": "mysql",
  276. "primary_mail_host":"sharklasers.com"
  277. },
  278. "GuerrillaRedisDB" : {
  279. "sql_dsn": "root:secret@tcp(127.0.0.1:3306)/gmail_mail?readTimeout=10s&writeTimeout=10s",
  280. "mail_table":"new_mail",
  281. "sql_driver": "mysql",
  282. "redis_interface" : "127.0.0.1:6379",
  283. "redis_expire_seconds" : 7200,
  284. "primary_mail_host":"sharklasers.com"
  285. }
  286. },
  287. "gateways" : {
  288. "default" : {
  289. "save_workers_size" : 3,
  290. "save_process": "GuerrillaRedisDB"
  291. }
  292. }
  293. },
  294. "servers" : [
  295. {
  296. "is_enabled" : true,
  297. "host_name":"mail.test.com",
  298. "max_size": 1000000,
  299. "timeout":180,
  300. "listen_interface":"127.0.0.1:2552",
  301. "max_clients": 200,
  302. "log_file" : "../../tests/testlog",
  303. "tls" : {
  304. "private_key_file":"../../tests/mail2.guerrillamail.com.key.pem",
  305. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  306. "start_tls_on":true,
  307. "tls_always_on":false
  308. }
  309. },
  310. {
  311. "is_enabled" : true,
  312. "host_name":"secure.test.com",
  313. "max_size":1000000,
  314. "timeout":180,
  315. "listen_interface":"127.0.0.1:4655",
  316. "max_clients":200,
  317. "log_file" : "../../tests/testlog",
  318. "tls" : {
  319. "private_key_file":"../../tests/mail2.guerrillamail.com.key.pem",
  320. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  321. "start_tls_on":false,
  322. "tls_always_on":true
  323. }
  324. }
  325. ]
  326. }
  327. `
  328. const testPauseDuration = time.Millisecond * 1010
  329. // reload config
  330. func sigHup(pidfile string) {
  331. if data, err := ioutil.ReadFile(pidfile); err == nil {
  332. if pid, err := strconv.Atoi(string(data)); err != nil {
  333. mainlog.WithError(err).Error("could not read pid")
  334. } else {
  335. mainlog.Fields("pid", pid).Info("pid read")
  336. ecmd := exec.Command("kill", "-HUP", string(data))
  337. _, err = ecmd.Output()
  338. if err != nil {
  339. mainlog.WithError(err).Error("could not SIGHUP")
  340. }
  341. }
  342. } else {
  343. mainlog.Fields("error", err, "file", pidfile).Info("sighup - Could not read pidfle")
  344. }
  345. }
  346. // shutdown after calling serve()
  347. func sigKill(pidfile string) {
  348. if data, err := ioutil.ReadFile(pidfile); err == nil {
  349. if pid, err := strconv.Atoi(string(data)); err != nil {
  350. mainlog.WithError(err).Error("could not read pid")
  351. } else {
  352. mainlog.Fields("pid", pid).Info("pid read")
  353. ecmd := exec.Command("kill", string(data))
  354. _, err = ecmd.Output()
  355. if err != nil {
  356. mainlog.WithError(err).Info("could not sigkill")
  357. }
  358. }
  359. } else {
  360. mainlog.WithError(err).Info("sigKill - Could not read pidfle")
  361. }
  362. }
  363. func Round(x float64) float64 {
  364. t := math.Trunc(x)
  365. if math.Abs(x-t) >= 0.5 {
  366. return t + math.Copysign(1, x)
  367. }
  368. return t
  369. }
  370. // exponentialBackoff sleeps in nanoseconds, according to this formula 2^(i-1) * 25 / 2
  371. func exponentialBackoff(i int) {
  372. time.Sleep(time.Duration(Round(math.Pow(3.0, float64(i))-1.0)*100.0/2.0) * time.Millisecond)
  373. }
  374. func matchTestlog(startLine int, args ...interface{}) (bool, error) {
  375. fd, err := os.Open("../../tests/testlog")
  376. if err != nil {
  377. return false, err
  378. }
  379. defer func() {
  380. _ = fd.Close()
  381. }()
  382. for tries := 0; tries < 6; tries++ {
  383. if b, err := ioutil.ReadAll(fd); err != nil {
  384. return false, err
  385. } else {
  386. if test.MatchLog(string(b), startLine, args...) {
  387. return true, nil
  388. }
  389. }
  390. // close and reopen
  391. err = fd.Close()
  392. if err != nil {
  393. return false, err
  394. }
  395. fd = nil
  396. // sleep
  397. exponentialBackoff(tries)
  398. _ = mainlog.Reopen()
  399. // re-open
  400. fd, err = os.OpenFile("../../tests/testlog", os.O_RDONLY, 0644)
  401. if err != nil {
  402. return false, err
  403. }
  404. }
  405. return false, nil
  406. }
  407. var grepNotFound error
  408. // grepTestlog looks for the `match` string in the testlog
  409. // the lineNumber indicates what line to start the search from
  410. // returns line number it was found on
  411. // error otherwise
  412. //
  413. // It will attempt to search the log multiple times, pausing loner for each re-try
  414. //
  415. func grepTestlog(match string, lineNumber int) (found int, err error) {
  416. found = 0
  417. fd, err := os.Open("../../tests/testlog")
  418. if err != nil {
  419. return found, err
  420. }
  421. defer func() {
  422. _ = fd.Close()
  423. }()
  424. buff := bufio.NewReader(fd)
  425. var ln int
  426. var line string
  427. for tries := 0; tries < 6; tries++ {
  428. for {
  429. ln++
  430. line, err = buff.ReadString('\n')
  431. if err != nil {
  432. break
  433. }
  434. if ln > lineNumber {
  435. if i := strings.Index(line, match); i != -1 {
  436. return ln, nil
  437. }
  438. }
  439. }
  440. if err != io.EOF {
  441. return found, err
  442. }
  443. err = fd.Close()
  444. if err != nil {
  445. return 0, err
  446. }
  447. fd = nil
  448. // sleep
  449. exponentialBackoff(tries)
  450. _ = mainlog.Reopen()
  451. // re-open
  452. fd, err = os.OpenFile("../../tests/testlog", os.O_RDONLY, 0644)
  453. if err != nil {
  454. return found, err
  455. }
  456. buff.Reset(fd)
  457. ln = 0
  458. }
  459. grepNotFound = errors.New("could not find " + match + " in tests/testlog after line" + strconv.Itoa(lineNumber))
  460. return found, grepNotFound
  461. }
  462. // In all the tests, there will be a minimum of about 2000 available
  463. func TestFileLimit(t *testing.T) {
  464. cfg := &guerrilla.AppConfig{LogFile: log.OutputOff.String()}
  465. sc := guerrilla.ServerConfig{
  466. ListenInterface: "127.0.0.1:2526",
  467. IsEnabled: true,
  468. MaxClients: 1000,
  469. }
  470. cfg.Servers = append(cfg.Servers, sc)
  471. d := guerrilla.Daemon{Config: cfg}
  472. if ok, maxClients, fileLimit := guerrilla.CheckFileLimit(d.Config); !ok {
  473. t.Errorf("Combined max clients for all servers (%d) is greater than open file limit (%d). "+
  474. "Please increase your open file limit. Please check your OS docs for how to increase the limit.", maxClients, fileLimit)
  475. }
  476. }
  477. func getTestLog() (mainlog log.Logger, err error) {
  478. return log.GetLogger("../../tests/testlog", "debug")
  479. }
  480. func truncateIfExists(filename string) error {
  481. if _, err := os.Stat(filename); !os.IsNotExist(err) {
  482. return os.Truncate(filename, 0)
  483. }
  484. return nil
  485. }
  486. func deleteIfExists(filename string) error {
  487. if _, err := os.Stat(filename); !os.IsNotExist(err) {
  488. return os.Remove(filename)
  489. }
  490. return nil
  491. }
  492. func cleanTestArtifacts(t *testing.T) {
  493. if err := truncateIfExists("../../tests/testlog"); err != nil {
  494. t.Error("could not clean tests/testlog:", err)
  495. }
  496. if err := truncateIfExists("../../tests/testlog2"); err != nil {
  497. t.Error("could not clean tests/testlog2:", err)
  498. }
  499. letters := []byte{'A', 'B', 'C', 'D', 'E'}
  500. for _, l := range letters {
  501. if err := deleteIfExists("configJson" + string(l) + ".json"); err != nil {
  502. t.Error("could not delete configJson"+string(l)+".json:", err)
  503. }
  504. }
  505. if err := deleteIfExists("./pidfile.pid"); err != nil {
  506. t.Error("could not delete ./pidfile.pid", err)
  507. }
  508. if err := deleteIfExists("./pidfile2.pid"); err != nil {
  509. t.Error("could not delete ./pidfile2.pid", err)
  510. }
  511. if err := deleteIfExists("../../tests/mail.guerrillamail.com.cert.pem"); err != nil {
  512. t.Error("could not delete ../../tests/mail.guerrillamail.com.cert.pem", err)
  513. }
  514. if err := deleteIfExists("../../tests/mail.guerrillamail.com.key.pem"); err != nil {
  515. t.Error("could not delete ../../tests/mail.guerrillamail.com.key.pem", err)
  516. }
  517. if err := deleteIfExists("../../tests/mail2.guerrillamail.com.cert.pem"); err != nil {
  518. t.Error("could not delete ../../tests/mail2.guerrillamail.com.cert.pem", err)
  519. }
  520. if err := deleteIfExists("../../tests/mail2.guerrillamail.com.key.pem"); err != nil {
  521. t.Error("could not delete ../../tests/mail2.guerrillamail.com.key.pem", err)
  522. }
  523. }
  524. // make sure that we get all the config change events
  525. func TestCmdConfigChangeEvents(t *testing.T) {
  526. defer cleanTestArtifacts(t)
  527. var err error
  528. err = testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  529. if err != nil {
  530. t.Error("failed to generate a test certificate", err)
  531. t.FailNow()
  532. }
  533. oldconf := &guerrilla.AppConfig{}
  534. if err := oldconf.Load([]byte(configJsonA)); err != nil {
  535. t.Error("configJsonA is invalid", err)
  536. }
  537. newconf := &guerrilla.AppConfig{}
  538. if err := newconf.Load([]byte(configJsonB)); err != nil {
  539. t.Error("configJsonB is invalid", err)
  540. }
  541. newerconf := &guerrilla.AppConfig{}
  542. if err := newerconf.Load([]byte(configJsonC)); err != nil {
  543. t.Error("configJsonC is invalid", err)
  544. }
  545. expectedEvents := map[guerrilla.Event]bool{
  546. guerrilla.EventConfigBackendConfigChanged: false, // backend_change:backend
  547. guerrilla.EventConfigServerNew: false, // server_change:new_server
  548. }
  549. mainlog, err = getTestLog()
  550. if err != nil {
  551. t.Error("could not get logger,", err)
  552. t.FailNow()
  553. }
  554. oldconf.BackendConfig = backends.BackendConfig{
  555. backends.ConfigProcessors: {"debugger": {"log_received_mails": true}},
  556. }
  557. oldconf.BackendConfig.ConfigureDefaults()
  558. backend, err := backends.New(backends.DefaultGateway, oldconf.BackendConfig, mainlog)
  559. if err != nil {
  560. t.Error("failed to create backend", err)
  561. return
  562. }
  563. app, err := guerrilla.New(oldconf, mainlog, backend)
  564. if err != nil {
  565. t.Error("Failed to create new app", err)
  566. }
  567. toUnsubscribe := map[guerrilla.Event]interface{}{}
  568. for event := range expectedEvents {
  569. // Put in anon func since range is overwriting event
  570. func(e guerrilla.Event) {
  571. if strings.Index(e.String(), "backend_change") == 0 {
  572. f := func(c *guerrilla.AppConfig, gateway string) {
  573. expectedEvents[e] = true
  574. }
  575. _ = app.Subscribe(e, f)
  576. toUnsubscribe[e] = f
  577. } else if strings.Index(e.String(), "server_change") == 0 {
  578. f := func(c *guerrilla.ServerConfig) {
  579. expectedEvents[e] = true
  580. }
  581. _ = app.Subscribe(e, f)
  582. toUnsubscribe[e] = f
  583. } else {
  584. f := func(c *guerrilla.AppConfig) {
  585. expectedEvents[e] = true
  586. }
  587. _ = app.Subscribe(e, f)
  588. toUnsubscribe[e] = f
  589. }
  590. }(event)
  591. }
  592. // emit events
  593. newconf.EmitChangeEvents(oldconf, app)
  594. newerconf.EmitChangeEvents(newconf, app)
  595. // unsubscribe
  596. for unevent, unfun := range toUnsubscribe {
  597. _ = app.Unsubscribe(unevent, unfun)
  598. }
  599. for event, val := range expectedEvents {
  600. if val == false {
  601. t.Error("Did not fire config change event:", event)
  602. t.FailNow()
  603. }
  604. }
  605. }
  606. // start server, change config, send SIG HUP, confirm that the pidfile changed & backend reloaded
  607. func TestServe(t *testing.T) {
  608. defer cleanTestArtifacts(t)
  609. var err error
  610. err = testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  611. if err != nil {
  612. t.Error("failed to generate a test certificate", err)
  613. t.FailNow()
  614. }
  615. mainlog, err = getTestLog()
  616. if err != nil {
  617. t.Error("could not get logger,", err)
  618. t.FailNow()
  619. }
  620. if err := ioutil.WriteFile("configJsonA.json", []byte(configJsonA), 0644); err != nil {
  621. t.Error(err)
  622. t.FailNow()
  623. }
  624. cmd := &cobra.Command{}
  625. configPath = "configJsonA.json"
  626. go func() {
  627. serve(cmd, []string{})
  628. }()
  629. if _, err := grepTestlog("msg=\"listening on TCP\" iface=\"127.0.0.1:3536\"", 0); err != nil {
  630. t.Error("server not started")
  631. }
  632. // wait for the pidfle to be written out
  633. if _, err := grepTestlog("pid_file", 0); err != nil {
  634. t.Error("pid_file not written")
  635. }
  636. data, err := ioutil.ReadFile("pidfile.pid")
  637. if err != nil {
  638. t.Error("error reading pidfile.pid", err)
  639. t.FailNow()
  640. }
  641. _, err = strconv.Atoi(string(data))
  642. if err != nil {
  643. t.Error("could not parse pidfile.pid", err)
  644. t.FailNow()
  645. }
  646. // change the config file
  647. err = ioutil.WriteFile("configJsonA.json", []byte(configJsonB), 0644)
  648. if err != nil {
  649. t.Error(err)
  650. t.FailNow()
  651. }
  652. // test SIGHUP via the kill command
  653. // Would not work on windows as kill is not available.
  654. // TODO: Implement an alternative test for windows.
  655. if runtime.GOOS != "windows" {
  656. sigHup("pidfile.pid")
  657. // did the pidfile change as expected?
  658. if _, err := grepTestlog("configuration was reloaded", 0); err != nil {
  659. t.Error("server did not catch sighup")
  660. }
  661. }
  662. if _, err := grepTestlog("gateway with new config started", 0); err != nil {
  663. t.Error("Dummy backend not restarted")
  664. }
  665. // send kill signal and wait for exit
  666. d.Shutdown()
  667. // did backend started as expected?
  668. // wait for shutdown
  669. if _, err := grepTestlog("backend shutdown completed", 0); err != nil {
  670. t.Error("server didn't stop")
  671. }
  672. }
  673. // Start with configJsonA.json,
  674. // then add a new server to it (127.0.0.1:2526),
  675. // then SIGHUP (to reload config & trigger config update events),
  676. // then connect to it & HELO.
  677. func TestServerAddEvent(t *testing.T) {
  678. var err error
  679. err = testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  680. if err != nil {
  681. t.Error("failed to generate a test certificate", err)
  682. t.FailNow()
  683. }
  684. defer cleanTestArtifacts(t)
  685. mainlog, err = getTestLog()
  686. if err != nil {
  687. t.Error("could not get logger,", err)
  688. t.FailNow()
  689. }
  690. // start the server by emulating the serve command
  691. if err := ioutil.WriteFile("configJsonA.json", []byte(configJsonA), 0644); err != nil {
  692. t.Error(err)
  693. t.FailNow()
  694. }
  695. cmd := &cobra.Command{}
  696. configPath = "configJsonA.json"
  697. go func() {
  698. serve(cmd, []string{})
  699. }()
  700. // allow the server to start
  701. if _, err := grepTestlog("msg=\"listening on TCP\" iface=\"127.0.0.1:3536\"", 0); err != nil {
  702. t.Error("server didn't start")
  703. }
  704. // now change the config by adding a server
  705. conf := &guerrilla.AppConfig{} // blank one
  706. err = conf.Load([]byte(configJsonA)) // load configJsonA
  707. if err != nil {
  708. t.Error(err)
  709. }
  710. newServer := conf.Servers[0] // copy the first server config
  711. newServer.ListenInterface = "127.0.0.1:2526" // change it
  712. newConf := conf // copy the cmdConfg
  713. newConf.Servers = append(newConf.Servers, newServer) // add the new server
  714. if jsonbytes, err := json.Marshal(newConf); err == nil {
  715. if err := ioutil.WriteFile("configJsonA.json", jsonbytes, 0644); err != nil {
  716. t.Error(err)
  717. }
  718. }
  719. // send a sighup signal to the server
  720. sigHup("./pidfile.pid")
  721. if _, err := grepTestlog("msg=\"listening on TCP\" iface=\"127.0.0.1:2526\"", 0); err != nil {
  722. t.Error("new server didn't start")
  723. }
  724. if conn, buffin, err := test.Connect(newServer, 20); err != nil {
  725. t.Error("Could not connect to new server", newServer.ListenInterface, err)
  726. return
  727. } else {
  728. if result, err := test.Command(conn, buffin, "HELO example.com"); err == nil {
  729. expect := "250 mail.test.com Hello"
  730. if strings.Index(result, expect) != 0 {
  731. t.Error("Expected", expect, "but got", result)
  732. }
  733. } else {
  734. t.Error(err)
  735. }
  736. }
  737. // shutdown the server
  738. d.Shutdown()
  739. // sever added as as expected?
  740. if matched, err := matchTestlog(
  741. 1, "msg", "new server added",
  742. "iface", "127.0.0.1:2526",
  743. "event", "server_change:new_server",
  744. ); !matched {
  745. t.Error("Did not add server [127.0.0.1:2526] after sighup", err)
  746. }
  747. if matched, err := matchTestlog(
  748. 1, "msg", "backend shutdown completed",
  749. ); !matched {
  750. t.Error("Server failed to stop", err)
  751. }
  752. }
  753. // Start with configJsonA.json,
  754. // then change the config to enable 127.0.0.1:2228,
  755. // then write the new config,
  756. // then SIGHUP (to reload config & trigger config update events),
  757. // then connect to 127.0.0.1:2228 & HELO.
  758. func TestServerStartEvent(t *testing.T) {
  759. var err error
  760. err = testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  761. if err != nil {
  762. t.Error("failed to generate a test certificate", err)
  763. t.FailNow()
  764. }
  765. defer cleanTestArtifacts(t)
  766. mainlog, err = getTestLog()
  767. if err != nil {
  768. t.Error("could not get logger,", err)
  769. t.FailNow()
  770. }
  771. if err := ioutil.WriteFile("configJsonA.json", []byte(configJsonA), 0644); err != nil {
  772. t.Error(err)
  773. t.FailNow()
  774. }
  775. cmd := &cobra.Command{}
  776. configPath = "configJsonA.json"
  777. go func() {
  778. serve(cmd, []string{})
  779. }()
  780. if _, err := grepTestlog("msg=\"listening on TCP\" iface=\"127.0.0.1:3536\"", 0); err != nil {
  781. t.Error("server didn't start")
  782. }
  783. // now change the config by adding a server
  784. conf := &guerrilla.AppConfig{} // blank one
  785. if err = conf.Load([]byte(configJsonA)); err != nil { // load configJsonA
  786. t.Error(err)
  787. }
  788. newConf := conf // copy the cmdConfg
  789. newConf.Servers[1].IsEnabled = true
  790. if jsonbytes, err := json.Marshal(newConf); err == nil {
  791. //fmt.Println(string(jsonbytes))
  792. if err = ioutil.WriteFile("configJsonA.json", jsonbytes, 0644); err != nil {
  793. t.Error(err)
  794. }
  795. } else {
  796. t.Error(err)
  797. }
  798. // send a sighup signal to the server
  799. sigHup("pidfile.pid")
  800. // see if the new server started?
  801. if _, err := grepTestlog("msg=\"listening on TCP\" iface=\"127.0.0.1:2228\"", 0); err != nil {
  802. t.Error("second server didn't start")
  803. }
  804. // can we talk to it?
  805. if conn, buffin, err := test.Connect(newConf.Servers[1], 20); err != nil {
  806. t.Error("Could not connect to new server", newConf.Servers[1].ListenInterface)
  807. } else {
  808. if result, err := test.Command(conn, buffin, "HELO example.com"); err == nil {
  809. expect := "250 enable.test.com Hello"
  810. if strings.Index(result, expect) != 0 {
  811. t.Error("Expected", expect, "but got", result)
  812. }
  813. } else {
  814. t.Error(err)
  815. }
  816. }
  817. // shutdown and wait for exit
  818. d.Shutdown()
  819. if _, err := grepTestlog("backend shutdown completed", 0); err != nil {
  820. t.Error("server didn't stop")
  821. }
  822. }
  823. // Start with configJsonA.json,
  824. // then change the config to enable 127.0.0.1:2228,
  825. // then write the new config,
  826. // then SIGHUP (to reload config & trigger config update events),
  827. // then connect to 127.0.0.1:2228 & HELO.
  828. // then change the config to dsiable 127.0.0.1:2228,
  829. // then SIGHUP (to reload config & trigger config update events),
  830. // then connect to 127.0.0.1:2228 - it should not connect
  831. func TestServerStopEvent(t *testing.T) {
  832. var err error
  833. err = testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  834. if err != nil {
  835. t.Error("failed to generate a test certificate", err)
  836. t.FailNow()
  837. }
  838. defer cleanTestArtifacts(t)
  839. mainlog, err = getTestLog()
  840. if err != nil {
  841. t.Error("could not get logger,", err)
  842. t.FailNow()
  843. }
  844. if err := ioutil.WriteFile("configJsonA.json", []byte(configJsonA), 0644); err != nil {
  845. t.Error(err)
  846. t.FailNow()
  847. }
  848. cmd := &cobra.Command{}
  849. configPath = "configJsonA.json"
  850. go func() {
  851. serve(cmd, []string{})
  852. }()
  853. // allow the server to start
  854. if _, err := grepTestlog("msg=\"listening on TCP\" iface=\"127.0.0.1:3536\"", 0); err != nil {
  855. t.Error("server didn't start")
  856. }
  857. // now change the config by enabling a server
  858. conf := &guerrilla.AppConfig{} // blank one
  859. if err = conf.Load([]byte(configJsonA)); err != nil { // load configJsonA
  860. t.Error(err)
  861. }
  862. newConf := conf // copy the cmdConfg
  863. newConf.Servers[1].IsEnabled = true // enable 2nd server
  864. if jsonbytes, err := json.Marshal(newConf); err == nil {
  865. //fmt.Println(string(jsonbytes))
  866. if err = ioutil.WriteFile("configJsonA.json", jsonbytes, 0644); err != nil {
  867. t.Error(err)
  868. }
  869. } else {
  870. t.Error(err)
  871. }
  872. // send a sighup signal to the server
  873. sigHup("pidfile.pid")
  874. // detect config change
  875. if _, err := grepTestlog("msg=\"listening on TCP\" iface=\"127.0.0.1:2228\"", 0); err != nil {
  876. t.Error("new server didn't start")
  877. }
  878. if conn, buffin, err := test.Connect(newConf.Servers[1], 20); err != nil {
  879. t.Error("Could not connect to new server", newConf.Servers[1].ListenInterface)
  880. } else {
  881. if result, err := test.Command(conn, buffin, "HELO example.com"); err == nil {
  882. expect := "250 enable.test.com Hello"
  883. if strings.Index(result, expect) != 0 {
  884. t.Error("Expected", expect, "but got", result)
  885. }
  886. } else {
  887. t.Error(err)
  888. }
  889. if err = conn.Close(); err != nil {
  890. t.Error(err)
  891. }
  892. }
  893. // now disable the server
  894. newerConf := newConf // copy the cmdConfg
  895. newerConf.Servers[1].IsEnabled = false
  896. if jsonbytes, err := json.Marshal(newerConf); err == nil {
  897. //fmt.Println(string(jsonbytes))
  898. if err = ioutil.WriteFile("configJsonA.json", jsonbytes, 0644); err != nil {
  899. t.Error(err)
  900. }
  901. } else {
  902. t.Error(err)
  903. }
  904. // send a sighup signal to the server
  905. sigHup("pidfile.pid")
  906. // detect config change
  907. if _, err := grepTestlog("msg=\"server has stopped accepting new clients\" iface=\"127.0.0.1:2228\"", 27); err != nil {
  908. t.Error("127.0.0.1:2228 did not stop")
  909. }
  910. // it should not connect to the server
  911. if _, _, err := test.Connect(newConf.Servers[1], 20); err == nil {
  912. t.Error("127.0.0.1:2228 was disabled, but still accepting connections", newConf.Servers[1].ListenInterface)
  913. }
  914. // shutdown wait for exit
  915. d.Shutdown()
  916. // wait for shutdown
  917. if _, err := grepTestlog("backend shutdown completed", 0); err != nil {
  918. t.Error("server didn't stop")
  919. }
  920. }
  921. // just a utility for debugging when using the debugger, skipped by default
  922. func TestDebug(t *testing.T) {
  923. t.SkipNow()
  924. conf := guerrilla.ServerConfig{ListenInterface: "127.0.0.1:2526"}
  925. if conn, buffin, err := test.Connect(conf, 20); err != nil {
  926. t.Error("Could not connect to new server", conf.ListenInterface, err)
  927. } else {
  928. if result, err := test.Command(conn, buffin, "HELO"); err == nil {
  929. expect := "250 mai1.guerrillamail.com Hello"
  930. if strings.Index(result, expect) != 0 {
  931. t.Error("Expected", expect, "but got", result)
  932. } else {
  933. if result, err = test.Command(conn, buffin, "RCPT TO:<[email protected]>"); err == nil {
  934. expect := "250 2.1.5 OK"
  935. if strings.Index(result, expect) != 0 {
  936. t.Error("Expected:", expect, "but got:", result)
  937. }
  938. }
  939. }
  940. }
  941. _ = conn.Close()
  942. }
  943. }
  944. // Start with configJsonD.json,
  945. // then connect to 127.0.0.1:4655 & HELO & try RCPT TO with an invalid host [grr.la]
  946. // then change the config to enable add new host [grr.la] to allowed_hosts
  947. // then write the new config,
  948. // then SIGHUP (to reload config & trigger config update events),
  949. // connect to 127.0.0.1:4655 & HELO & try RCPT TO, grr.la should work
  950. func TestAllowedHostsEvent(t *testing.T) {
  951. var err error
  952. err = testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  953. if err != nil {
  954. t.Error("failed to generate a test certificate", err)
  955. t.FailNow()
  956. }
  957. defer cleanTestArtifacts(t)
  958. mainlog, err = getTestLog()
  959. if err != nil {
  960. t.Error("could not get logger,", err)
  961. t.FailNow()
  962. }
  963. if err := ioutil.WriteFile("configJsonD.json", []byte(configJsonD), 0644); err != nil {
  964. t.Error(err)
  965. t.FailNow()
  966. }
  967. // start the server by emulating the serve command
  968. conf := &guerrilla.AppConfig{} // blank one
  969. if err = conf.Load([]byte(configJsonD)); err != nil { // load configJsonD
  970. t.Error(err)
  971. }
  972. cmd := &cobra.Command{}
  973. configPath = "configJsonD.json"
  974. go func() {
  975. serve(cmd, []string{})
  976. }()
  977. // wait for start
  978. if _, err := grepTestlog("msg=\"listening on TCP\" iface=\"127.0.0.1:2552\"", 0); err != nil {
  979. t.Error("server didn't start")
  980. }
  981. // now connect and try RCPT TO with an invalid host
  982. if conn, buffin, err := test.Connect(conf.Servers[1], 20); err != nil {
  983. t.Error("Could not connect to new server", conf.Servers[1].ListenInterface, err)
  984. } else {
  985. if result, err := test.Command(conn, buffin, "HELO example.com"); err == nil {
  986. expect := "250 secure.test.com Hello"
  987. if strings.Index(result, expect) != 0 {
  988. t.Error("Expected", expect, "but got", result)
  989. } else {
  990. if result, err = test.Command(conn, buffin, "RCPT TO:<[email protected]>"); err == nil {
  991. expect := "454 4.1.1 Error: Relay access denied: grr.la"
  992. if strings.Index(result, expect) != 0 {
  993. t.Error("Expected:", expect, "but got:", result)
  994. }
  995. }
  996. }
  997. }
  998. _ = conn.Close()
  999. }
  1000. // now change the config by adding a host to allowed hosts
  1001. newConf := conf
  1002. newConf.AllowedHosts = append(newConf.AllowedHosts, "grr.la")
  1003. if jsonbytes, err := json.Marshal(newConf); err == nil {
  1004. if err = ioutil.WriteFile("configJsonD.json", jsonbytes, 0644); err != nil {
  1005. t.Error(err)
  1006. }
  1007. } else {
  1008. t.Error(err)
  1009. }
  1010. // send a sighup signal to the server to reload config
  1011. sigHup("pidfile.pid")
  1012. if _, err := grepTestlog("allowed_hosts config changed", 0); err != nil {
  1013. t.Error("allowed_hosts config not changed")
  1014. t.FailNow()
  1015. }
  1016. // now repeat the same conversion, RCPT TO should be accepted
  1017. if conn, buffin, err := test.Connect(conf.Servers[1], 20); err != nil {
  1018. t.Error("Could not connect to new server", conf.Servers[1].ListenInterface, err)
  1019. } else {
  1020. if result, err := test.Command(conn, buffin, "HELO example.com"); err == nil {
  1021. expect := "250 secure.test.com Hello"
  1022. if strings.Index(result, expect) != 0 {
  1023. t.Error("Expected", expect, "but got", result)
  1024. } else {
  1025. if result, err = test.Command(conn, buffin, "RCPT TO:<[email protected]>"); err == nil {
  1026. expect := "250 2.1.5 OK"
  1027. if strings.Index(result, expect) != 0 {
  1028. t.Error("Expected:", expect, "but got:", result)
  1029. }
  1030. }
  1031. }
  1032. }
  1033. _ = conn.Close()
  1034. }
  1035. // shutdown wait for exit
  1036. d.Shutdown()
  1037. // wait for shutdown
  1038. if _, err := grepTestlog("backend shutdown completed", 0); err != nil {
  1039. t.Error("server didn't stop")
  1040. }
  1041. }
  1042. // Test TLS config change event
  1043. // start with configJsonD
  1044. // should be able to STARTTLS to 127.0.0.1:2525 with no problems
  1045. // generate new certs & reload config
  1046. // should get a new tls event & able to STARTTLS with no problem
  1047. func TestTLSConfigEvent(t *testing.T) {
  1048. var err error
  1049. err = testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  1050. if err != nil {
  1051. t.Error("failed to generate a test certificate", err)
  1052. t.FailNow()
  1053. }
  1054. defer cleanTestArtifacts(t)
  1055. mainlog, err = getTestLog()
  1056. if err != nil {
  1057. t.Error("could not get logger,", err)
  1058. t.FailNow()
  1059. }
  1060. if err := ioutil.WriteFile("configJsonD.json", []byte(configJsonD), 0644); err != nil {
  1061. t.Error(err)
  1062. t.FailNow()
  1063. }
  1064. conf := &guerrilla.AppConfig{} // blank one
  1065. if err = conf.Load([]byte(configJsonD)); err != nil { // load configJsonD
  1066. t.Error(err)
  1067. t.FailNow()
  1068. }
  1069. cmd := &cobra.Command{}
  1070. configPath = "configJsonD.json"
  1071. go func() {
  1072. serve(cmd, []string{})
  1073. }()
  1074. // wait for server to start
  1075. if _, err := grepTestlog("msg=\"listening on TCP\" iface=\"127.0.0.1:2552\"", 0); err != nil {
  1076. t.Error("server didn't start")
  1077. }
  1078. // Test STARTTLS handshake
  1079. testTlsHandshake := func() {
  1080. if conn, buffin, err := test.Connect(conf.Servers[0], 20); err != nil {
  1081. t.Error("Could not connect to server", conf.Servers[0].ListenInterface, err)
  1082. } else {
  1083. if result, err := test.Command(conn, buffin, "HELO example.com"); err == nil {
  1084. expect := "250 mail.test.com Hello"
  1085. if strings.Index(result, expect) != 0 {
  1086. t.Error("Expected", expect, "but got", result)
  1087. } else {
  1088. if result, err = test.Command(conn, buffin, "STARTTLS"); err == nil {
  1089. expect := "220 2.0.0 Ready to start TLS"
  1090. if strings.Index(result, expect) != 0 {
  1091. t.Error("Expected:", expect, "but got:", result)
  1092. } else {
  1093. tlsConn := tls.Client(conn, &tls.Config{
  1094. InsecureSkipVerify: true,
  1095. ServerName: "127.0.0.1",
  1096. })
  1097. if err := tlsConn.Handshake(); err != nil {
  1098. t.Error("Failed to handshake", conf.Servers[0].ListenInterface)
  1099. } else {
  1100. conn = tlsConn
  1101. mainlog.Info("TLS Handshake succeeded")
  1102. }
  1103. }
  1104. }
  1105. }
  1106. }
  1107. _ = conn.Close()
  1108. }
  1109. }
  1110. testTlsHandshake()
  1111. // TLS Handshake succeeded?
  1112. if _, err := grepTestlog("TLS Handshake succeeded", 0); err != nil {
  1113. t.Error("TLS Handshake did not succeed")
  1114. t.FailNow()
  1115. }
  1116. // now delete old certs, configure new certs, and send a sighup to load them in
  1117. if err := deleteIfExists("../../tests/mail2.guerrillamail.com.cert.pem"); err != nil {
  1118. t.Error("could not delete ../../tests/mail2.guerrillamail.com.cert.pem", err)
  1119. }
  1120. if err := deleteIfExists("../../tests/mail2.guerrillamail.com.key.pem"); err != nil {
  1121. t.Error("could not delete ../../tests/mail2.guerrillamail.com.key.pem", err)
  1122. }
  1123. time.Sleep(testPauseDuration) // need to pause so that the new certs have different timestamps!
  1124. // generate a new cert
  1125. err = testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  1126. if err != nil {
  1127. t.Error("failed to generate a test certificate", err)
  1128. t.FailNow()
  1129. }
  1130. // pause for generated cert to output (don't need, since we've fsynced)
  1131. // time.Sleep(testPauseDuration) // (don't need, since we've fsynced)
  1132. // did cert output?
  1133. if _, err := os.Stat("../../tests/mail2.guerrillamail.com.cert.pem"); err != nil {
  1134. t.Error("Did not create cert ", err)
  1135. }
  1136. sigHup("pidfile.pid")
  1137. // wait for config to reload
  1138. if _, err := matchTestlog(1, "iface", "127.0.0.1:4655", "msg", "server re-opened"); err != nil {
  1139. t.Error("server didn't catch sighup")
  1140. }
  1141. // did tls configuration reload as expected?
  1142. if _, err := grepTestlog("new TLS configuration loaded", 0); err != nil {
  1143. t.Error("server didn't catch sighup")
  1144. }
  1145. // test again
  1146. testTlsHandshake()
  1147. // after line 25
  1148. if _, err := grepTestlog("TLS Handshake succeeded", 25); err != nil {
  1149. t.Error("TLS Handshake did not succeed")
  1150. t.FailNow()
  1151. }
  1152. d.Shutdown()
  1153. // wait for shutdown
  1154. if _, err := grepTestlog("backend shutdown completed", 0); err != nil {
  1155. t.Error("server didn't stop")
  1156. }
  1157. }
  1158. // Testing starting a server with a bad TLS config
  1159. // It should not start, return exit code 1
  1160. func TestBadTLSStart(t *testing.T) {
  1161. var err error
  1162. mainlog, err = getTestLog()
  1163. if err != nil {
  1164. t.Error("could not get logger,", err)
  1165. t.FailNow()
  1166. }
  1167. // Need to run the test in a different process by executing a command
  1168. // because the serve() does os.Exit when starting with a bad TLS config
  1169. if os.Getenv("BE_CRASHER") == "1" {
  1170. // do the test
  1171. // first, remove the good certs, if any
  1172. if err := deleteIfExists("../../tests/mail2.guerrillamail.com.cert.pem"); err != nil {
  1173. t.Error("could not delete ../../tests/mail2.guerrillamail.com.cert.pem", err)
  1174. }
  1175. if err := deleteIfExists("../../tests/mail2.guerrillamail.com.key.pem"); err != nil {
  1176. t.Error("could not delete ../../tests/mail2.guerrillamail.com.key.pem", err)
  1177. }
  1178. // next run the server
  1179. if err = ioutil.WriteFile("configJsonD.json", []byte(configJsonD), 0644); err != nil {
  1180. t.Error(err)
  1181. }
  1182. conf := &guerrilla.AppConfig{} // blank one
  1183. if err = conf.Load([]byte(configJsonD)); err != nil { // load configJsonD
  1184. t.Error(err)
  1185. }
  1186. cmd := &cobra.Command{}
  1187. configPath = "configJsonD.json"
  1188. var serveWG sync.WaitGroup
  1189. serveWG.Add(1)
  1190. go func() {
  1191. serve(cmd, []string{})
  1192. serveWG.Done()
  1193. }()
  1194. // it should exit by now because the TLS config is incorrect
  1195. time.Sleep(testPauseDuration)
  1196. sigKill("pidfile.pid")
  1197. serveWG.Wait()
  1198. return
  1199. }
  1200. defer cleanTestArtifacts(t)
  1201. cmd := exec.Command(os.Args[0], "-test.run=TestBadTLSStart")
  1202. cmd.Env = append(os.Environ(), "BE_CRASHER=1")
  1203. err = cmd.Run()
  1204. if e, ok := err.(*exec.ExitError); ok && !e.Success() {
  1205. if _, err := grepTestlog("level=fatal", 0); err != nil {
  1206. t.Error("server didn't exit with a fatal error")
  1207. }
  1208. return
  1209. }
  1210. t.Error("Server started with a bad TLS config, was expecting exit status 0")
  1211. }
  1212. // Test config reload with a bad TLS config
  1213. // It should ignore the config reload, keep running with old settings
  1214. func TestBadTLSReload(t *testing.T) {
  1215. var err error
  1216. mainlog, err = getTestLog()
  1217. if err != nil {
  1218. t.Error("could not get logger,", err)
  1219. t.FailNow()
  1220. }
  1221. defer cleanTestArtifacts(t)
  1222. // start with a good cert
  1223. err = testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  1224. if err != nil {
  1225. t.Error("failed to generate a test certificate", err)
  1226. t.FailNow()
  1227. }
  1228. // start the server by emulating the serve command
  1229. if err = ioutil.WriteFile("configJsonD.json", []byte(configJsonD), 0644); err != nil {
  1230. t.Error(err)
  1231. t.FailNow()
  1232. }
  1233. conf := &guerrilla.AppConfig{} // blank one
  1234. if err = conf.Load([]byte(configJsonD)); err != nil { // load configJsonD
  1235. t.Error(err)
  1236. t.FailNow()
  1237. }
  1238. cmd := &cobra.Command{}
  1239. configPath = "configJsonD.json"
  1240. go func() {
  1241. serve(cmd, []string{})
  1242. }()
  1243. // wait for server to start
  1244. if _, err := grepTestlog("msg=\"listening on TCP\" iface=\"127.0.0.1:4655\"", 0); err != nil {
  1245. t.Error("server didn't start")
  1246. }
  1247. if conn, buffin, err := test.Connect(conf.Servers[0], 20); err != nil {
  1248. t.Error("Could not connect to server", conf.Servers[0].ListenInterface, err)
  1249. } else {
  1250. if result, err := test.Command(conn, buffin, "HELO example.com"); err == nil {
  1251. expect := "250 mail.test.com Hello"
  1252. if strings.Index(result, expect) != 0 {
  1253. t.Error("Expected", expect, "but got", result)
  1254. }
  1255. }
  1256. }
  1257. // write some trash data
  1258. if err = ioutil.WriteFile("./../../tests/mail2.guerrillamail.com.cert.pem",
  1259. []byte("trash data"),
  1260. 0664); err != nil {
  1261. t.Error(err)
  1262. }
  1263. if err = ioutil.WriteFile("./../../tests/mail2.guerrillamail.com.key.pem",
  1264. []byte("trash data"),
  1265. 0664); err != nil {
  1266. t.Error(err)
  1267. }
  1268. newConf := conf // copy the cmdConfg
  1269. if jsonbytes, err := json.Marshal(newConf); err == nil {
  1270. if err = ioutil.WriteFile("configJsonD.json", jsonbytes, 0644); err != nil {
  1271. t.Error(err)
  1272. }
  1273. } else {
  1274. t.Error(err)
  1275. }
  1276. // send a sighup signal to the server to reload config
  1277. sigHup("pidfile.pid")
  1278. // did the config reload reload event fire? There should be config read error
  1279. if _, err := grepTestlog("could not read config file", 0); err != nil {
  1280. t.Error("was expecting an error reading config")
  1281. }
  1282. // we should still be able to to talk to it
  1283. if conn, buffin, err := test.Connect(conf.Servers[0], 20); err != nil {
  1284. t.Error("Could not connect to server", conf.Servers[0].ListenInterface, err)
  1285. } else {
  1286. if result, err := test.Command(conn, buffin, "HELO example.com"); err == nil {
  1287. expect := "250 mail.test.com Hello"
  1288. if strings.Index(result, expect) != 0 {
  1289. t.Error("Expected", expect, "but got", result)
  1290. }
  1291. }
  1292. }
  1293. // shutdown & wait for exit
  1294. d.Shutdown()
  1295. // wait for shutdown
  1296. if _, err := grepTestlog("backend shutdown completed", 0); err != nil {
  1297. t.Error("server didn't stop")
  1298. }
  1299. }
  1300. // Test for when the server config Timeout value changes
  1301. // Start with configJsonD.json
  1302. func TestSetTimeoutEvent(t *testing.T) {
  1303. var err error
  1304. mainlog, err = getTestLog()
  1305. if err != nil {
  1306. t.Error("could not get logger,", err)
  1307. t.FailNow()
  1308. }
  1309. defer cleanTestArtifacts(t)
  1310. err = testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  1311. if err != nil {
  1312. t.Error("failed to generate a test certificate", err)
  1313. t.FailNow()
  1314. }
  1315. // start the server by emulating the serve command
  1316. if err = ioutil.WriteFile("configJsonD.json", []byte(configJsonD), 0644); err != nil {
  1317. t.Error(err)
  1318. }
  1319. conf := &guerrilla.AppConfig{} // blank one
  1320. if err = conf.Load([]byte(configJsonD)); err != nil { // load configJsonD
  1321. t.Error(err)
  1322. }
  1323. cmd := &cobra.Command{}
  1324. configPath = "configJsonD.json"
  1325. go func() {
  1326. serve(cmd, []string{})
  1327. }()
  1328. // wait for start
  1329. if _, err := grepTestlog("msg=\"listening on TCP\" iface=\"127.0.0.1:4655\"", 0); err != nil {
  1330. t.Error("server didn't start")
  1331. }
  1332. // set the timeout to 1 second
  1333. newConf := conf // copy the cmdConfg
  1334. newConf.Servers[0].Timeout = 1
  1335. if jsonbytes, err := json.Marshal(newConf); err == nil {
  1336. if err = ioutil.WriteFile("configJsonD.json", jsonbytes, 0644); err != nil {
  1337. t.Error(err)
  1338. }
  1339. } else {
  1340. t.Error(err)
  1341. }
  1342. // send a sighup signal to the server to reload config
  1343. sigHup("pidfile.pid")
  1344. // did config update?
  1345. if _, err := grepTestlog("a new config has been saved", 0); err != nil {
  1346. t.Error("config didn't update")
  1347. }
  1348. var waitTimeout sync.WaitGroup
  1349. if conn, buffin, err := test.Connect(conf.Servers[0], 20); err != nil {
  1350. t.Error("Could not connect to server", conf.Servers[0].ListenInterface, err)
  1351. } else {
  1352. waitTimeout.Add(1)
  1353. go func() {
  1354. if result, err := test.Command(conn, buffin, "HELO example.com"); err == nil {
  1355. expect := "250 mail.test.com Hello"
  1356. if strings.Index(result, expect) != 0 {
  1357. t.Error("Expected", expect, "but got", result)
  1358. } else {
  1359. b := make([]byte, 1024)
  1360. _, _ = conn.Read(b)
  1361. }
  1362. }
  1363. waitTimeout.Done()
  1364. }()
  1365. }
  1366. // wait for timeout
  1367. waitTimeout.Wait()
  1368. d.Shutdown()
  1369. // wait for shutdown
  1370. if _, err := grepTestlog("backend shutdown completed", 0); err != nil {
  1371. t.Error("server didn't stop")
  1372. }
  1373. // so the connection we have opened should timeout by now
  1374. // did we get timeout as expected?
  1375. if _, err := grepTestlog("i/o timeout", 0); err != nil {
  1376. t.Error("it looks like the timeout config didnt change")
  1377. t.FailNow()
  1378. }
  1379. }
  1380. // Test debug level config change
  1381. // Start in log_level = debug
  1382. // Load config & start server
  1383. func TestDebugLevelChange(t *testing.T) {
  1384. var err error
  1385. mainlog, err = getTestLog()
  1386. if err != nil {
  1387. t.Error("could not get logger,", err)
  1388. t.FailNow()
  1389. }
  1390. defer cleanTestArtifacts(t)
  1391. err = testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  1392. if err != nil {
  1393. t.Error("failed to generate a test certificate", err)
  1394. t.FailNow()
  1395. } // start the server by emulating the serve command
  1396. if err = ioutil.WriteFile("configJsonD.json", []byte(configJsonD), 0644); err != nil {
  1397. t.Error(err)
  1398. }
  1399. conf := &guerrilla.AppConfig{} // blank one
  1400. if err = conf.Load([]byte(configJsonD)); err != nil { // load configJsonD
  1401. t.Error(err)
  1402. }
  1403. conf.LogLevel = "debug"
  1404. cmd := &cobra.Command{}
  1405. configPath = "configJsonD.json"
  1406. go func() {
  1407. serve(cmd, []string{})
  1408. }()
  1409. if _, err := grepTestlog("msg=\"listening on TCP\" iface=\"127.0.0.1:2552\"", 0); err != nil {
  1410. t.Error("server didn't start")
  1411. }
  1412. if conn, buffin, err := test.Connect(conf.Servers[0], 20); err != nil {
  1413. t.Error("Could not connect to server", conf.Servers[0].ListenInterface, err)
  1414. } else {
  1415. if result, err := test.Command(conn, buffin, "HELO example.com"); err == nil {
  1416. expect := "250 mail.test.com Hello"
  1417. if strings.Index(result, expect) != 0 {
  1418. t.Error("Expected", expect, "but got", result)
  1419. }
  1420. }
  1421. _ = conn.Close()
  1422. }
  1423. // set the log_level to info
  1424. newConf := conf // copy the cmdConfg
  1425. newConf.LogLevel = log.InfoLevel.String()
  1426. if jsonbytes, err := json.Marshal(newConf); err == nil {
  1427. if err = ioutil.WriteFile("configJsonD.json", jsonbytes, 0644); err != nil {
  1428. t.Error(err)
  1429. }
  1430. } else {
  1431. t.Error(err)
  1432. }
  1433. // send a sighup signal to the server to reload config
  1434. sigHup("pidfile.pid")
  1435. // did the config reload?
  1436. if _, err := grepTestlog("configuration was reloaded", 0); err != nil {
  1437. t.Error("config did not reload")
  1438. t.FailNow()
  1439. }
  1440. // connect again, this time we should see info
  1441. if conn, buffin, err := test.Connect(conf.Servers[0], 20); err != nil {
  1442. t.Error("Could not connect to server", conf.Servers[0].ListenInterface, err)
  1443. } else {
  1444. if result, err := test.Command(conn, buffin, "NOOP"); err == nil {
  1445. expect := "200 2.0.0 OK"
  1446. if strings.Index(result, expect) != 0 {
  1447. t.Error("Expected", expect, "but got", result)
  1448. }
  1449. }
  1450. _ = conn.Close()
  1451. }
  1452. d.Shutdown()
  1453. if ok, err := matchTestlog(1, "msg", "log level changed"); !ok {
  1454. t.Error("log level did not change", err)
  1455. t.FailNow()
  1456. }
  1457. }
  1458. // When reloading with a bad backend config, it should revert to old backend config
  1459. // using the API way
  1460. func TestBadBackendReload(t *testing.T) {
  1461. defer cleanTestArtifacts(t)
  1462. var err error
  1463. err = testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  1464. if err != nil {
  1465. t.Error("failed to generate a test certificate", err)
  1466. t.FailNow()
  1467. }
  1468. if err = ioutil.WriteFile("configJsonA.json", []byte(configJsonA), 0644); err != nil {
  1469. t.Error(err)
  1470. }
  1471. d := guerrilla.Daemon{}
  1472. _, err = d.LoadConfig("configJsonA.json")
  1473. if err != nil {
  1474. t.Error("ReadConfig error", err)
  1475. return
  1476. }
  1477. err = d.Start()
  1478. if err != nil {
  1479. t.Error("start error", err)
  1480. return
  1481. } else {
  1482. if err = ioutil.WriteFile("configJsonA.json", []byte(configJsonE), 0644); err != nil {
  1483. t.Error(err)
  1484. return
  1485. }
  1486. if err = d.ReloadConfigFile("configJsonA.json"); err != nil {
  1487. t.Error(err)
  1488. return
  1489. }
  1490. d.Shutdown()
  1491. if _, err := grepTestlog("configuration was reloaded", 0); err != nil {
  1492. t.Error("config didn't update")
  1493. }
  1494. // reverted to old gateway config?
  1495. if _, err := grepTestlog("reverted to old gateway config", 0); err != nil {
  1496. t.Error("Did not revert to old gateway config")
  1497. }
  1498. // did the pidfile change as expected?
  1499. if _, err := grepTestlog("msg=\"pid_file written\" file=./pidfile2.pid", 0); err != nil {
  1500. t.Error("pid_file (./pidfile2.pid) not written")
  1501. }
  1502. if _, err := os.Stat("./pidfile2.pid"); os.IsNotExist(err) {
  1503. t.Error("pidfile not changed after sighup SIGHUP", err)
  1504. }
  1505. }
  1506. }