serve_test.go 38 KB

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