serve_test.go 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212
  1. package main
  2. import (
  3. "crypto/tls"
  4. "encoding/json"
  5. "io/ioutil"
  6. "os"
  7. "os/exec"
  8. "runtime"
  9. "strconv"
  10. "strings"
  11. "sync"
  12. "testing"
  13. "time"
  14. "github.com/flashmob/go-guerrilla"
  15. "github.com/flashmob/go-guerrilla/backends"
  16. "github.com/flashmob/go-guerrilla/log"
  17. test "github.com/flashmob/go-guerrilla/tests"
  18. "github.com/flashmob/go-guerrilla/tests/testcert"
  19. "github.com/spf13/cobra"
  20. )
  21. var configJsonA = `
  22. {
  23. "log_file" : "../../tests/testlog",
  24. "log_level" : "debug",
  25. "pid_file" : "./pidfile.pid",
  26. "allowed_hosts": [
  27. "guerrillamail.com",
  28. "guerrillamailblock.com",
  29. "sharklasers.com",
  30. "guerrillamail.net",
  31. "guerrillamail.org"
  32. ],
  33. "backend_config": {
  34. "save_workers_size" : 1,
  35. "save_process": "HeadersParser|Debugger",
  36. "log_received_mails": true
  37. },
  38. "servers" : [
  39. {
  40. "is_enabled" : true,
  41. "host_name":"mail.test.com",
  42. "max_size": 1000000,
  43. "private_key_file":"../..//tests/mail2.guerrillamail.com.key.pem",
  44. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  45. "timeout":180,
  46. "listen_interface":"127.0.0.1:3536",
  47. "start_tls_on":true,
  48. "tls_always_on":false,
  49. "max_clients": 1000,
  50. "log_file" : "../../tests/testlog"
  51. },
  52. {
  53. "is_enabled" : false,
  54. "host_name":"enable.test.com",
  55. "max_size": 1000000,
  56. "private_key_file":"../..//tests/mail2.guerrillamail.com.key.pem",
  57. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  58. "timeout":180,
  59. "listen_interface":"127.0.0.1:2228",
  60. "start_tls_on":true,
  61. "tls_always_on":false,
  62. "max_clients": 1000,
  63. "log_file" : "../../tests/testlog"
  64. }
  65. ]
  66. }
  67. `
  68. // backend config changed, log_received_mails is false
  69. var configJsonB = `
  70. {
  71. "log_file" : "../../tests/testlog",
  72. "log_level" : "debug",
  73. "pid_file" : "./pidfile2.pid",
  74. "allowed_hosts": [
  75. "guerrillamail.com",
  76. "guerrillamailblock.com",
  77. "sharklasers.com",
  78. "guerrillamail.net",
  79. "guerrillamail.org"
  80. ],
  81. "backend_config": {
  82. "save_workers_size" : 1,
  83. "save_process": "HeadersParser|Debugger",
  84. "log_received_mails": false
  85. },
  86. "servers" : [
  87. {
  88. "is_enabled" : true,
  89. "host_name":"mail.test.com",
  90. "max_size": 1000000,
  91. "private_key_file":"../..//tests/mail2.guerrillamail.com.key.pem",
  92. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  93. "timeout":180,
  94. "listen_interface":"127.0.0.1:3536",
  95. "start_tls_on":true,
  96. "tls_always_on":false,
  97. "max_clients": 1000,
  98. "log_file" : "../../tests/testlog"
  99. }
  100. ]
  101. }
  102. `
  103. // backend_name changed, is guerrilla-redis-db + added a server
  104. var configJsonC = `
  105. {
  106. "log_file" : "../../tests/testlog",
  107. "log_level" : "debug",
  108. "pid_file" : "./pidfile.pid",
  109. "allowed_hosts": [
  110. "guerrillamail.com",
  111. "guerrillamailblock.com",
  112. "sharklasers.com",
  113. "guerrillamail.net",
  114. "guerrillamail.org"
  115. ],
  116. "backend_name": "guerrilla-redis-db",
  117. "backend_config" :
  118. {
  119. "sql_driver": "mysql",
  120. "sql_dsn": "root:ok@tcp(127.0.0.1:3306)/gmail_mail?readTimeout=10&writeTimeout=10",
  121. "mail_table":"new_mail",
  122. "redis_interface" : "127.0.0.1:6379",
  123. "redis_expire_seconds" : 7200,
  124. "save_workers_size" : 3,
  125. "primary_mail_host":"sharklasers.com",
  126. "save_workers_size" : 1,
  127. "save_process": "HeadersParser|Debugger",
  128. "log_received_mails": true
  129. },
  130. "servers" : [
  131. {
  132. "is_enabled" : true,
  133. "host_name":"mail.test.com",
  134. "max_size": 1000000,
  135. "private_key_file":"../..//tests/mail2.guerrillamail.com.key.pem",
  136. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  137. "timeout":180,
  138. "listen_interface":"127.0.0.1:25",
  139. "start_tls_on":true,
  140. "tls_always_on":false,
  141. "max_clients": 1000,
  142. "log_file" : "../../tests/testlog"
  143. },
  144. {
  145. "is_enabled" : true,
  146. "host_name":"mail.test.com",
  147. "max_size":1000000,
  148. "private_key_file":"../..//tests/mail2.guerrillamail.com.key.pem",
  149. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  150. "timeout":180,
  151. "listen_interface":"127.0.0.1:465",
  152. "start_tls_on":false,
  153. "tls_always_on":true,
  154. "max_clients":500,
  155. "log_file" : "../../tests/testlog"
  156. }
  157. ]
  158. }
  159. `
  160. // adds 127.0.0.1:4655, a secure server
  161. var configJsonD = `
  162. {
  163. "log_file" : "../../tests/testlog",
  164. "log_level" : "debug",
  165. "pid_file" : "./pidfile.pid",
  166. "allowed_hosts": [
  167. "guerrillamail.com",
  168. "guerrillamailblock.com",
  169. "sharklasers.com",
  170. "guerrillamail.net",
  171. "guerrillamail.org"
  172. ],
  173. "backend_config": {
  174. "save_workers_size" : 1,
  175. "save_process": "HeadersParser|Debugger",
  176. "log_received_mails": false
  177. },
  178. "servers" : [
  179. {
  180. "is_enabled" : true,
  181. "host_name":"mail.test.com",
  182. "max_size": 1000000,
  183. "private_key_file":"../..//tests/mail2.guerrillamail.com.key.pem",
  184. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  185. "timeout":180,
  186. "listen_interface":"127.0.0.1:2552",
  187. "start_tls_on":true,
  188. "tls_always_on":false,
  189. "max_clients": 1000,
  190. "log_file" : "../../tests/testlog"
  191. },
  192. {
  193. "is_enabled" : true,
  194. "host_name":"secure.test.com",
  195. "max_size":1000000,
  196. "private_key_file":"../..//tests/mail2.guerrillamail.com.key.pem",
  197. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  198. "timeout":180,
  199. "listen_interface":"127.0.0.1:4655",
  200. "start_tls_on":false,
  201. "tls_always_on":true,
  202. "max_clients":500,
  203. "log_file" : "../../tests/testlog"
  204. }
  205. ]
  206. }
  207. `
  208. // adds 127.0.0.1:4655, a secure server
  209. var configJsonE = `
  210. {
  211. "log_file" : "../../tests/testlog",
  212. "log_level" : "debug",
  213. "pid_file" : "./pidfile2.pid",
  214. "allowed_hosts": [
  215. "guerrillamail.com",
  216. "guerrillamailblock.com",
  217. "sharklasers.com",
  218. "guerrillamail.net",
  219. "guerrillamail.org"
  220. ],
  221. "backend_config" :
  222. {
  223. "save_process_old": "HeadersParser|Debugger|Hasher|Header|Compressor|Redis|MySql",
  224. "save_process": "GuerrillaRedisDB",
  225. "log_received_mails" : true,
  226. "sql_driver": "mysql",
  227. "sql_dsn": "root:secret@tcp(127.0.0.1:3306)/gmail_mail?readTimeout=10&writeTimeout=10",
  228. "mail_table":"new_mail",
  229. "redis_interface" : "127.0.0.1:6379",
  230. "redis_expire_seconds" : 7200,
  231. "save_workers_size" : 3,
  232. "primary_mail_host":"sharklasers.com"
  233. },
  234. "servers" : [
  235. {
  236. "is_enabled" : true,
  237. "host_name":"mail.test.com",
  238. "max_size": 1000000,
  239. "private_key_file":"../..//tests/mail2.guerrillamail.com.key.pem",
  240. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  241. "timeout":180,
  242. "listen_interface":"127.0.0.1:2552",
  243. "start_tls_on":true,
  244. "tls_always_on":false,
  245. "max_clients": 1000,
  246. "log_file" : "../../tests/testlog"
  247. },
  248. {
  249. "is_enabled" : true,
  250. "host_name":"secure.test.com",
  251. "max_size":1000000,
  252. "private_key_file":"../..//tests/mail2.guerrillamail.com.key.pem",
  253. "public_key_file":"../../tests/mail2.guerrillamail.com.cert.pem",
  254. "timeout":180,
  255. "listen_interface":"127.0.0.1:4655",
  256. "start_tls_on":false,
  257. "tls_always_on":true,
  258. "max_clients":500,
  259. "log_file" : "../../tests/testlog"
  260. }
  261. ]
  262. }
  263. `
  264. const testPauseDuration = time.Millisecond * 600
  265. // reload config
  266. func sigHup() {
  267. if data, err := ioutil.ReadFile("pidfile.pid"); err == nil {
  268. mainlog.Infof("pid read is %s", data)
  269. ecmd := exec.Command("kill", "-HUP", string(data))
  270. _, err = ecmd.Output()
  271. if err != nil {
  272. mainlog.Infof("could not SIGHUP", err)
  273. }
  274. } else {
  275. mainlog.WithError(err).Info("sighup - Could not read pidfle")
  276. }
  277. }
  278. // shutdown after calling serve()
  279. func sigKill() {
  280. if data, err := ioutil.ReadFile("pidfile.pid"); err == nil {
  281. mainlog.Infof("pid read is %s", data)
  282. ecmd := exec.Command("kill", string(data))
  283. _, err = ecmd.Output()
  284. if err != nil {
  285. mainlog.Infof("could not sigkill", err)
  286. }
  287. } else {
  288. mainlog.WithError(err).Info("sigKill - Could not read pidfle")
  289. }
  290. }
  291. // make sure that we get all the config change events
  292. func TestCmdConfigChangeEvents(t *testing.T) {
  293. oldconf := &guerrilla.AppConfig{}
  294. if err := oldconf.Load([]byte(configJsonA)); err != nil {
  295. t.Error("configJsonA is invalid", err)
  296. }
  297. newconf := &guerrilla.AppConfig{}
  298. if err := newconf.Load([]byte(configJsonB)); err != nil {
  299. t.Error("configJsonB is invalid", err)
  300. }
  301. newerconf := &guerrilla.AppConfig{}
  302. if err := newerconf.Load([]byte(configJsonC)); err != nil {
  303. t.Error("configJsonC is invalid", err)
  304. }
  305. expectedEvents := map[guerrilla.Event]bool{
  306. guerrilla.EventConfigBackendConfig: false,
  307. guerrilla.EventConfigServerNew: false,
  308. }
  309. mainlog, _ = log.GetLogger("../../tests/testlog", "debug")
  310. bcfg := backends.BackendConfig{"log_received_mails": true}
  311. backend, err := backends.New(bcfg, mainlog)
  312. app, err := guerrilla.New(oldconf, backend, mainlog)
  313. if err != nil {
  314. t.Error("Failed to create new app", err)
  315. }
  316. toUnsubscribe := map[guerrilla.Event]func(c *guerrilla.AppConfig){}
  317. toUnsubscribeS := map[guerrilla.Event]func(c *guerrilla.ServerConfig){}
  318. for event := range expectedEvents {
  319. // Put in anon func since range is overwriting event
  320. func(e guerrilla.Event) {
  321. if strings.Index(e.String(), "server_change") == 0 {
  322. f := func(c *guerrilla.ServerConfig) {
  323. expectedEvents[e] = true
  324. }
  325. app.Subscribe(e, f)
  326. toUnsubscribeS[e] = f
  327. } else {
  328. f := func(c *guerrilla.AppConfig) {
  329. expectedEvents[e] = true
  330. }
  331. app.Subscribe(e, f)
  332. toUnsubscribe[e] = f
  333. }
  334. }(event)
  335. }
  336. // emit events
  337. newconf.EmitChangeEvents(oldconf, app)
  338. newerconf.EmitChangeEvents(newconf, app)
  339. // unsubscribe
  340. for unevent, unfun := range toUnsubscribe {
  341. app.Unsubscribe(unevent, unfun)
  342. }
  343. for unevent, unfun := range toUnsubscribeS {
  344. app.Unsubscribe(unevent, unfun)
  345. }
  346. for event, val := range expectedEvents {
  347. if val == false {
  348. t.Error("Did not fire config change event:", event)
  349. t.FailNow()
  350. break
  351. }
  352. }
  353. // cleanup
  354. os.Truncate("../../tests/testlog", 0)
  355. }
  356. // start server, change config, send SIG HUP, confirm that the pidfile changed & backend reloaded
  357. func TestServe(t *testing.T) {
  358. testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  359. mainlog, _ = log.GetLogger("../../tests/testlog", "debug")
  360. ioutil.WriteFile("configJsonA.json", []byte(configJsonA), 0644)
  361. cmd := &cobra.Command{}
  362. configPath = "configJsonA.json"
  363. var serveWG sync.WaitGroup
  364. serveWG.Add(1)
  365. go func() {
  366. serve(cmd, []string{})
  367. serveWG.Done()
  368. }()
  369. time.Sleep(testPauseDuration)
  370. data, err := ioutil.ReadFile("pidfile.pid")
  371. if err != nil {
  372. t.Error("error reading pidfile.pid", err)
  373. t.FailNow()
  374. }
  375. _, err = strconv.Atoi(string(data))
  376. if err != nil {
  377. t.Error("could not parse pidfile.pid", err)
  378. t.FailNow()
  379. }
  380. // change the config file
  381. ioutil.WriteFile("configJsonA.json", []byte(configJsonB), 0644)
  382. // test SIGHUP via the kill command
  383. // Would not work on windows as kill is not available.
  384. // TODO: Implement an alternative test for windows.
  385. if runtime.GOOS != "windows" {
  386. sigHup()
  387. time.Sleep(testPauseDuration) // allow sighup to do its job
  388. // did the pidfile change as expected?
  389. if _, err := os.Stat("./pidfile2.pid"); os.IsNotExist(err) {
  390. t.Error("pidfile not changed after sighup SIGHUP", err)
  391. }
  392. }
  393. // send kill signal and wait for exit
  394. sigKill()
  395. // wait for exit
  396. serveWG.Wait()
  397. // did backend started as expected?
  398. fd, err := os.Open("../../tests/testlog")
  399. if err != nil {
  400. t.Error(err)
  401. }
  402. if read, err := ioutil.ReadAll(fd); err == nil {
  403. logOutput := string(read)
  404. if i := strings.Index(logOutput, "new backend started"); i < 0 {
  405. t.Error("Dummy backend not restared")
  406. }
  407. }
  408. // cleanup
  409. os.Truncate("../../tests/testlog", 0)
  410. os.Remove("configJsonA.json")
  411. os.Remove("./pidfile.pid")
  412. os.Remove("./pidfile2.pid")
  413. }
  414. // Start with configJsonA.json,
  415. // then add a new server to it (127.0.0.1:2526),
  416. // then SIGHUP (to reload config & trigger config update events),
  417. // then connect to it & HELO.
  418. func TestServerAddEvent(t *testing.T) {
  419. testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  420. mainlog, _ = log.GetLogger("../../tests/testlog", "debug")
  421. // start the server by emulating the serve command
  422. ioutil.WriteFile("configJsonA.json", []byte(configJsonA), 0644)
  423. cmd := &cobra.Command{}
  424. configPath = "configJsonA.json"
  425. var serveWG sync.WaitGroup
  426. serveWG.Add(1)
  427. go func() {
  428. serve(cmd, []string{})
  429. serveWG.Done()
  430. }()
  431. time.Sleep(testPauseDuration) // allow the server to start
  432. // now change the config by adding a server
  433. conf := &guerrilla.AppConfig{} // blank one
  434. conf.Load([]byte(configJsonA)) // load configJsonA
  435. newServer := conf.Servers[0] // copy the first server config
  436. newServer.ListenInterface = "127.0.0.1:2526" // change it
  437. newConf := conf // copy the cmdConfg
  438. newConf.Servers = append(newConf.Servers, newServer) // add the new server
  439. if jsonbytes, err := json.Marshal(newConf); err == nil {
  440. //fmt.Println(string(jsonbytes))
  441. ioutil.WriteFile("configJsonA.json", []byte(jsonbytes), 0644)
  442. }
  443. // send a sighup signal to the server
  444. sigHup()
  445. time.Sleep(testPauseDuration) // pause for config to reload
  446. if conn, buffin, err := test.Connect(newServer, 20); err != nil {
  447. t.Error("Could not connect to new server", newServer.ListenInterface)
  448. } else {
  449. if result, err := test.Command(conn, buffin, "HELO"); err == nil {
  450. expect := "250 mail.test.com Hello"
  451. if strings.Index(result, expect) != 0 {
  452. t.Error("Expected", expect, "but got", result)
  453. }
  454. } else {
  455. t.Error(err)
  456. }
  457. }
  458. // send kill signal and wait for exit
  459. sigKill()
  460. serveWG.Wait()
  461. // did backend started as expected?
  462. fd, _ := os.Open("../../tests/testlog")
  463. if read, err := ioutil.ReadAll(fd); err == nil {
  464. logOutput := string(read)
  465. //fmt.Println(logOutput)
  466. if i := strings.Index(logOutput, "New server added [127.0.0.1:2526]"); i < 0 {
  467. t.Error("Did not add [127.0.0.1:2526], most likely because Bus.Subscribe(\"server_change:new_server\" didnt fire")
  468. }
  469. }
  470. // cleanup
  471. os.Truncate("../../tests/testlog", 0)
  472. os.Remove("configJsonA.json")
  473. os.Remove("./pidfile.pid")
  474. }
  475. // Start with configJsonA.json,
  476. // then change the config to enable 127.0.0.1:2228,
  477. // then write the new config,
  478. // then SIGHUP (to reload config & trigger config update events),
  479. // then connect to 127.0.0.1:2228 & HELO.
  480. func TestServerStartEvent(t *testing.T) {
  481. testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  482. mainlog, _ = log.GetLogger("../../tests/testlog", "debug")
  483. // start the server by emulating the serve command
  484. ioutil.WriteFile("configJsonA.json", []byte(configJsonA), 0644)
  485. cmd := &cobra.Command{}
  486. configPath = "configJsonA.json"
  487. var serveWG sync.WaitGroup
  488. serveWG.Add(1)
  489. go func() {
  490. serve(cmd, []string{})
  491. serveWG.Done()
  492. }()
  493. time.Sleep(testPauseDuration)
  494. // now change the config by adding a server
  495. conf := &guerrilla.AppConfig{} // blank one
  496. conf.Load([]byte(configJsonA)) // load configJsonA
  497. newConf := conf // copy the cmdConfg
  498. newConf.Servers[1].IsEnabled = true
  499. if jsonbytes, err := json.Marshal(newConf); err == nil {
  500. //fmt.Println(string(jsonbytes))
  501. ioutil.WriteFile("configJsonA.json", []byte(jsonbytes), 0644)
  502. } else {
  503. t.Error(err)
  504. }
  505. // send a sighup signal to the server
  506. sigHup()
  507. time.Sleep(testPauseDuration) // pause for config to reload
  508. if conn, buffin, err := test.Connect(newConf.Servers[1], 20); err != nil {
  509. t.Error("Could not connect to new server", newConf.Servers[1].ListenInterface)
  510. } else {
  511. if result, err := test.Command(conn, buffin, "HELO"); err == nil {
  512. expect := "250 enable.test.com Hello"
  513. if strings.Index(result, expect) != 0 {
  514. t.Error("Expected", expect, "but got", result)
  515. }
  516. } else {
  517. t.Error(err)
  518. }
  519. }
  520. // send kill signal and wait for exit
  521. sigKill()
  522. serveWG.Wait()
  523. // did backend started as expected?
  524. fd, _ := os.Open("../../tests/testlog")
  525. if read, err := ioutil.ReadAll(fd); err == nil {
  526. logOutput := string(read)
  527. //fmt.Println(logOutput)
  528. if i := strings.Index(logOutput, "Starting server [127.0.0.1:2228]"); i < 0 {
  529. t.Error("did not add [127.0.0.1:2228], most likely because Bus.Subscribe(\"server_change:start_server\" didnt fire")
  530. }
  531. }
  532. // cleanup
  533. os.Truncate("../../tests/testlog", 0)
  534. os.Remove("configJsonA.json")
  535. os.Remove("./pidfile.pid")
  536. }
  537. // Start with configJsonA.json,
  538. // then change the config to enable 127.0.0.1:2228,
  539. // then write the new config,
  540. // then SIGHUP (to reload config & trigger config update events),
  541. // then connect to 127.0.0.1:2228 & HELO.
  542. // then change the config to dsiable 127.0.0.1:2228,
  543. // then SIGHUP (to reload config & trigger config update events),
  544. // then connect to 127.0.0.1:2228 - it should not connect
  545. func TestServerStopEvent(t *testing.T) {
  546. testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  547. mainlog, _ = log.GetLogger("../../tests/testlog", "debug")
  548. // start the server by emulating the serve command
  549. ioutil.WriteFile("configJsonA.json", []byte(configJsonA), 0644)
  550. cmd := &cobra.Command{}
  551. configPath = "configJsonA.json"
  552. var serveWG sync.WaitGroup
  553. serveWG.Add(1)
  554. go func() {
  555. serve(cmd, []string{})
  556. serveWG.Done()
  557. }()
  558. time.Sleep(testPauseDuration)
  559. // now change the config by enabling a server
  560. conf := &guerrilla.AppConfig{} // blank one
  561. conf.Load([]byte(configJsonA)) // load configJsonA
  562. newConf := conf // copy the cmdConfg
  563. newConf.Servers[1].IsEnabled = true
  564. if jsonbytes, err := json.Marshal(newConf); err == nil {
  565. //fmt.Println(string(jsonbytes))
  566. ioutil.WriteFile("configJsonA.json", []byte(jsonbytes), 0644)
  567. } else {
  568. t.Error(err)
  569. }
  570. // send a sighup signal to the server
  571. sigHup()
  572. time.Sleep(testPauseDuration) // pause for config to reload
  573. if conn, buffin, err := test.Connect(newConf.Servers[1], 20); err != nil {
  574. t.Error("Could not connect to new server", newConf.Servers[1].ListenInterface)
  575. } else {
  576. if result, err := test.Command(conn, buffin, "HELO"); err == nil {
  577. expect := "250 enable.test.com Hello"
  578. if strings.Index(result, expect) != 0 {
  579. t.Error("Expected", expect, "but got", result)
  580. }
  581. } else {
  582. t.Error(err)
  583. }
  584. conn.Close()
  585. }
  586. // now disable the server
  587. newerConf := newConf // copy the cmdConfg
  588. newerConf.Servers[1].IsEnabled = false
  589. if jsonbytes, err := json.Marshal(newerConf); err == nil {
  590. //fmt.Println(string(jsonbytes))
  591. ioutil.WriteFile("configJsonA.json", []byte(jsonbytes), 0644)
  592. } else {
  593. t.Error(err)
  594. }
  595. // send a sighup signal to the server
  596. sigHup()
  597. time.Sleep(testPauseDuration) // pause for config to reload
  598. // it should not connect to the server
  599. if _, _, err := test.Connect(newConf.Servers[1], 20); err == nil {
  600. t.Error("127.0.0.1:2228 was disabled, but still accepting connections", newConf.Servers[1].ListenInterface)
  601. }
  602. // send kill signal and wait for exit
  603. sigKill()
  604. serveWG.Wait()
  605. // did backend started as expected?
  606. fd, _ := os.Open("../../tests/testlog")
  607. if read, err := ioutil.ReadAll(fd); err == nil {
  608. logOutput := string(read)
  609. //fmt.Println(logOutput)
  610. if i := strings.Index(logOutput, "Server [127.0.0.1:2228] stopped"); i < 0 {
  611. t.Error("did not stop [127.0.0.1:2228], most likely because Bus.Subscribe(\"server_change:stop_server\" didnt fire")
  612. }
  613. }
  614. // cleanup
  615. os.Truncate("../../tests/testlog", 0)
  616. os.Remove("configJsonA.json")
  617. os.Remove("./pidfile.pid")
  618. }
  619. // Start with configJsonD.json,
  620. // then connect to 127.0.0.1:4655 & HELO & try RCPT TO with an invalid host [grr.la]
  621. // then change the config to enable add new host [grr.la] to allowed_hosts
  622. // then write the new config,
  623. // then SIGHUP (to reload config & trigger config update events),
  624. // connect to 127.0.0.1:4655 & HELO & try RCPT TO, grr.la should work
  625. func TestAllowedHostsEvent(t *testing.T) {
  626. testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  627. mainlog, _ = log.GetLogger("../../tests/testlog", "debug")
  628. // start the server by emulating the serve command
  629. ioutil.WriteFile("configJsonD.json", []byte(configJsonD), 0644)
  630. conf := &guerrilla.AppConfig{} // blank one
  631. conf.Load([]byte(configJsonD)) // load configJsonD
  632. cmd := &cobra.Command{}
  633. configPath = "configJsonD.json"
  634. var serveWG sync.WaitGroup
  635. time.Sleep(testPauseDuration)
  636. serveWG.Add(1)
  637. go func() {
  638. serve(cmd, []string{})
  639. serveWG.Done()
  640. }()
  641. time.Sleep(testPauseDuration)
  642. // now connect and try RCPT TO with an invalid host
  643. if conn, buffin, err := test.Connect(conf.Servers[1], 20); err != nil {
  644. t.Error("Could not connect to new server", conf.Servers[1].ListenInterface, err)
  645. } else {
  646. if result, err := test.Command(conn, buffin, "HELO"); err == nil {
  647. expect := "250 secure.test.com Hello"
  648. if strings.Index(result, expect) != 0 {
  649. t.Error("Expected", expect, "but got", result)
  650. } else {
  651. if result, err = test.Command(conn, buffin, "RCPT TO:[email protected]"); err == nil {
  652. expect := "454 4.1.1 Error: Relay access denied: grr.la"
  653. if strings.Index(result, expect) != 0 {
  654. t.Error("Expected:", expect, "but got:", result)
  655. }
  656. }
  657. }
  658. }
  659. conn.Close()
  660. }
  661. // now change the config by adding a host to allowed hosts
  662. newConf := conf
  663. newConf.AllowedHosts = append(newConf.AllowedHosts, "grr.la")
  664. if jsonbytes, err := json.Marshal(newConf); err == nil {
  665. ioutil.WriteFile("configJsonD.json", []byte(jsonbytes), 0644)
  666. } else {
  667. t.Error(err)
  668. }
  669. // send a sighup signal to the server to reload config
  670. sigHup()
  671. time.Sleep(testPauseDuration) // pause for config to reload
  672. // now repeat the same conversion, RCPT TO should be accepted
  673. if conn, buffin, err := test.Connect(conf.Servers[1], 20); err != nil {
  674. t.Error("Could not connect to new server", conf.Servers[1].ListenInterface, err)
  675. } else {
  676. if result, err := test.Command(conn, buffin, "HELO"); err == nil {
  677. expect := "250 secure.test.com Hello"
  678. if strings.Index(result, expect) != 0 {
  679. t.Error("Expected", expect, "but got", result)
  680. } else {
  681. if result, err = test.Command(conn, buffin, "RCPT TO:[email protected]"); err == nil {
  682. expect := "250 2.1.5 OK"
  683. if strings.Index(result, expect) != 0 {
  684. t.Error("Expected:", expect, "but got:", result)
  685. }
  686. }
  687. }
  688. }
  689. conn.Close()
  690. }
  691. // send kill signal and wait for exit
  692. sigKill()
  693. serveWG.Wait()
  694. // did backend started as expected?
  695. fd, _ := os.Open("../../tests/testlog")
  696. if read, err := ioutil.ReadAll(fd); err == nil {
  697. logOutput := string(read)
  698. //fmt.Println(logOutput)
  699. if i := strings.Index(logOutput, "allowed_hosts config changed, a new list was set"); i < 0 {
  700. t.Errorf("did not change allowed_hosts, most likely because Bus.Subscribe(\"%s\" didnt fire",
  701. guerrilla.EventConfigAllowedHosts)
  702. }
  703. }
  704. // cleanup
  705. os.Truncate("../../tests/testlog", 0)
  706. os.Remove("configJsonD.json")
  707. os.Remove("./pidfile.pid")
  708. }
  709. // Test TLS config change event
  710. // start with configJsonD
  711. // should be able to STARTTLS to 127.0.0.1:2525 with no problems
  712. // generate new certs & reload config
  713. // should get a new tls event & able to STARTTLS with no problem
  714. func TestTLSConfigEvent(t *testing.T) {
  715. testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  716. // pause for generated cert to output on slow machines
  717. time.Sleep(testPauseDuration)
  718. // did cert output?
  719. if _, err := os.Stat("../../tests/mail2.guerrillamail.com.cert.pem"); err != nil {
  720. t.Error("Did not create cert ", err)
  721. }
  722. mainlog, _ = log.GetLogger("../../tests/testlog", "debug")
  723. // start the server by emulating the serve command
  724. ioutil.WriteFile("configJsonD.json", []byte(configJsonD), 0644)
  725. conf := &guerrilla.AppConfig{} // blank one
  726. conf.Load([]byte(configJsonD)) // load configJsonD
  727. cmd := &cobra.Command{}
  728. configPath = "configJsonD.json"
  729. var serveWG sync.WaitGroup
  730. serveWG.Add(1)
  731. go func() {
  732. serve(cmd, []string{})
  733. serveWG.Done()
  734. }()
  735. time.Sleep(testPauseDuration)
  736. // Test STARTTLS handshake
  737. testTlsHandshake := func() {
  738. if conn, buffin, err := test.Connect(conf.Servers[0], 20); err != nil {
  739. t.Error("Could not connect to server", conf.Servers[0].ListenInterface, err)
  740. } else {
  741. if result, err := test.Command(conn, buffin, "HELO"); err == nil {
  742. expect := "250 mail.test.com Hello"
  743. if strings.Index(result, expect) != 0 {
  744. t.Error("Expected", expect, "but got", result)
  745. } else {
  746. if result, err = test.Command(conn, buffin, "STARTTLS"); err == nil {
  747. expect := "220 2.0.0 Ready to start TLS"
  748. if strings.Index(result, expect) != 0 {
  749. t.Error("Expected:", expect, "but got:", result)
  750. } else {
  751. tlsConn := tls.Client(conn, &tls.Config{
  752. InsecureSkipVerify: true,
  753. ServerName: "127.0.0.1",
  754. })
  755. if err := tlsConn.Handshake(); err != nil {
  756. t.Error("Failed to handshake", conf.Servers[0].ListenInterface)
  757. } else {
  758. conn = tlsConn
  759. mainlog.Info("TLS Handshake succeeded")
  760. }
  761. }
  762. }
  763. }
  764. }
  765. conn.Close()
  766. }
  767. }
  768. testTlsHandshake()
  769. if err := os.Remove("../../tests/mail2.guerrillamail.com.cert.pem"); err != nil {
  770. t.Error("could not remove cert", err)
  771. }
  772. if err := os.Remove("../../tests/mail2.guerrillamail.com.key.pem"); err != nil {
  773. t.Error("could not remove key", err)
  774. }
  775. // generate a new cert
  776. testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  777. // pause for generated cert to output
  778. time.Sleep(testPauseDuration)
  779. // did cert output?
  780. if _, err := os.Stat("../../tests/mail2.guerrillamail.com.cert.pem"); err != nil {
  781. t.Error("Did not create cert ", err)
  782. }
  783. sigHup()
  784. time.Sleep(testPauseDuration * 2) // pause for config to reload
  785. testTlsHandshake()
  786. //time.Sleep(testPauseDuration)
  787. // send kill signal and wait for exit
  788. sigKill()
  789. serveWG.Wait()
  790. // did backend started as expected?
  791. fd, _ := os.Open("../../tests/testlog")
  792. if read, err := ioutil.ReadAll(fd); err == nil {
  793. logOutput := string(read)
  794. //fmt.Println(logOutput)
  795. if i := strings.Index(logOutput, "Server [127.0.0.1:2552] new TLS configuration loaded"); i < 0 {
  796. t.Error("did not change tls, most likely because Bus.Subscribe(\"server_change:tls_config\" didnt fire")
  797. }
  798. }
  799. // cleanup
  800. os.Truncate("../../tests/testlog", 0)
  801. os.Remove("configJsonD.json")
  802. os.Remove("./pidfile.pid")
  803. }
  804. // Testing starting a server with a bad TLS config
  805. // It should not start, return exit code 1
  806. func TestBadTLSStart(t *testing.T) {
  807. // Need to run the test in a different process by executing a command
  808. // because the serve() does os.Exit when starting with a bad TLS config
  809. if os.Getenv("BE_CRASHER") == "1" {
  810. // do the test
  811. // first, remove the good certs, if any
  812. if err := os.Remove("./../../tests/mail2.guerrillamail.com.cert.pem"); err != nil {
  813. mainlog.WithError(err).Error("could not remove ./../../tests/mail2.guerrillamail.com.cert.pem")
  814. } else {
  815. mainlog.Info("removed ./../../tests/mail2.guerrillamail.com.cert.pem")
  816. }
  817. // next run the server
  818. ioutil.WriteFile("configJsonD.json", []byte(configJsonD), 0644)
  819. conf := &guerrilla.AppConfig{} // blank one
  820. conf.Load([]byte(configJsonD)) // load configJsonD
  821. cmd := &cobra.Command{}
  822. configPath = "configJsonD.json"
  823. var serveWG sync.WaitGroup
  824. serveWG.Add(1)
  825. go func() {
  826. serve(cmd, []string{})
  827. serveWG.Done()
  828. }()
  829. time.Sleep(testPauseDuration)
  830. sigKill()
  831. serveWG.Wait()
  832. return
  833. }
  834. cmd := exec.Command(os.Args[0], "-test.run=TestBadTLSStart")
  835. cmd.Env = append(os.Environ(), "BE_CRASHER=1")
  836. err := cmd.Run()
  837. if e, ok := err.(*exec.ExitError); ok && !e.Success() {
  838. return
  839. }
  840. t.Error("Server started with a bad TLS config, was expecting exit status 1")
  841. // cleanup
  842. os.Truncate("../../tests/testlog", 0)
  843. os.Remove("configJsonD.json")
  844. os.Remove("./pidfile.pid")
  845. }
  846. // Test config reload with a bad TLS config
  847. // It should ignore the config reload, keep running with old settings
  848. func TestBadTLSReload(t *testing.T) {
  849. mainlog, _ = log.GetLogger("../../tests/testlog", "debug")
  850. // start with a good cert
  851. testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  852. // start the server by emulating the serve command
  853. ioutil.WriteFile("configJsonD.json", []byte(configJsonD), 0644)
  854. conf := &guerrilla.AppConfig{} // blank one
  855. conf.Load([]byte(configJsonD)) // load configJsonD
  856. cmd := &cobra.Command{}
  857. configPath = "configJsonD.json"
  858. var serveWG sync.WaitGroup
  859. serveWG.Add(1)
  860. go func() {
  861. serve(cmd, []string{})
  862. serveWG.Done()
  863. }()
  864. time.Sleep(testPauseDuration)
  865. if conn, buffin, err := test.Connect(conf.Servers[0], 20); err != nil {
  866. t.Error("Could not connect to server", conf.Servers[0].ListenInterface, err)
  867. } else {
  868. if result, err := test.Command(conn, buffin, "HELO"); err == nil {
  869. expect := "250 mail.test.com Hello"
  870. if strings.Index(result, expect) != 0 {
  871. t.Error("Expected", expect, "but got", result)
  872. }
  873. }
  874. }
  875. // write some trash data
  876. ioutil.WriteFile("./../../tests/mail2.guerrillamail.com.cert.pem", []byte("trash data"), 0664)
  877. ioutil.WriteFile("./../../tests/mail2.guerrillamail.com.key.pem", []byte("trash data"), 0664)
  878. newConf := conf // copy the cmdConfg
  879. if jsonbytes, err := json.Marshal(newConf); err == nil {
  880. ioutil.WriteFile("configJsonD.json", []byte(jsonbytes), 0644)
  881. } else {
  882. t.Error(err)
  883. }
  884. // send a sighup signal to the server to reload config
  885. sigHup()
  886. time.Sleep(testPauseDuration) // pause for config to reload
  887. // we should still be able to to talk to it
  888. if conn, buffin, err := test.Connect(conf.Servers[0], 20); err != nil {
  889. t.Error("Could not connect to server", conf.Servers[0].ListenInterface, err)
  890. } else {
  891. if result, err := test.Command(conn, buffin, "HELO"); err == nil {
  892. expect := "250 mail.test.com Hello"
  893. if strings.Index(result, expect) != 0 {
  894. t.Error("Expected", expect, "but got", result)
  895. }
  896. }
  897. }
  898. sigKill()
  899. serveWG.Wait()
  900. // did config reload fail as expected?
  901. fd, _ := os.Open("../../tests/testlog")
  902. if read, err := ioutil.ReadAll(fd); err == nil {
  903. logOutput := string(read)
  904. //fmt.Println(logOutput)
  905. if i := strings.Index(logOutput, "cannot use TLS config for"); i < 0 {
  906. t.Error("[127.0.0.1:2552] did not reject our tls config as expected")
  907. }
  908. }
  909. // cleanup
  910. os.Truncate("../../tests/testlog", 0)
  911. os.Remove("configJsonD.json")
  912. os.Remove("./pidfile.pid")
  913. }
  914. // Test for when the server config Timeout value changes
  915. // Start with configJsonD.json
  916. func TestSetTimeoutEvent(t *testing.T) {
  917. mainlog, _ = log.GetLogger("../../tests/testlog", "debug")
  918. testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  919. // start the server by emulating the serve command
  920. ioutil.WriteFile("configJsonD.json", []byte(configJsonD), 0644)
  921. conf := &guerrilla.AppConfig{} // blank one
  922. conf.Load([]byte(configJsonD)) // load configJsonD
  923. cmd := &cobra.Command{}
  924. configPath = "configJsonD.json"
  925. var serveWG sync.WaitGroup
  926. serveWG.Add(1)
  927. go func() {
  928. serve(cmd, []string{})
  929. serveWG.Done()
  930. }()
  931. time.Sleep(testPauseDuration)
  932. // set the timeout to 1 second
  933. newConf := conf // copy the cmdConfg
  934. newConf.Servers[0].Timeout = 1
  935. if jsonbytes, err := json.Marshal(newConf); err == nil {
  936. ioutil.WriteFile("configJsonD.json", []byte(jsonbytes), 0644)
  937. } else {
  938. t.Error(err)
  939. }
  940. // send a sighup signal to the server to reload config
  941. sigHup()
  942. time.Sleep(testPauseDuration) // config reload
  943. var waitTimeout sync.WaitGroup
  944. if conn, buffin, err := test.Connect(conf.Servers[0], 20); err != nil {
  945. t.Error("Could not connect to server", conf.Servers[0].ListenInterface, err)
  946. } else {
  947. waitTimeout.Add(1)
  948. go func() {
  949. if result, err := test.Command(conn, buffin, "HELO"); err == nil {
  950. expect := "250 mail.test.com Hello"
  951. if strings.Index(result, expect) != 0 {
  952. t.Error("Expected", expect, "but got", result)
  953. } else {
  954. b := make([]byte, 1024)
  955. conn.Read(b)
  956. }
  957. }
  958. waitTimeout.Done()
  959. }()
  960. }
  961. // wait for timeout
  962. waitTimeout.Wait()
  963. // so the connection we have opened should timeout by now
  964. // send kill signal and wait for exit
  965. sigKill()
  966. serveWG.Wait()
  967. // did backend started as expected?
  968. fd, _ := os.Open("../../tests/testlog")
  969. if read, err := ioutil.ReadAll(fd); err == nil {
  970. logOutput := string(read)
  971. //fmt.Println(logOutput)
  972. if i := strings.Index(logOutput, "i/o timeout"); i < 0 {
  973. t.Error("Connection to 127.0.0.1:2552 didn't timeout as expected")
  974. }
  975. }
  976. // cleanup
  977. os.Truncate("../../tests/testlog", 0)
  978. os.Remove("configJsonD.json")
  979. os.Remove("./pidfile.pid")
  980. }
  981. // Test debug level config change
  982. // Start in log_level = debug
  983. // Load config & start server
  984. func TestDebugLevelChange(t *testing.T) {
  985. mainlog, _ = log.GetLogger("../../tests/testlog", "debug")
  986. testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  987. // start the server by emulating the serve command
  988. ioutil.WriteFile("configJsonD.json", []byte(configJsonD), 0644)
  989. conf := &guerrilla.AppConfig{} // blank one
  990. conf.Load([]byte(configJsonD)) // load configJsonD
  991. conf.LogLevel = "debug"
  992. cmd := &cobra.Command{}
  993. configPath = "configJsonD.json"
  994. var serveWG sync.WaitGroup
  995. serveWG.Add(1)
  996. go func() {
  997. serve(cmd, []string{})
  998. serveWG.Done()
  999. }()
  1000. time.Sleep(testPauseDuration)
  1001. if conn, buffin, err := test.Connect(conf.Servers[0], 20); err != nil {
  1002. t.Error("Could not connect to server", conf.Servers[0].ListenInterface, err)
  1003. } else {
  1004. if result, err := test.Command(conn, buffin, "HELO"); err == nil {
  1005. expect := "250 mail.test.com Hello"
  1006. if strings.Index(result, expect) != 0 {
  1007. t.Error("Expected", expect, "but got", result)
  1008. }
  1009. }
  1010. conn.Close()
  1011. }
  1012. // set the log_level to info
  1013. newConf := conf // copy the cmdConfg
  1014. newConf.LogLevel = log.InfoLevel.String()
  1015. if jsonbytes, err := json.Marshal(newConf); err == nil {
  1016. ioutil.WriteFile("configJsonD.json", []byte(jsonbytes), 0644)
  1017. } else {
  1018. t.Error(err)
  1019. }
  1020. // send a sighup signal to the server to reload config
  1021. sigHup()
  1022. time.Sleep(testPauseDuration) // log to change
  1023. // connect again, this time we should see info
  1024. if conn, buffin, err := test.Connect(conf.Servers[0], 20); err != nil {
  1025. t.Error("Could not connect to server", conf.Servers[0].ListenInterface, err)
  1026. } else {
  1027. if result, err := test.Command(conn, buffin, "NOOP"); err == nil {
  1028. expect := "200 2.0.0 OK"
  1029. if strings.Index(result, expect) != 0 {
  1030. t.Error("Expected", expect, "but got", result)
  1031. }
  1032. }
  1033. conn.Close()
  1034. }
  1035. // send kill signal and wait for exit
  1036. sigKill()
  1037. serveWG.Wait()
  1038. // did backend started as expected?
  1039. fd, _ := os.Open("../../tests/testlog")
  1040. if read, err := ioutil.ReadAll(fd); err == nil {
  1041. logOutput := string(read)
  1042. //fmt.Println(logOutput)
  1043. if i := strings.Index(logOutput, "log level changed to [info]"); i < 0 {
  1044. t.Error("Log level did not change to [info]")
  1045. }
  1046. // This should not be there:
  1047. if i := strings.Index(logOutput, "Client sent: NOOP"); i != -1 {
  1048. t.Error("Log level did not change to [info], we are still seeing debug messages")
  1049. }
  1050. }
  1051. // cleanup
  1052. os.Truncate("../../tests/testlog", 0)
  1053. os.Remove("configJsonD.json")
  1054. os.Remove("./pidfile.pid")
  1055. }
  1056. // When reloading with a bad backend config, it should revert to old backend config
  1057. func TestBadBackendReload(t *testing.T) {
  1058. testcert.GenerateCert("mail2.guerrillamail.com", "", 365*24*time.Hour, false, 2048, "P256", "../../tests/")
  1059. mainlog, _ = log.GetLogger("../../tests/testlog", "debug")
  1060. ioutil.WriteFile("configJsonA.json", []byte(configJsonA), 0644)
  1061. cmd := &cobra.Command{}
  1062. configPath = "configJsonA.json"
  1063. var serveWG sync.WaitGroup
  1064. serveWG.Add(1)
  1065. go func() {
  1066. serve(cmd, []string{})
  1067. serveWG.Done()
  1068. }()
  1069. time.Sleep(testPauseDuration)
  1070. // change the config file to the one with a broken backend
  1071. ioutil.WriteFile("configJsonA.json", []byte(configJsonE), 0644)
  1072. // test SIGHUP via the kill command
  1073. // Would not work on windows as kill is not available.
  1074. // TODO: Implement an alternative test for windows.
  1075. if runtime.GOOS != "windows" {
  1076. sigHup()
  1077. time.Sleep(testPauseDuration) // allow sighup to do its job
  1078. // did the pidfile change as expected?
  1079. if _, err := os.Stat("./pidfile2.pid"); os.IsNotExist(err) {
  1080. t.Error("pidfile not changed after sighup SIGHUP", err)
  1081. }
  1082. }
  1083. // send kill signal and wait for exit
  1084. sigKill()
  1085. serveWG.Wait()
  1086. // did backend started as expected?
  1087. fd, err := os.Open("../../tests/testlog")
  1088. if err != nil {
  1089. t.Error(err)
  1090. }
  1091. if read, err := ioutil.ReadAll(fd); err == nil {
  1092. logOutput := string(read)
  1093. if i := strings.Index(logOutput, "reverted to old backend config"); i < 0 {
  1094. t.Error("did not revert to old backend config")
  1095. }
  1096. }
  1097. // cleanup
  1098. os.Truncate("../../tests/testlog", 0)
  1099. os.Remove("configJsonA.json")
  1100. os.Remove("./pidfile.pid")
  1101. os.Remove("./pidfile2.pid")
  1102. }