@cloudant/couchbackup 2.9.14 → 2.9.15-SNAPSHOT.162

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (379) hide show
  1. package/.scannerwork/report-task.txt +2 -2
  2. package/.scannerwork/scanner-report/analysis-warnings.pb +2 -2
  3. package/.scannerwork/scanner-report/changesets-31.pb +1 -0
  4. package/.scannerwork/scanner-report/changesets-32.pb +1 -0
  5. package/.scannerwork/scanner-report/changesets-33.pb +1 -0
  6. package/.scannerwork/scanner-report/changesets-34.pb +1 -0
  7. package/.scannerwork/scanner-report/changesets-35.pb +1 -0
  8. package/.scannerwork/scanner-report/changesets-36.pb +1 -0
  9. package/.scannerwork/scanner-report/changesets-4.pb +1 -0
  10. package/.scannerwork/scanner-report/changesets-45.pb +1 -0
  11. package/.scannerwork/scanner-report/changesets-46.pb +1 -0
  12. package/.scannerwork/scanner-report/changesets-47.pb +1 -0
  13. package/.scannerwork/scanner-report/changesets-48.pb +1 -0
  14. package/.scannerwork/scanner-report/changesets-63.pb +1 -0
  15. package/.scannerwork/scanner-report/changesets-64.pb +1 -0
  16. package/.scannerwork/scanner-report/changesets-65.pb +1 -0
  17. package/.scannerwork/scanner-report/changesets-66.pb +1 -0
  18. package/.scannerwork/scanner-report/changesets-67.pb +1 -0
  19. package/.scannerwork/scanner-report/component-1.pb +3 -2
  20. package/.scannerwork/scanner-report/component-10.pb +1 -1
  21. package/.scannerwork/scanner-report/component-13.pb +1 -1
  22. package/.scannerwork/scanner-report/component-15.pb +1 -1
  23. package/.scannerwork/scanner-report/component-16.pb +1 -1
  24. package/.scannerwork/scanner-report/component-18.pb +1 -1
  25. package/.scannerwork/scanner-report/component-31.pb +1 -0
  26. package/.scannerwork/scanner-report/component-32.pb +1 -0
  27. package/.scannerwork/scanner-report/component-33.pb +1 -0
  28. package/.scannerwork/scanner-report/component-34.pb +1 -0
  29. package/.scannerwork/scanner-report/component-35.pb +1 -0
  30. package/.scannerwork/scanner-report/component-36.pb +1 -0
  31. package/.scannerwork/scanner-report/component-37.pb +1 -1
  32. package/.scannerwork/scanner-report/component-39.pb +1 -1
  33. package/.scannerwork/scanner-report/component-4.pb +1 -0
  34. package/.scannerwork/scanner-report/component-40.pb +1 -1
  35. package/.scannerwork/scanner-report/component-41.pb +1 -1
  36. package/.scannerwork/scanner-report/component-42.pb +1 -1
  37. package/.scannerwork/scanner-report/component-43.pb +1 -1
  38. package/.scannerwork/scanner-report/component-44.pb +1 -1
  39. package/.scannerwork/scanner-report/component-45.pb +1 -0
  40. package/.scannerwork/scanner-report/component-46.pb +1 -0
  41. package/.scannerwork/scanner-report/component-47.pb +1 -0
  42. package/.scannerwork/scanner-report/component-48.pb +1 -0
  43. package/.scannerwork/scanner-report/component-49.pb +1 -1
  44. package/.scannerwork/scanner-report/component-50.pb +1 -1
  45. package/.scannerwork/scanner-report/component-51.pb +1 -1
  46. package/.scannerwork/scanner-report/component-53.pb +1 -1
  47. package/.scannerwork/scanner-report/component-55.pb +1 -1
  48. package/.scannerwork/scanner-report/component-56.pb +1 -1
  49. package/.scannerwork/scanner-report/component-57.pb +1 -1
  50. package/.scannerwork/scanner-report/component-58.pb +1 -1
  51. package/.scannerwork/scanner-report/component-59.pb +1 -1
  52. package/.scannerwork/scanner-report/component-6.pb +1 -1
  53. package/.scannerwork/scanner-report/component-60.pb +1 -1
  54. package/.scannerwork/scanner-report/component-61.pb +1 -1
  55. package/.scannerwork/scanner-report/component-62.pb +1 -1
  56. package/.scannerwork/scanner-report/component-63.pb +1 -0
  57. package/.scannerwork/scanner-report/component-64.pb +1 -0
  58. package/.scannerwork/scanner-report/component-65.pb +1 -0
  59. package/.scannerwork/scanner-report/component-66.pb +1 -0
  60. package/.scannerwork/scanner-report/component-67.pb +1 -1
  61. package/.scannerwork/scanner-report/coverages-10.pb +0 -0
  62. package/.scannerwork/scanner-report/coverages-13.pb +0 -0
  63. package/.scannerwork/scanner-report/coverages-15.pb +0 -0
  64. package/.scannerwork/scanner-report/coverages-16.pb +0 -0
  65. package/.scannerwork/scanner-report/coverages-18.pb +0 -0
  66. package/.scannerwork/scanner-report/coverages-31.pb +0 -0
  67. package/.scannerwork/scanner-report/coverages-32.pb +0 -0
  68. package/.scannerwork/scanner-report/coverages-33.pb +0 -0
  69. package/.scannerwork/scanner-report/coverages-34.pb +0 -0
  70. package/.scannerwork/scanner-report/coverages-37.pb +0 -0
  71. package/.scannerwork/scanner-report/coverages-39.pb +0 -0
  72. package/.scannerwork/scanner-report/coverages-40.pb +0 -0
  73. package/.scannerwork/scanner-report/coverages-41.pb +0 -0
  74. package/.scannerwork/scanner-report/coverages-42.pb +0 -0
  75. package/.scannerwork/scanner-report/coverages-43.pb +0 -0
  76. package/.scannerwork/scanner-report/coverages-44.pb +0 -0
  77. package/.scannerwork/scanner-report/{coverages-21.pb → coverages-45.pb} +0 -0
  78. package/.scannerwork/scanner-report/coverages-47.pb +0 -0
  79. package/.scannerwork/scanner-report/coverages-48.pb +0 -0
  80. package/.scannerwork/scanner-report/coverages-49.pb +0 -0
  81. package/.scannerwork/scanner-report/coverages-50.pb +0 -0
  82. package/.scannerwork/scanner-report/coverages-53.pb +0 -0
  83. package/.scannerwork/scanner-report/coverages-55.pb +0 -0
  84. package/.scannerwork/scanner-report/coverages-56.pb +0 -0
  85. package/.scannerwork/scanner-report/coverages-57.pb +0 -0
  86. package/.scannerwork/scanner-report/coverages-58.pb +0 -0
  87. package/.scannerwork/scanner-report/coverages-59.pb +0 -0
  88. package/.scannerwork/scanner-report/coverages-60.pb +0 -0
  89. package/.scannerwork/scanner-report/coverages-61.pb +0 -0
  90. package/.scannerwork/scanner-report/coverages-62.pb +0 -0
  91. package/.scannerwork/scanner-report/coverages-63.pb +0 -0
  92. package/.scannerwork/scanner-report/coverages-64.pb +0 -0
  93. package/.scannerwork/scanner-report/coverages-65.pb +0 -0
  94. package/.scannerwork/scanner-report/coverages-67.pb +0 -0
  95. package/.scannerwork/scanner-report/duplications-10.pb +2 -0
  96. package/.scannerwork/scanner-report/duplications-13.pb +3 -0
  97. package/.scannerwork/scanner-report/duplications-16.pb +3 -0
  98. package/.scannerwork/scanner-report/duplications-32.pb +2 -0
  99. package/.scannerwork/scanner-report/duplications-42.pb +2 -2
  100. package/.scannerwork/scanner-report/duplications-43.pb +0 -2
  101. package/.scannerwork/scanner-report/duplications-44.pb +0 -2
  102. package/.scannerwork/scanner-report/duplications-53.pb +0 -2
  103. package/.scannerwork/scanner-report/duplications-65.pb +2 -0
  104. package/.scannerwork/scanner-report/duplications-66.pb +2 -0
  105. package/.scannerwork/scanner-report/measures-10.pb +0 -0
  106. package/.scannerwork/scanner-report/measures-13.pb +0 -0
  107. package/.scannerwork/scanner-report/measures-15.pb +0 -0
  108. package/.scannerwork/scanner-report/measures-16.pb +0 -0
  109. package/.scannerwork/scanner-report/measures-18.pb +0 -0
  110. package/.scannerwork/scanner-report/measures-31.pb +0 -0
  111. package/.scannerwork/scanner-report/measures-32.pb +0 -0
  112. package/.scannerwork/scanner-report/measures-33.pb +0 -0
  113. package/.scannerwork/scanner-report/measures-34.pb +0 -0
  114. package/.scannerwork/scanner-report/measures-37.pb +0 -0
  115. package/.scannerwork/scanner-report/measures-39.pb +0 -0
  116. package/.scannerwork/scanner-report/measures-40.pb +0 -0
  117. package/.scannerwork/scanner-report/measures-41.pb +0 -0
  118. package/.scannerwork/scanner-report/measures-42.pb +0 -0
  119. package/.scannerwork/scanner-report/measures-43.pb +0 -0
  120. package/.scannerwork/scanner-report/measures-44.pb +0 -0
  121. package/.scannerwork/scanner-report/measures-45.pb +0 -0
  122. package/.scannerwork/scanner-report/measures-47.pb +0 -0
  123. package/.scannerwork/scanner-report/measures-48.pb +0 -0
  124. package/.scannerwork/scanner-report/measures-49.pb +0 -0
  125. package/.scannerwork/scanner-report/measures-50.pb +0 -0
  126. package/.scannerwork/scanner-report/measures-51.pb +0 -0
  127. package/.scannerwork/scanner-report/measures-53.pb +0 -0
  128. package/.scannerwork/scanner-report/measures-55.pb +0 -0
  129. package/.scannerwork/scanner-report/measures-56.pb +0 -0
  130. package/.scannerwork/scanner-report/measures-57.pb +0 -0
  131. package/.scannerwork/scanner-report/measures-58.pb +0 -0
  132. package/.scannerwork/scanner-report/measures-59.pb +0 -0
  133. package/.scannerwork/scanner-report/measures-6.pb +0 -0
  134. package/.scannerwork/scanner-report/measures-60.pb +0 -0
  135. package/.scannerwork/scanner-report/measures-61.pb +0 -0
  136. package/.scannerwork/scanner-report/measures-62.pb +0 -0
  137. package/.scannerwork/scanner-report/measures-63.pb +0 -0
  138. package/.scannerwork/scanner-report/measures-64.pb +0 -0
  139. package/.scannerwork/scanner-report/measures-65.pb +0 -0
  140. package/.scannerwork/scanner-report/measures-66.pb +0 -0
  141. package/.scannerwork/scanner-report/measures-67.pb +0 -0
  142. package/.scannerwork/scanner-report/metadata.pb +0 -0
  143. package/.scannerwork/scanner-report/source-10.txt +170 -80
  144. package/.scannerwork/scanner-report/source-13.txt +141 -415
  145. package/.scannerwork/scanner-report/source-15.txt +18 -77
  146. package/.scannerwork/scanner-report/source-16.txt +192 -20
  147. package/.scannerwork/scanner-report/source-18.txt +169 -15
  148. package/.scannerwork/scanner-report/source-31.txt +100 -0
  149. package/.scannerwork/scanner-report/source-32.txt +183 -0
  150. package/.scannerwork/scanner-report/source-33.txt +101 -0
  151. package/.scannerwork/scanner-report/source-34.txt +37 -0
  152. package/.scannerwork/scanner-report/source-37.txt +12 -55
  153. package/.scannerwork/scanner-report/source-39.txt +15 -267
  154. package/.scannerwork/scanner-report/source-40.txt +104 -165
  155. package/.scannerwork/scanner-report/source-41.txt +136 -115
  156. package/.scannerwork/scanner-report/source-42.txt +157 -153
  157. package/.scannerwork/scanner-report/source-43.txt +262 -148
  158. package/.scannerwork/scanner-report/source-44.txt +23 -173
  159. package/.scannerwork/scanner-report/{source-21.txt → source-45.txt} +10 -9
  160. package/.scannerwork/scanner-report/source-47.txt +75 -0
  161. package/.scannerwork/scanner-report/source-48.txt +449 -0
  162. package/.scannerwork/scanner-report/source-49.txt +42 -41
  163. package/.scannerwork/scanner-report/source-50.txt +57 -89
  164. package/.scannerwork/scanner-report/source-51.txt +424 -75
  165. package/.scannerwork/scanner-report/source-53.txt +390 -68
  166. package/.scannerwork/scanner-report/source-55.txt +145 -110
  167. package/.scannerwork/scanner-report/source-56.txt +88 -23
  168. package/.scannerwork/scanner-report/source-57.txt +55 -256
  169. package/.scannerwork/scanner-report/source-58.txt +90 -88
  170. package/.scannerwork/scanner-report/source-59.txt +14 -24
  171. package/.scannerwork/scanner-report/source-6.txt +102 -60
  172. package/.scannerwork/scanner-report/source-60.txt +103 -92
  173. package/.scannerwork/scanner-report/source-61.txt +24 -14
  174. package/.scannerwork/scanner-report/source-62.txt +40 -61
  175. package/.scannerwork/scanner-report/source-63.txt +118 -0
  176. package/.scannerwork/scanner-report/source-64.txt +46 -0
  177. package/.scannerwork/scanner-report/source-65.txt +92 -0
  178. package/.scannerwork/scanner-report/source-66.txt +75 -0
  179. package/.scannerwork/scanner-report/source-67.txt +281 -424
  180. package/.scannerwork/scanner-report/symbols-10.pb +180 -69
  181. package/.scannerwork/scanner-report/symbols-13.pb +140 -777
  182. package/.scannerwork/scanner-report/symbols-15.pb +19 -58
  183. package/.scannerwork/scanner-report/symbols-16.pb +264 -31
  184. package/.scannerwork/scanner-report/symbols-18.pb +209 -9
  185. package/.scannerwork/scanner-report/symbols-31.pb +69 -0
  186. package/.scannerwork/scanner-report/symbols-32.pb +203 -0
  187. package/.scannerwork/scanner-report/symbols-33.pb +58 -0
  188. package/.scannerwork/scanner-report/symbols-34.pb +9 -0
  189. package/.scannerwork/scanner-report/symbols-37.pb +8 -38
  190. package/.scannerwork/scanner-report/symbols-39.pb +13 -421
  191. package/.scannerwork/scanner-report/symbols-40.pb +86 -209
  192. package/.scannerwork/scanner-report/symbols-41.pb +93 -86
  193. package/.scannerwork/scanner-report/symbols-42.pb +209 -185
  194. package/.scannerwork/scanner-report/symbols-43.pb +420 -152
  195. package/.scannerwork/scanner-report/symbols-44.pb +23 -180
  196. package/.scannerwork/scanner-report/symbols-45.pb +31 -0
  197. package/.scannerwork/scanner-report/symbols-47.pb +39 -0
  198. package/.scannerwork/scanner-report/symbols-48.pb +790 -0
  199. package/.scannerwork/scanner-report/symbols-49.pb +21 -19
  200. package/.scannerwork/scanner-report/symbols-50.pb +32 -46
  201. package/.scannerwork/scanner-report/symbols-53.pb +604 -44
  202. package/.scannerwork/scanner-report/symbols-55.pb +125 -32
  203. package/.scannerwork/scanner-report/symbols-56.pb +58 -19
  204. package/.scannerwork/scanner-report/symbols-57.pb +46 -354
  205. package/.scannerwork/scanner-report/symbols-58.pb +45 -58
  206. package/.scannerwork/scanner-report/symbols-59.pb +13 -17
  207. package/.scannerwork/scanner-report/symbols-60.pb +32 -29
  208. package/.scannerwork/scanner-report/symbols-61.pb +17 -13
  209. package/.scannerwork/scanner-report/symbols-62.pb +18 -45
  210. package/.scannerwork/scanner-report/symbols-63.pb +30 -0
  211. package/.scannerwork/scanner-report/symbols-64.pb +20 -0
  212. package/.scannerwork/scanner-report/symbols-65.pb +44 -0
  213. package/.scannerwork/scanner-report/symbols-67.pb +354 -0
  214. package/.scannerwork/scanner-report/syntax-highlightings-10.pb +187 -69
  215. package/.scannerwork/scanner-report/syntax-highlightings-13.pb +140 -551
  216. package/.scannerwork/scanner-report/syntax-highlightings-15.pb +24 -112
  217. package/.scannerwork/scanner-report/syntax-highlightings-16.pb +258 -31
  218. package/.scannerwork/scanner-report/syntax-highlightings-18.pb +254 -25
  219. package/.scannerwork/scanner-report/syntax-highlightings-31.pb +107 -0
  220. package/.scannerwork/scanner-report/syntax-highlightings-32.pb +280 -0
  221. package/.scannerwork/scanner-report/syntax-highlightings-33.pb +154 -0
  222. package/.scannerwork/scanner-report/syntax-highlightings-34.pb +61 -0
  223. package/.scannerwork/scanner-report/syntax-highlightings-37.pb +18 -65
  224. package/.scannerwork/scanner-report/syntax-highlightings-39.pb +27 -673
  225. package/.scannerwork/scanner-report/syntax-highlightings-40.pb +88 -253
  226. package/.scannerwork/scanner-report/syntax-highlightings-41.pb +202 -90
  227. package/.scannerwork/scanner-report/syntax-highlightings-42.pb +273 -185
  228. package/.scannerwork/scanner-report/syntax-highlightings-43.pb +663 -169
  229. package/.scannerwork/scanner-report/syntax-highlightings-44.pb +23 -192
  230. package/.scannerwork/scanner-report/syntax-highlightings-45.pb +69 -0
  231. package/.scannerwork/scanner-report/syntax-highlightings-47.pb +101 -0
  232. package/.scannerwork/scanner-report/syntax-highlightings-48.pb +625 -0
  233. package/.scannerwork/scanner-report/syntax-highlightings-49.pb +59 -38
  234. package/.scannerwork/scanner-report/syntax-highlightings-50.pb +79 -107
  235. package/.scannerwork/scanner-report/syntax-highlightings-51.pb +3329 -67
  236. package/.scannerwork/scanner-report/syntax-highlightings-53.pb +610 -59
  237. package/.scannerwork/scanner-report/syntax-highlightings-55.pb +170 -86
  238. package/.scannerwork/scanner-report/syntax-highlightings-56.pb +98 -29
  239. package/.scannerwork/scanner-report/syntax-highlightings-57.pb +55 -245
  240. package/.scannerwork/scanner-report/syntax-highlightings-58.pb +89 -96
  241. package/.scannerwork/scanner-report/syntax-highlightings-59.pb +16 -21
  242. package/.scannerwork/scanner-report/syntax-highlightings-6.pb +668 -56
  243. package/.scannerwork/scanner-report/syntax-highlightings-60.pb +91 -75
  244. package/.scannerwork/scanner-report/syntax-highlightings-61.pb +21 -16
  245. package/.scannerwork/scanner-report/syntax-highlightings-62.pb +26 -62
  246. package/.scannerwork/scanner-report/syntax-highlightings-63.pb +113 -0
  247. package/.scannerwork/scanner-report/syntax-highlightings-64.pb +64 -0
  248. package/.scannerwork/scanner-report/syntax-highlightings-65.pb +90 -0
  249. package/.scannerwork/scanner-report/syntax-highlightings-66.pb +78 -0
  250. package/.scannerwork/scanner-report/syntax-highlightings-67.pb +199 -3256
  251. package/package.json +1 -1
  252. package/test-18-results.xml +175 -175
  253. package/test-iam-18-results.xml +49 -49
  254. package/.scannerwork/scanner-report/changesets-11.pb +0 -1
  255. package/.scannerwork/scanner-report/changesets-12.pb +0 -1
  256. package/.scannerwork/scanner-report/changesets-14.pb +0 -1
  257. package/.scannerwork/scanner-report/changesets-20.pb +0 -1
  258. package/.scannerwork/scanner-report/changesets-21.pb +0 -1
  259. package/.scannerwork/scanner-report/changesets-22.pb +0 -1
  260. package/.scannerwork/scanner-report/changesets-23.pb +0 -1
  261. package/.scannerwork/scanner-report/changesets-24.pb +0 -1
  262. package/.scannerwork/scanner-report/changesets-25.pb +0 -1
  263. package/.scannerwork/scanner-report/changesets-5.pb +0 -1
  264. package/.scannerwork/scanner-report/changesets-51.pb +0 -1
  265. package/.scannerwork/scanner-report/changesets-52.pb +0 -1
  266. package/.scannerwork/scanner-report/changesets-6.pb +0 -1
  267. package/.scannerwork/scanner-report/changesets-7.pb +0 -1
  268. package/.scannerwork/scanner-report/changesets-8.pb +0 -1
  269. package/.scannerwork/scanner-report/changesets-9.pb +0 -1
  270. package/.scannerwork/scanner-report/component-11.pb +0 -1
  271. package/.scannerwork/scanner-report/component-12.pb +0 -1
  272. package/.scannerwork/scanner-report/component-14.pb +0 -1
  273. package/.scannerwork/scanner-report/component-2.pb +0 -1
  274. package/.scannerwork/scanner-report/component-20.pb +0 -1
  275. package/.scannerwork/scanner-report/component-21.pb +0 -1
  276. package/.scannerwork/scanner-report/component-22.pb +0 -1
  277. package/.scannerwork/scanner-report/component-23.pb +0 -1
  278. package/.scannerwork/scanner-report/component-24.pb +0 -1
  279. package/.scannerwork/scanner-report/component-25.pb +0 -1
  280. package/.scannerwork/scanner-report/component-5.pb +0 -1
  281. package/.scannerwork/scanner-report/component-52.pb +0 -1
  282. package/.scannerwork/scanner-report/component-7.pb +0 -1
  283. package/.scannerwork/scanner-report/component-8.pb +0 -1
  284. package/.scannerwork/scanner-report/component-9.pb +0 -1
  285. package/.scannerwork/scanner-report/coverages-11.pb +0 -0
  286. package/.scannerwork/scanner-report/coverages-12.pb +0 -0
  287. package/.scannerwork/scanner-report/coverages-20.pb +0 -0
  288. package/.scannerwork/scanner-report/coverages-23.pb +0 -0
  289. package/.scannerwork/scanner-report/coverages-25.pb +0 -0
  290. package/.scannerwork/scanner-report/coverages-5.pb +0 -0
  291. package/.scannerwork/scanner-report/coverages-52.pb +0 -0
  292. package/.scannerwork/scanner-report/coverages-6.pb +0 -0
  293. package/.scannerwork/scanner-report/coverages-7.pb +0 -0
  294. package/.scannerwork/scanner-report/coverages-9.pb +0 -0
  295. package/.scannerwork/scanner-report/duplications-23.pb +0 -3
  296. package/.scannerwork/scanner-report/duplications-51.pb +0 -2
  297. package/.scannerwork/scanner-report/duplications-9.pb +0 -2
  298. package/.scannerwork/scanner-report/measures-11.pb +0 -15
  299. package/.scannerwork/scanner-report/measures-12.pb +0 -0
  300. package/.scannerwork/scanner-report/measures-2.pb +0 -0
  301. package/.scannerwork/scanner-report/measures-20.pb +0 -0
  302. package/.scannerwork/scanner-report/measures-21.pb +0 -0
  303. package/.scannerwork/scanner-report/measures-23.pb +0 -0
  304. package/.scannerwork/scanner-report/measures-25.pb +0 -0
  305. package/.scannerwork/scanner-report/measures-5.pb +0 -0
  306. package/.scannerwork/scanner-report/measures-52.pb +0 -0
  307. package/.scannerwork/scanner-report/measures-7.pb +0 -0
  308. package/.scannerwork/scanner-report/measures-9.pb +0 -0
  309. package/.scannerwork/scanner-report/source-11.txt +0 -151
  310. package/.scannerwork/scanner-report/source-12.txt +0 -37
  311. package/.scannerwork/scanner-report/source-2.txt +0 -102
  312. package/.scannerwork/scanner-report/source-20.txt +0 -32
  313. package/.scannerwork/scanner-report/source-23.txt +0 -213
  314. package/.scannerwork/scanner-report/source-25.txt +0 -42
  315. package/.scannerwork/scanner-report/source-5.txt +0 -414
  316. package/.scannerwork/scanner-report/source-52.txt +0 -164
  317. package/.scannerwork/scanner-report/source-7.txt +0 -81
  318. package/.scannerwork/scanner-report/source-9.txt +0 -187
  319. package/.scannerwork/scanner-report/symbols-11.pb +0 -93
  320. package/.scannerwork/scanner-report/symbols-12.pb +0 -13
  321. package/.scannerwork/scanner-report/symbols-20.pb +0 -9
  322. package/.scannerwork/scanner-report/symbols-21.pb +0 -23
  323. package/.scannerwork/scanner-report/symbols-23.pb +0 -264
  324. package/.scannerwork/scanner-report/symbols-25.pb +0 -19
  325. package/.scannerwork/scanner-report/symbols-5.pb +0 -604
  326. package/.scannerwork/scanner-report/symbols-52.pb +0 -126
  327. package/.scannerwork/scanner-report/symbols-6.pb +0 -21
  328. package/.scannerwork/scanner-report/symbols-7.pb +0 -32
  329. package/.scannerwork/scanner-report/symbols-9.pb +0 -227
  330. package/.scannerwork/scanner-report/syntax-highlightings-11.pb +0 -237
  331. package/.scannerwork/scanner-report/syntax-highlightings-12.pb +0 -62
  332. package/.scannerwork/scanner-report/syntax-highlightings-2.pb +0 -692
  333. package/.scannerwork/scanner-report/syntax-highlightings-20.pb +0 -54
  334. package/.scannerwork/scanner-report/syntax-highlightings-21.pb +0 -56
  335. package/.scannerwork/scanner-report/syntax-highlightings-23.pb +0 -296
  336. package/.scannerwork/scanner-report/syntax-highlightings-25.pb +0 -66
  337. package/.scannerwork/scanner-report/syntax-highlightings-5.pb +0 -641
  338. package/.scannerwork/scanner-report/syntax-highlightings-52.pb +0 -213
  339. package/.scannerwork/scanner-report/syntax-highlightings-7.pb +0 -98
  340. package/.scannerwork/scanner-report/syntax-highlightings-9.pb +0 -368
  341. /package/.scannerwork/scanner-report/{coverages-14.pb → coverages-35.pb} +0 -0
  342. /package/.scannerwork/scanner-report/{coverages-24.pb → coverages-36.pb} +0 -0
  343. /package/.scannerwork/scanner-report/{coverages-8.pb → coverages-4.pb} +0 -0
  344. /package/.scannerwork/scanner-report/{coverages-22.pb → coverages-46.pb} +0 -0
  345. /package/.scannerwork/scanner-report/{coverages-51.pb → coverages-66.pb} +0 -0
  346. /package/.scannerwork/scanner-report/{duplications-11.pb → duplications-31.pb} +0 -0
  347. /package/.scannerwork/scanner-report/{duplications-12.pb → duplications-33.pb} +0 -0
  348. /package/.scannerwork/scanner-report/{duplications-14.pb → duplications-34.pb} +0 -0
  349. /package/.scannerwork/scanner-report/{duplications-20.pb → duplications-35.pb} +0 -0
  350. /package/.scannerwork/scanner-report/{duplications-21.pb → duplications-36.pb} +0 -0
  351. /package/.scannerwork/scanner-report/{duplications-22.pb → duplications-4.pb} +0 -0
  352. /package/.scannerwork/scanner-report/{duplications-24.pb → duplications-45.pb} +0 -0
  353. /package/.scannerwork/scanner-report/{duplications-25.pb → duplications-46.pb} +0 -0
  354. /package/.scannerwork/scanner-report/{duplications-5.pb → duplications-47.pb} +0 -0
  355. /package/.scannerwork/scanner-report/{duplications-52.pb → duplications-48.pb} +0 -0
  356. /package/.scannerwork/scanner-report/{duplications-6.pb → duplications-63.pb} +0 -0
  357. /package/.scannerwork/scanner-report/{duplications-7.pb → duplications-64.pb} +0 -0
  358. /package/.scannerwork/scanner-report/{duplications-8.pb → duplications-67.pb} +0 -0
  359. /package/.scannerwork/scanner-report/{issues-25.pb → issues-15.pb} +0 -0
  360. /package/.scannerwork/scanner-report/{issues-23.pb → issues-16.pb} +0 -0
  361. /package/.scannerwork/scanner-report/{issues-24.pb → issues-36.pb} +0 -0
  362. /package/.scannerwork/scanner-report/{issues-41.pb → issues-40.pb} +0 -0
  363. /package/.scannerwork/scanner-report/{measures-14.pb → measures-35.pb} +0 -0
  364. /package/.scannerwork/scanner-report/{measures-24.pb → measures-36.pb} +0 -0
  365. /package/.scannerwork/scanner-report/{measures-8.pb → measures-4.pb} +0 -0
  366. /package/.scannerwork/scanner-report/{measures-22.pb → measures-46.pb} +0 -0
  367. /package/.scannerwork/scanner-report/{source-14.txt → source-35.txt} +0 -0
  368. /package/.scannerwork/scanner-report/{source-24.txt → source-36.txt} +0 -0
  369. /package/.scannerwork/scanner-report/{source-8.txt → source-4.txt} +0 -0
  370. /package/.scannerwork/scanner-report/{source-22.txt → source-46.txt} +0 -0
  371. /package/.scannerwork/scanner-report/{symbols-14.pb → symbols-35.pb} +0 -0
  372. /package/.scannerwork/scanner-report/{symbols-24.pb → symbols-36.pb} +0 -0
  373. /package/.scannerwork/scanner-report/{symbols-8.pb → symbols-4.pb} +0 -0
  374. /package/.scannerwork/scanner-report/{symbols-22.pb → symbols-46.pb} +0 -0
  375. /package/.scannerwork/scanner-report/{symbols-51.pb → symbols-66.pb} +0 -0
  376. /package/.scannerwork/scanner-report/{syntax-highlightings-14.pb → syntax-highlightings-35.pb} +0 -0
  377. /package/.scannerwork/scanner-report/{syntax-highlightings-24.pb → syntax-highlightings-36.pb} +0 -0
  378. /package/.scannerwork/scanner-report/{syntax-highlightings-8.pb → syntax-highlightings-4.pb} +0 -0
  379. /package/.scannerwork/scanner-report/{syntax-highlightings-22.pb → syntax-highlightings-46.pb} +0 -0
@@ -1,4 +1,4 @@
1
- // Copyright © 2017, 2018 IBM Corp. All rights reserved.
1
+ // Copyright © 2017, 2023 IBM Corp. All rights reserved.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -12,164 +12,278 @@
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
14
 
15
- // Small script which backs up a Cloudant or CouchDB database to an S3
16
- // bucket via a stream rather than on-disk file.
17
- //
18
- // The script generates the backup object name by combining together the path
19
- // part of the database URL and the current time.
20
-
15
+ /* global describe it before after beforeEach */
21
16
  'use strict';
22
17
 
23
- const stream = require('stream');
24
- const url = require('url');
25
-
26
- const AWS = require('aws-sdk');
27
- const couchbackup = require('@cloudant/couchbackup');
28
- const debug = require('debug')('s3-backup');
29
- const VError = require('verror').VError;
30
-
31
- /*
32
- Main function, run from base of file.
33
- */
34
- function main() {
35
- const argv = require('yargs')
36
- .usage('Usage: $0 [options]')
37
- .example('$0 -s https://user:pass@host/db -b <bucket>', 'Backup db to bucket')
38
- .options({
39
- source: { alias: 's', nargs: 1, demandOption: true, describe: 'Source database URL' },
40
- bucket: { alias: 'b', nargs: 1, demandOption: true, describe: 'Destination bucket' },
41
- prefix: { alias: 'p', nargs: 1, describe: 'Prefix for backup object key', default: 'couchbackup' },
42
- s3url: { nargs: 1, describe: 'S3 endpoint URL' },
43
- awsprofile: { nargs: 1, describe: 'The profile section to use in the ~/.aws/credentials file', default: 'default' }
44
- })
45
- .help('h').alias('h', 'help')
46
- .epilog('Copyright (C) IBM 2017')
47
- .argv;
48
-
49
- const sourceUrl = argv.source;
50
- const backupName = new url.URL(sourceUrl).pathname.split('/').filter(function(x) { return x; }).join('-');
51
- const backupBucket = argv.bucket;
52
- const backupKeyPrefix = `${argv.prefix}-${backupName}`;
53
- const shallow = argv.shallow;
54
-
55
- const backupKey = `${backupKeyPrefix}-${new Date().toISOString()}`;
56
-
57
- const s3Endpoint = argv.s3url;
58
- const awsProfile = argv.awsprofile;
59
-
60
- // Creds are from ~/.aws/credentials, environment etc. (see S3 docs).
61
- const awsOpts = {
62
- signatureVersion: 'v4',
63
- credentials: new AWS.SharedIniFileCredentials({ profile: awsProfile })
64
- };
65
- if (typeof s3Endpoint !== 'undefined') {
66
- awsOpts.endpoint = new AWS.Endpoint(s3Endpoint);
18
+ const assert = require('assert');
19
+ const fs = require('fs');
20
+ const u = require('./citestutils.js');
21
+ const mockServerPort = +process.env.COUCHBACKUP_MOCK_SERVER_PORT || 7777;
22
+ const { once } = require('node:events');
23
+ const url = `http://localhost:${mockServerPort}`;
24
+ const nock = require('nock');
25
+ const httpProxy = require('http-proxy');
26
+ const Readable = require('stream').Readable;
27
+
28
+ // Create an infinite stream to read.
29
+ // It just keeps sending a backup line, useful for testing cases of
30
+ // termination while a stream has content remaining (the animaldb backup
31
+ // is too small for that).
32
+ class InfiniteBackupStream extends Readable {
33
+ constructor(opt) {
34
+ super(opt);
35
+ this.contents = Buffer.from('[{"_id":"giraffe","_rev":"3-7665c3e66315ff40616cceef62886bd8","min_weight":830,"min_length":5,"max_weight":1600,"max_length":6,"wiki_page":"http://en.wikipedia.org/wiki/Giraffe","class":"mammal","diet":"herbivore","_revisions":{"start":3,"ids":["7665c3e66315ff40616cceef62886bd8","aaaf10d5a68cdf22d95a5482a0e95549","967a00dff5e02add41819138abb3284d"]}}]\n', 'utf8');
67
36
  }
68
- const s3 = new AWS.S3(awsOpts);
69
37
 
70
- debug(`Creating a new backup of ${s(sourceUrl)} at ${backupBucket}/${backupKey}...`);
71
- bucketAccessible(s3, backupBucket)
72
- .then(() => {
73
- return backupToS3(sourceUrl, s3, backupBucket, backupKey, shallow);
74
- })
38
+ _read() {
39
+ let proceed;
40
+ do {
41
+ proceed = this.push(this.contents);
42
+ } while (proceed);
43
+ }
44
+ }
45
+
46
+ function assertNock() {
47
+ try {
48
+ assert.ok(nock.isDone());
49
+ } catch (err) {
50
+ console.error('pending mocks: %j', nock.pendingMocks());
51
+ throw err;
52
+ }
53
+ }
54
+
55
+ function testPromiseWithAssertNock(testPromise) {
56
+ return testPromise.finally(() => {
57
+ assertNock();
58
+ });
59
+ }
60
+
61
+ async function backupHttpError(opts, errorName, errorCode) {
62
+ const p = u.p(opts, { expectedBackupError: { name: errorName, code: errorCode } });
63
+
64
+ // Create a file and attempt a backup to it
65
+ const output = fs.createWriteStream('/dev/null');
66
+ return once(output, 'open')
75
67
  .then(() => {
76
- debug('done.');
77
- })
78
- .catch((reason) => {
79
- debug(`Error: ${reason}`);
80
- process.exit(1);
68
+ return testPromiseWithAssertNock(u.testBackup(p, 'fakenockdb', output));
81
69
  });
82
70
  }
83
71
 
84
- /**
85
- * Return a promise that resolves if the bucket is available and
86
- * rejects if not.
87
- *
88
- * @param {any} s3 S3 client object
89
- * @param {any} bucketName Bucket name
90
- * @returns Promise
91
- */
92
- function bucketAccessible(s3, bucketName) {
93
- return new Promise(function(resolve, reject) {
94
- const params = {
95
- Bucket: bucketName
96
- };
97
- s3.headBucket(params, function(err, data) {
98
- if (err) {
99
- reject(new VError(err, 'S3 bucket not accessible'));
100
- } else {
101
- resolve();
102
- }
103
- });
104
- });
72
+ async function restoreHttpError(opts, errorName, errorCode) {
73
+ const q = u.p(opts, { expectedRestoreError: { name: errorName, code: errorCode } });
74
+ return testPromiseWithAssertNock(u.testRestoreFromFile(q, './test/fixtures/animaldb_expected.json', 'fakenockdb'));
105
75
  }
106
76
 
107
- /**
108
- * Backup directly from Cloudant to an object store object via a stream.
109
- *
110
- * @param {any} sourceUrl URL of database
111
- * @param {any} s3Client Object store client
112
- * @param {any} s3Bucket Backup destination bucket
113
- * @param {any} s3Key Backup destination key name (shouldn't exist)
114
- * @param {any} shallow Whether to use the couchbackup `shallow` mode
115
- * @returns Promise
116
- */
117
- function backupToS3(sourceUrl, s3Client, s3Bucket, s3Key, shallow) {
118
- return new Promise((resolve, reject) => {
119
- debug(`Setting up S3 upload to ${s3Bucket}/${s3Key}`);
120
-
121
- // A pass through stream that has couchbackup's output
122
- // written to it and it then read by the S3 upload client.
123
- // It has a 64MB highwater mark to allow for fairly
124
- // uneven network connectivity.
125
- const streamToUpload = new stream.PassThrough({ highWaterMark: 67108864 });
126
-
127
- // Set up S3 upload.
128
- const params = {
129
- Bucket: s3Bucket,
130
- Key: s3Key,
131
- Body: streamToUpload
132
- };
133
- s3Client.upload(params, function(err, data) {
134
- debug('Object store upload done');
135
- if (err) {
136
- debug(err);
137
- reject(new VError(err, 'Object store upload failed'));
138
- return;
77
+ [{ useApi: true }, { useApi: false }].forEach(function(params) {
78
+ describe(u.scenario('#unit Fatal errors', params), function() {
79
+ let processEnvCopy;
80
+ let proxy;
81
+
82
+ before('Set process data for test', function() {
83
+ const proxyPort = mockServerPort + 1000;
84
+ // Copy env and argv so we can reset them after the tests
85
+ processEnvCopy = JSON.parse(JSON.stringify(process.env));
86
+
87
+ // Set up a proxy to point to our nock server because the nock override
88
+ // isn't visible to the spawned CLI process
89
+ if (!params.useApi) {
90
+ proxy = httpProxy.createProxyServer({ target: url }).listen(proxyPort, 'localhost');
91
+ proxy.on('error', (err, req, res) => {
92
+ console.log(`Proxy received error ${err}`);
93
+ res.writeHead(400, {
94
+ 'Content-Type': 'application/json'
95
+ });
96
+ res.end(JSON.stringify(err));
97
+ });
139
98
  }
140
- debug('Object store upload succeeded');
141
- debug(data);
142
- resolve();
143
- }).httpUploadProgress = (progress) => {
144
- debug(`Object store upload progress: ${progress}`);
145
- };
146
-
147
- debug(`Starting streaming data from ${s(sourceUrl)}`);
148
- couchbackup.backup(
149
- sourceUrl,
150
- streamToUpload,
151
- (err, obj) => {
152
- if (err) {
153
- debug(err);
154
- reject(new VError(err, 'CouchBackup failed with an error'));
155
- return;
156
- }
157
- debug(`Download from ${s(sourceUrl)} complete.`);
158
- streamToUpload.end(); // must call end() to complete upload.
159
- // resolve() is called by the upload
99
+
100
+ // setup environment variables
101
+ process.env.COUCH_URL = (params.useApi) ? url : `http://localhost:${proxyPort}`;
102
+
103
+ nock.emitter.on('no match', (req, opts) => {
104
+ console.error(`Unmatched nock request ${opts.method} ${opts.protocol}${opts.host}${opts.path}`);
105
+ });
106
+ });
107
+
108
+ after('Reset process data', function(done) {
109
+ process.env = processEnvCopy;
110
+ nock.emitter.removeAllListeners();
111
+ if (!params.useApi) {
112
+ proxy.close(done);
113
+ } else {
114
+ done();
160
115
  }
161
- );
162
- });
163
- }
116
+ });
164
117
 
165
- /**
166
- * Remove creds from a URL, e.g., before logging
167
- *
168
- * @param {string} url URL to safen
169
- */
170
- function s(originalUrl) {
171
- const parts = new url.URL(originalUrl);
172
- return url.format(parts, { auth: false });
173
- }
118
+ beforeEach('Reset nocks', function() {
119
+ nock.cleanAll();
120
+ });
121
+
122
+ describe('for backup', function() {
123
+ it('should terminate when DB does not exist', function() {
124
+ // Simulate existence check
125
+ nock(url).head('/fakenockdb').reply(404, { error: 'not_found', reason: 'missing' });
126
+ return backupHttpError(params, 'DatabaseNotFound', 10);
127
+ });
128
+
129
+ it('should terminate on BulkGetError', function() {
130
+ // Simulate existence check
131
+ const n = nock(url).head('/fakenockdb').reply(200);
132
+ // Simulate _bulk_get not available
133
+ n.post('/fakenockdb/_bulk_get').reply(404, { error: 'not_found', reason: 'missing' });
134
+ return backupHttpError(params, 'BulkGetError', 50);
135
+ });
136
+
137
+ it('should terminate on Unauthorized existence check', function() {
138
+ // Simulate a 401
139
+ nock(url).head('/fakenockdb').reply(401, { error: 'unauthorized', reason: '_reader access is required for this request' });
140
+ return backupHttpError(params, 'Unauthorized', 11);
141
+ });
142
+
143
+ it('should terminate on Forbidden no _reader', function() {
144
+ // Simulate a 403
145
+ nock(url).head('/fakenockdb').reply(403, { error: 'forbidden', reason: '_reader access is required for this request' });
146
+ return backupHttpError(params, 'Forbidden', 12);
147
+ });
148
+
149
+ it('should terminate on _bulk_get HTTPFatalError', function() {
150
+ // Provide a mock complete changes log to allow a resume to skip ahead
151
+ const p = u.p(params, { opts: { resume: true, log: './test/fixtures/test.log' } });
152
+ // Allow the existence and _bulk_get checks to pass
153
+ const n = nock(url).head('/fakenockdb').reply(200);
154
+ n.post('/fakenockdb/_bulk_get').reply(200, '{"results": []}');
155
+ // Simulate a fatal HTTP error when trying to fetch docs
156
+ // Note: 2 outstanding batches, so 2 responses, 1 mock is optional because we can't guarantee timing
157
+ n.post('/fakenockdb/_bulk_get').query(true).reply(400, { error: 'bad_request', reason: 'testing bad response' });
158
+ n.post('/fakenockdb/_bulk_get').query(true).optionally().reply(400, { error: 'bad_request', reason: 'testing bad response' });
159
+ return backupHttpError(p, 'HTTPFatalError', 40);
160
+ });
161
+
162
+ it('should terminate on NoLogFileName', function() {
163
+ // Don't supply a log file name with resume
164
+ const p = u.p(params, { opts: { resume: true } });
165
+ return backupHttpError(p, 'NoLogFileName', 20);
166
+ });
167
+
168
+ it('should terminate on LogDoesNotExist', function() {
169
+ // Use a non-existent log file
170
+ const p = u.p(params, { opts: { resume: true, log: './test/fixtures/doesnotexist.log' } });
171
+ return backupHttpError(p, 'LogDoesNotExist', 21);
172
+ });
173
+
174
+ it('should terminate on IncompleteChangesInLogFile', function() {
175
+ // Use an incomplete changes log file
176
+ const p = u.p(params, { opts: { resume: true, log: './test/fixtures/incomplete_changes.log' } });
177
+ // Allow the existence and _bulk_get checks to pass
178
+ const n = nock(url).head('/fakenockdb').reply(200);
179
+ n.post('/fakenockdb/_bulk_get').reply(200, '{"results": []}');
180
+ // Should fail when it reads the incomplete changes
181
+ return backupHttpError(p, 'IncompleteChangesInLogFile', 22);
182
+ });
183
+
184
+ it('should terminate on _changes HTTPFatalError', function() {
185
+ // Allow the existence and _bulk_get checks to pass
186
+ const n = nock(url).head('/fakenockdb').reply(200);
187
+ n.post('/fakenockdb/_bulk_get').reply(200, '{"results": []}');
188
+ // Simulate a fatal HTTP error when trying to fetch docs (note 2 outstanding batches)
189
+ n.post('/fakenockdb/_changes').query(true).reply(400, { error: 'bad_request', reason: 'testing bad response' });
190
+ return backupHttpError(params, 'HTTPFatalError', 40);
191
+ });
174
192
 
175
- main();
193
+ it('should terminate on SpoolChangesError', function() {
194
+ // Allow the existence and _bulk_get checks to pass
195
+ const n = nock(url).head('/fakenockdb').reply(200);
196
+ n.post('/fakenockdb/_bulk_get').reply(200, '{"results": []}');
197
+ // Simulate a changes without a last_seq
198
+ n.post('/fakenockdb/_changes').query(true).reply(200,
199
+ {
200
+ results: [{
201
+ seq: '2-g1AAAAEbeJzLYWBgYMlgTmFQSElKzi9KdUhJstTLTS3KLElMT9VLzskvTUnMK9HLSy3JAapkSmRIsv___39WBnMiUy5QgN3MzDIxOdEMWb85dv0gSxThigyN8diS5AAkk-pBFiUyoOkzxKMvjwVIMjQAKaDW_Zh6TQnqPQDRC7I3CwDPDV1k',
202
+ id: 'badger',
203
+ changes: [{ rev: '4-51aa94e4b0ef37271082033bba52b850' }]
204
+ }]
205
+ });
206
+ return backupHttpError(params, 'SpoolChangesError', 30);
207
+ });
208
+ });
209
+
210
+ describe('for restore', function() {
211
+ it('should terminate on Unauthorized db existence check', function() {
212
+ // Simulate a 401
213
+ nock(url).get('/fakenockdb').reply(401, { error: 'unauthorized', reason: '_reader access is required for this request' });
214
+ return restoreHttpError(params, 'Unauthorized', 11);
215
+ });
216
+
217
+ it('should terminate on Forbidden no _writer', function() {
218
+ // Simulate the DB exists (i.e. you can read it)
219
+ const n = nock(url).get('/fakenockdb').reply(200, { doc_count: 0, doc_del_count: 0 });
220
+ // Simulate a 403 trying to write
221
+ n.post('/fakenockdb/_bulk_docs').reply(403, { error: 'forbidden', reason: '_writer access is required for this request' });
222
+ return restoreHttpError(params, 'Forbidden', 12);
223
+ });
224
+
225
+ it('should terminate on RestoreDatabaseNotFound', function() {
226
+ // Simulate the DB does not exist
227
+ nock(url).get('/fakenockdb').reply(404, { error: 'not_found', reason: 'Database does not exist.' });
228
+ return restoreHttpError(params, 'DatabaseNotFound', 10);
229
+ });
230
+
231
+ it('should terminate on notEmptyDBErr when database is not empty', function() {
232
+ // Simulate the DB that does exist and not empty
233
+ nock(url).get('/fakenockdb').reply(200, { doc_count: 10, doc_del_count: 0 });
234
+ return restoreHttpError(params, 'DatabaseNotEmpty', 13);
235
+ });
236
+
237
+ it('should terminate on notEmptyDBErr when database is not new', function() {
238
+ // Simulate the DB that does exist and not new
239
+ nock(url).get('/fakenockdb').reply(200, { doc_count: 0, doc_del_count: 10 });
240
+ return restoreHttpError(params, 'DatabaseNotEmpty', 13);
241
+ });
242
+
243
+ it('should terminate on _bulk_docs HTTPFatalError', function() {
244
+ // Simulate the DB exists
245
+ const n = nock(url).get('/fakenockdb').reply(200, { doc_count: 0, doc_del_count: 0 });
246
+ // Use a parallelism of one and mock one response
247
+ const p = u.p(params, { opts: { parallelism: 1 } });
248
+ // Simulate a 400 trying to write
249
+ n.post('/fakenockdb/_bulk_docs').reply(400, { error: 'bad_request', reason: 'testing bad response' });
250
+ return restoreHttpError(p, 'HTTPFatalError', 40);
251
+ });
252
+
253
+ it('should terminate on _bulk_docs HTTPFatalError from system database', function() {
254
+ // Simulate that target database exists and is _not_ empty.
255
+ // This should pass validator as we exclude system databases from the check.
256
+ const n = nock(url).get('/_replicator').reply(200, { doc_count: 1, doc_del_count: 0 });
257
+ // Simulate a 400 trying to write
258
+ n.post('/_replicator/_bulk_docs').reply(400, { error: 'bad_request', reason: 'testing bad response' });
259
+ // Use a parallelism of one and mock one response
260
+ const q = u.p(params, { opts: { parallelism: 1 }, expectedRestoreError: { name: 'HTTPFatalError', code: 40 } });
261
+ return testPromiseWithAssertNock(u.testRestore(q, new InfiniteBackupStream(), '_replicator'));
262
+ });
263
+
264
+ it('should terminate on _bulk_docs HTTPFatalError large stream', function() {
265
+ // Simulate the DB exists
266
+ const n = nock(url).get('/fakenockdb').reply(200, { doc_count: 0, doc_del_count: 0 });
267
+ // Simulate a 400 trying to write
268
+ // Provide a body function to handle the stream, but allow any body
269
+ n.post('/fakenockdb/_bulk_docs', function(body) { return true; }).reply(400, { error: 'bad_request', reason: 'testing bad response' });
270
+ // Use only parallelism 1 so we don't have to mock up loads of responses
271
+ const q = u.p(params, { opts: { parallelism: 1 }, expectedRestoreError: { name: 'HTTPFatalError', code: 40 } });
272
+ return testPromiseWithAssertNock(u.testRestore(q, new InfiniteBackupStream(), 'fakenockdb'));
273
+ });
274
+
275
+ it('should terminate on multiple _bulk_docs HTTPFatalError', function() {
276
+ // Simulate the DB exists
277
+ const n = nock(url).get('/fakenockdb').reply(200, { doc_count: 0, doc_del_count: 0 });
278
+ // Simulate a 400 trying to write docs, 5 times because of default parallelism
279
+ // Provide a body function to handle the stream, but allow any body
280
+ // Four of the mocks are optional because of parallelism 5 we can't guarantee that the exit will happen
281
+ // after all 5 requests, but we must get at least one of them
282
+ n.post('/fakenockdb/_bulk_docs', function(body) { return true; }).reply(400, { error: 'bad_request', reason: 'testing bad response' });
283
+ n.post('/fakenockdb/_bulk_docs', function(body) { return true; }).times(4).optionally().reply(400, { error: 'bad_request', reason: 'testing bad response' });
284
+ const q = u.p(params, { opts: { bufferSize: 1 }, expectedRestoreError: { name: 'HTTPFatalError', code: 40 } });
285
+ return restoreHttpError(q, 'HTTPFatalError', 40);
286
+ });
287
+ });
288
+ });
289
+ });
@@ -1,4 +1,4 @@
1
- // Copyright © 2017, 2018 IBM Corp. All rights reserved.
1
+ // Copyright © 2017, 2023 IBM Corp. All rights reserved.
2
2
  //
3
3
  // Licensed under the Apache License, Version 2.0 (the "License");
4
4
  // you may not use this file except in compliance with the License.
@@ -12,179 +12,29 @@
12
12
  // See the License for the specific language governing permissions and
13
13
  // limitations under the License.
14
14
 
15
- // Small script which backs up a Cloudant or CouchDB database to an S3
16
- // bucket, using an intermediary file on disk.
17
- //
18
- // The script generates the backup object name by combining together the path
19
- // part of the database URL and the current time.
20
-
15
+ /* global describe it */
21
16
  'use strict';
22
17
 
23
- const stream = require('stream');
24
- const fs = require('fs');
25
- const url = require('url');
26
-
27
- const AWS = require('aws-sdk');
28
- const couchbackup = require('@cloudant/couchbackup');
29
- const debug = require('debug')('s3-backup');
30
- const tmp = require('tmp');
31
- const VError = require('verror').VError;
32
-
33
- /*
34
- Main function, run from base of file.
35
- */
36
- function main() {
37
- const argv = require('yargs')
38
- .usage('Usage: $0 [options]')
39
- .example('$0 -s https://user:pass@host/db -b <bucket>', 'Backup db to bucket')
40
- .options({
41
- source: { alias: 's', nargs: 1, demandOption: true, describe: 'Source database URL' },
42
- bucket: { alias: 'b', nargs: 1, demandOption: true, describe: 'Destination bucket' },
43
- prefix: { alias: 'p', nargs: 1, describe: 'Prefix for backup object key', default: 'couchbackup' },
44
- s3url: { nargs: 1, describe: 'S3 endpoint URL' },
45
- awsprofile: { nargs: 1, describe: 'The profile section to use in the ~/.aws/credentials file', default: 'default' }
46
- })
47
- .help('h').alias('h', 'help')
48
- .epilog('Copyright (C) IBM 2017')
49
- .argv;
50
-
51
- const sourceUrl = argv.source;
52
- const backupBucket = argv.bucket;
53
- const backupName = new url.URL(sourceUrl).pathname.split('/').filter(function(x) { return x; }).join('-');
54
- const backupKeyPrefix = `${argv.prefix}-${backupName}`;
55
-
56
- const backupKey = `${backupKeyPrefix}-${new Date().toISOString()}`;
57
- const backupTmpFile = tmp.fileSync();
58
-
59
- const s3Endpoint = argv.s3url;
60
- const awsProfile = argv.awsprofile;
61
-
62
- // Creds are from ~/.aws/credentials, environment etc. (see S3 docs).
63
- const awsOpts = {
64
- signatureVersion: 'v4',
65
- credentials: new AWS.SharedIniFileCredentials({ profile: awsProfile })
66
- };
67
- if (typeof s3Endpoint !== 'undefined') {
68
- awsOpts.endpoint = new AWS.Endpoint(s3Endpoint);
69
- }
70
- const s3 = new AWS.S3(awsOpts);
71
-
72
- debug(`Creating a new backup of ${s(sourceUrl)} at ${backupBucket}/${backupKey}...`);
73
- bucketAccessible(s3, backupBucket)
74
- .then(() => {
75
- return createBackupFile(sourceUrl, backupTmpFile.name);
76
- })
77
- .then(() => {
78
- return uploadNewBackup(s3, backupTmpFile.name, backupBucket, backupKey);
79
- })
80
- .then(() => {
81
- debug('Backup successful!');
82
- backupTmpFile.removeCallback();
83
- debug('done.');
84
- })
85
- .catch((reason) => {
86
- debug(`Error: ${reason}`);
87
- });
88
- }
89
-
90
- /**
91
- * Return a promise that resolves if the bucket is available and
92
- * rejects if not.
93
- *
94
- * @param {any} s3 S3 client object
95
- * @param {any} bucketName Bucket name
96
- * @returns Promise
97
- */
98
- function bucketAccessible(s3, bucketName) {
99
- return new Promise(function(resolve, reject) {
100
- const params = {
101
- Bucket: bucketName
102
- };
103
- s3.headBucket(params, function(err, data) {
104
- if (err) {
105
- reject(new VError(err, 'S3 bucket not accessible'));
106
- } else {
107
- resolve();
108
- }
109
- });
110
- });
111
- }
112
-
113
- /**
114
- * Use couchbackup to create a backup of the specified database to a file path.
115
- *
116
- * @param {any} sourceUrl Database URL
117
- * @param {any} backupTmpFilePath Path to write file
118
- * @returns Promise
119
- */
120
- function createBackupFile(sourceUrl, backupTmpFilePath) {
121
- return new Promise((resolve, reject) => {
122
- couchbackup.backup(
123
- sourceUrl,
124
- fs.createWriteStream(backupTmpFilePath),
125
- (err) => {
126
- if (err) {
127
- return reject(new VError(err, 'CouchBackup process failed'));
128
- }
129
- debug('couchbackup to file done; uploading to S3');
130
- resolve('creating backup file complete');
131
- }
132
- );
133
- });
134
- }
135
-
136
- /**
137
- * Upload a backup file to an S3 bucket.
138
- *
139
- * @param {any} s3 Object store client
140
- * @param {any} backupTmpFilePath Path of backup file to write.
141
- * @param {any} bucket Object store bucket name
142
- * @param {any} key Object store key name
143
- * @returns Promise
144
- */
145
- function uploadNewBackup(s3, backupTmpFilePath, bucket, key) {
146
- return new Promise((resolve, reject) => {
147
- debug(`Uploading from ${backupTmpFilePath} to ${bucket}/${key}`);
148
-
149
- function uploadFromStream(s3, bucket, key) {
150
- const pass = new stream.PassThrough();
151
-
152
- const params = {
153
- Bucket: bucket,
154
- Key: key,
155
- Body: pass
156
- };
157
- s3.upload(params, function(err, data) {
158
- debug('S3 upload done');
159
- if (err) {
160
- debug(err);
161
- reject(new VError(err, 'Upload failed'));
162
- return;
18
+ const assert = require('assert');
19
+ const logfilesummary = require('../includes/logfilesummary.js');
20
+
21
+ describe('#unit Fetching summary from the log file', function() {
22
+ it('should fetch a summary correctly', function() {
23
+ return new Promise((resolve, reject) => {
24
+ logfilesummary('./test/fixtures/test.log', function(err, data) {
25
+ try {
26
+ assert.ok(!err);
27
+ assert.ok(data);
28
+ assert.strictEqual(data.changesComplete, true);
29
+ assert.strictEqual(typeof data.batches, 'object');
30
+ assert.strictEqual(Object.keys(data.batches).length, 2);
31
+ assert.deepStrictEqual(data.batches['1'], true);
32
+ assert.deepStrictEqual(data.batches['4'], true);
33
+ resolve();
34
+ } catch (err) {
35
+ reject(err);
163
36
  }
164
- debug('Upload succeeded');
165
- debug(data);
166
- resolve();
167
- }).httpUploadProgress = (progress) => {
168
- debug(`S3 upload progress: ${progress}`);
169
- };
170
-
171
- return pass;
172
- }
173
-
174
- const inputStream = fs.createReadStream(backupTmpFilePath);
175
- const s3Stream = uploadFromStream(s3, bucket, key);
176
- inputStream.pipe(s3Stream);
37
+ });
38
+ });
177
39
  });
178
- }
179
-
180
- /**
181
- * Remove creds from a URL, e.g., before logging
182
- *
183
- * @param {string} url URL to safen
184
- */
185
- function s(originalUrl) {
186
- const parts = new url.URL(originalUrl);
187
- return url.format(parts, { auth: false });
188
- }
189
-
190
- main();
40
+ });