serve_test.go 37 KB

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