├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── example.yaml ├── go.mod ├── main.go ├── pkg └── api │ └── api.go └── vendor ├── github.com ├── LINBIT │ └── golinstor │ │ ├── LICENSE │ │ ├── README.md │ │ ├── go.mod │ │ ├── linstor.go │ │ └── linstor_test.go └── satori │ └── go.uuid │ ├── .travis.yml │ ├── LICENSE │ ├── README.md │ ├── codec.go │ ├── codec_test.go │ ├── generator.go │ ├── generator_test.go │ ├── sql.go │ ├── sql_test.go │ ├── uuid.go │ └── uuid_test.go ├── gopkg.in └── check.v1 │ ├── .gitignore │ ├── .travis.yml │ ├── LICENSE │ ├── README.md │ ├── TODO │ ├── benchmark.go │ ├── benchmark_test.go │ ├── bootstrap_test.go │ ├── check.go │ ├── check_test.go │ ├── checkers.go │ ├── checkers_test.go │ ├── export_test.go │ ├── fixture_test.go │ ├── foundation_test.go │ ├── helpers.go │ ├── helpers_test.go │ ├── printer.go │ ├── printer_test.go │ ├── reporter.go │ ├── reporter_test.go │ ├── run.go │ └── run_test.go └── vgo.list /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - tip 4 | before_deploy: "make release" 5 | deploy: 6 | provider: releases 7 | api_key: 8 | secure: OJVFGhHIr9lWnBvN4IOIWk5lxwCj8xMezpgH5NPjKGWPNPdQQM4ONhfEswEnD9gNtyStNh2POOQEbaimpDIPby/dX8DXF6FJ2Isfyu/kabbZAKz8sdoUlSyT/lt+4gx5IBxrWP14yLMPVF+hhvVdXiXKLYnFSKyONy/HK7qvnwhftwbArzQn0yKlPpTysER9T1fqSAK5g1CQ8Yz1FGu678Fu/XsGm6WumD4tP4w/bf10feINJBQiAbCs/9lc9FkTHt/tQzMfy/X5vKPHaX5kF+LI1iYq95I32CSRLyOFwMlV/9cs3Zz62vHbjbDWPobxHhO8HXh3D5vBDYCq7ofkgtWEgDkktsZ9sDGnP2mYbXwbzcRPhR51S1sopWo+ScRYtuNIyftV60ieQQb9JxZx2JuzWTooFJ2VtdmoaNtUTBILt61Y8bs8FYpJI5HI5NhAMX5G3Cu2jP+ExsKmeVQr6uFeDDZXQOrxpVNEfwAqRC5dFTkCl1ASE5eo4QkIbzy9ZB0AGlnAX7EC7fLnN+I4mccsfVOpUY2qTYOPyAovpS8Uanio40tuDSFkifJQEbA2Ev3siI4OWbPAAJlKTpfbpfwBfsSxtF3YmP6DvjRF6XP15q24tt/z8aIg+vWs+NefEJItxiuZ32uiMoAejzGwK+tTStbh8UluRqcyTn9Yxjw= 9 | file: linstor-flexvolume-linux-amd64 10 | skip_cleanup: true 11 | on: 12 | repo: LINBIT/linstor-flexvolume 13 | tags: true 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = `basename $$PWD` 2 | LATESTTAG=$(shell git describe --abbrev=0 --tags | tr -d 'v') 3 | VERSION=`git describe --tags --always --dirty` 4 | OS=linux 5 | ARCH=amd64 6 | 7 | MAGIC_DIR = /usr/libexec/kubernetes/kubelet-plugins/volume/exec/linbit~${PROJECT_NAME} 8 | 9 | GO = go 10 | LDFLAGS = -ldflags "-X main.Version=${VERSION}" 11 | 12 | MKDIR = mkdir 13 | MKDIR_FLAGS = -pv 14 | 15 | CP = cp 16 | CP_FLAGS = -i 17 | 18 | RM = rm 19 | RM_FLAGS = -vf 20 | 21 | all: build 22 | 23 | get: 24 | -go get ./... &> /dev/null 25 | 26 | build: get 27 | $(GO) build $(LDFLAGS) 28 | 29 | release: get 30 | GOOS=$(OS) GOARCH=$(ARCH) $(GO) build $(LDFLAGS) -o $(PROJECT_NAME)-$(OS)-$(ARCH) 31 | 32 | install: 33 | $(MKDIR) $(MKDIR_FLAGS) $(MAGIC_DIR) 34 | $(CP) $(CP_FLAGS) $(PROJECT_NAME) $(MAGIC_DIR) 35 | 36 | clean: 37 | $(RM) $(RM_FLAGS) $(PROJECT_NAME) 38 | 39 | distclean: clean 40 | $(RM) $(RM_FLAGS) $(PROJECT_NAME)-$(OS)-$(ARCH) 41 | 42 | # packaging, you need the packaging branch for these 43 | 44 | # we build binary-only packages and use the static binary in this tarball 45 | linstor-flexvolume-$(LATESTTAG).tar.gz: build 46 | dh_clean || true 47 | tar --transform="s,^,linstor-flexvolume-$(LATESTTAG)/," --owner=0 --group=0 -czf $@ linstor-flexvolume debian linstor-flexvolume.spec 48 | 49 | # consistency with the other linbit projects 50 | debrelease: linstor-flexvolume-$(LATESTTAG).tar.gz 51 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # THIS PROJECT IS DEPRECATED, PLEASE USE OUR [CSI PLUGIN](https://github.com/LINBIT/linstor-csi)














2 | 3 | # Linstor flexvolume plugin for Kubernetes 4 | 5 | ## Building 6 | 7 | Requires Go 1.10 or higher and a configured GOPATH 8 | 9 | `mkdir -p $GOPATH/src/github.com/LINBIT/` 10 | 11 | `cd $GOPATH/src/github.com/LINBIT/` 12 | 13 | `git clone https://github.com/LINBIT/linstor-flexvolume` 14 | 15 | `cd linstor-flexvolume` 16 | 17 | `make` 18 | 19 | This will compile a binary targeting the local machine's architecture and 20 | place it into the root of the project. 21 | 22 | ## Installing 23 | 24 | Place the generated binary named `linstor-flexvolume` under the following path 25 | on the kubelet and kube-controller-manager nodes: 26 | 27 | ```bash 28 | /usr/libexec/kubernetes/kubelet-plugins/volume/exec/linbit~linstor-flexvolume/ 29 | ``` 30 | After installation, restarting kubelet process is required on each node 31 | for Kubernetes versions older than 1.8. 32 | 33 | You must set the `--enable-controller-attach-detach=false` option on all 34 | kubelets. For systemd managed kubelets this can be set in 35 | `/etc/systemd/system/kubelet.service.d/10-kubeadm.conf` 36 | 37 | ## Usage 38 | 39 | This project must be used in conjunction with a working LINSTOR cluster. [LINSTOR's 40 | documentation](https://docs.linbit.com/docs/users-guide-9.0/#p-linstor) is the 41 | foremost guide on setting up and administering LINSTOR. 42 | 43 | Resources must be created before attachment with Linstor or 44 | [linstor-external-provisioner](https://github.com/LINBIT/linstor-external-provisioner) before 45 | they are available for this plugin to use. 46 | 47 | The kube-controller-manager and all kubelets eligible to run containers must be 48 | part of the same Linstor cluster. Volumes will be attached to the kubelet 49 | across the network via the DRBD Transport protocol, so they do not require local 50 | storage. You will need to install the Linstor Client on each kubelet and 51 | unless the Linstor controller is running locally, you'll need to pass in the 52 | `controllers` option in order to communicate with the Linstor controller. 53 | Either via setting in the StorageClass and using the refular PVC notation, or 54 | by using the flexvolume notation> 55 | 56 | Kubelet nodes names must match the output of `uname -n` exactly. If they do not, 57 | this may be overridden via the kubelet `--hostname-override` parameter 58 | 59 | Please note that the Kubernetes PV name and the associated Linstor resource 60 | name **must** match exactly in order for the volume to remain attached to the 61 | kubelet due to https://github.com/kubernetes/kubernetes/issues/44737 62 | 63 | `example.yaml`, located in the root of this project, contains an example 64 | configuration that attaches a resource named `r0` to the container under the path 65 | `/data`. Note that that the PV name is also named `r0`. 66 | -------------------------------------------------------------------------------- /example.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: fedora 5 | namespace: default 6 | spec: 7 | containers: 8 | - name: fedora 9 | image: fedora 10 | command: [/bin/bash] 11 | args: ["-c", "while true; do sleep 10; done"] 12 | volumeMounts: 13 | - name: r0 14 | mountPath: /data 15 | ports: 16 | - containerPort: 80 17 | volumes: 18 | - name: r0 19 | flexVolume: 20 | driver: "linbit/linstor-flexvolume" 21 | fsType: "xfs" 22 | options: 23 | resource: "r0" 24 | controllers: "192.168.100.100:3367" 25 | storagePool: "drbd-pool" 26 | autoPlace: "2" 27 | nodeList: "node-a node-b node-c" 28 | fsOpts: "-b size=1024" 29 | mountOpts: "defaults,sync,noatime" 30 | doNotPlaceWithRegex: ".*" 31 | encryptVolumes: "yes" 32 | disklessStoragePool: "diskless-pool" 33 | 34 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/LINBIT/linstor-flexvolume 2 | 3 | require github.com/LINBIT/golinstor v0.10.1 4 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Linstor Flexvolume plugin for Kubernetes. 3 | * Copyright © 2018 LINBIT USA LLC 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, see . 17 | */ 18 | 19 | package main 20 | 21 | import ( 22 | "fmt" 23 | "log" 24 | "log/syslog" 25 | "os" 26 | "strings" 27 | 28 | "github.com/LINBIT/linstor-flexvolume/pkg/api" 29 | ) 30 | 31 | // Version is set via ldflags configued in the Makefile. 32 | var Version string 33 | 34 | func main() { 35 | 36 | apiCall := os.Args[1] 37 | 38 | // Print version and exit. 39 | if apiCall == "--version" { 40 | fmt.Println(Version) 41 | os.Exit(0) 42 | } 43 | 44 | sysLog, err := syslog.New(syslog.LOG_INFO, "Linstor FlexVolume") 45 | if err != nil { 46 | log.Fatal(err) 47 | } 48 | log.SetOutput(sysLog) 49 | 50 | log.Printf("called with %s: %s", apiCall, strings.Join(os.Args[2:], ", ")) 51 | 52 | api := api.FlexVolumeApi{} 53 | 54 | out, ret := api.Call(os.Args[1:]) 55 | 56 | log.Printf("responded to %s: %s", os.Args[1], out) 57 | 58 | fmt.Print(out) 59 | os.Exit(ret) 60 | } 61 | -------------------------------------------------------------------------------- /pkg/api/api.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Linstor Flexvolume plugin for Kubernetes. 3 | * Copyright © 2018 LINBIT USA LLC 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, see . 17 | */ 18 | 19 | package api 20 | 21 | import ( 22 | "encoding/json" 23 | "fmt" 24 | "io" 25 | "log" 26 | "log/syslog" 27 | "os" 28 | "strconv" 29 | 30 | linstor "github.com/LINBIT/golinstor" 31 | ) 32 | 33 | // API status codes, used as exit codes in main. 34 | const ( 35 | EXITSUCCESS int = iota 36 | EXITDRBDFAILURE 37 | EXITBADAPICALL 38 | ) 39 | 40 | type flexAPIErr struct { 41 | message string 42 | } 43 | 44 | func (e flexAPIErr) Error() string { 45 | return fmt.Sprintf("Linstor Flexvoume API: %s", e.message) 46 | } 47 | 48 | type response struct { 49 | Status string `json:"status"` 50 | Message string `json:"message"` 51 | } 52 | 53 | type attachResponse struct { 54 | response 55 | Device string `json:"device"` 56 | } 57 | 58 | type isAttachedResponse struct { 59 | response 60 | Attached bool `json:"attached"` 61 | } 62 | 63 | type getVolNameResponse struct { 64 | response 65 | VolumeName string `json:"volumeName"` 66 | } 67 | 68 | type options struct { 69 | // K8s volume options. 70 | FsType string `json:"kubernetes.io/fsType"` 71 | Readwrite string `json:"kubernetes.io/readwrite"` 72 | PVCResource string `json:"kubernetes.io/pvOrVolumeName"` 73 | 74 | // Homegrown volume options. 75 | Resource string `json:"resource"` 76 | BlockSize string `json:"blockSize"` 77 | Force string `json:"force"` 78 | XFSDiscardBlocks string `json:"xfsDiscardBlocks"` 79 | XFSDataSU string `json:"xfsDataSu"` 80 | XFSDataSW string `json:"xfsDataSw"` 81 | XFSLogDev string `json:"xfsLogDev"` 82 | DisklessStoragePool string `json:"disklessStoragePool"` 83 | MountOpts string `json:"mountOpts"` 84 | FSOpts string `json:"fsOpts"` 85 | 86 | // Parsed option ready to pass to linstor.FSUtil 87 | xfsDataSW int 88 | blockSize int64 89 | force bool 90 | xfsdiscardblocks bool 91 | } 92 | 93 | func (o *options) getResource() string { 94 | if o.Resource != "" { 95 | return o.Resource 96 | } 97 | return o.PVCResource 98 | } 99 | 100 | func parseOptions(s string) (options, error) { 101 | opts := options{} 102 | err := json.Unmarshal([]byte(s), &opts) 103 | if err != nil { 104 | return opts, flexAPIErr{fmt.Sprintf("couldn't parse options from %s", s)} 105 | } 106 | 107 | // BlockSizes of zero are ignored by FSUtil 108 | if opts.BlockSize == "" { 109 | opts.BlockSize = "0" 110 | } 111 | opts.blockSize, err = strconv.ParseInt(opts.BlockSize, 10, 32) 112 | if err != nil { 113 | return opts, err 114 | } 115 | 116 | if opts.XFSDataSW == "" { 117 | opts.XFSDataSW = "0" 118 | } 119 | xfsdatasw, err := strconv.ParseInt(opts.XFSDataSW, 10, 32) 120 | if err != nil { 121 | return opts, err 122 | } 123 | opts.xfsDataSW = int(xfsdatasw) 124 | 125 | if opts.Force == "" { 126 | opts.Force = "false" 127 | } 128 | opts.force, err = strconv.ParseBool(opts.Force) 129 | if err != nil { 130 | return opts, err 131 | } 132 | 133 | if opts.XFSDiscardBlocks == "" { 134 | opts.XFSDiscardBlocks = "false" 135 | } 136 | opts.xfsdiscardblocks, err = strconv.ParseBool(opts.XFSDiscardBlocks) 137 | if err != nil { 138 | return opts, err 139 | } 140 | 141 | return opts, nil 142 | } 143 | 144 | var logOutput io.Writer 145 | 146 | func init() { 147 | out, err := syslog.New(syslog.LOG_INFO, "Linstor FlexVolume") 148 | if err != nil { 149 | log.Fatal(err) 150 | } 151 | 152 | logOutput = out 153 | } 154 | 155 | type FlexVolumeApi struct { 156 | action string 157 | } 158 | 159 | func (api FlexVolumeApi) fmtAPIError(err error) (string, int) { 160 | res, _ := json.Marshal(response{ 161 | Status: "Failure", 162 | Message: flexAPIErr{fmt.Sprintf("%s: %v", api.action, err)}.Error(), 163 | }) 164 | return string(res), EXITBADAPICALL 165 | } 166 | 167 | func (api *FlexVolumeApi) Call(args []string) (string, int) { 168 | if len(args) < 1 { 169 | res, _ := json.Marshal(response{ 170 | Status: "Failure", 171 | Message: flexAPIErr{"No driver action! Valid actions are: init, attach, detach, mountdevice, unmountdevice, isattached"}.Error(), 172 | }) 173 | return string(res), EXITBADAPICALL 174 | } 175 | api.action = args[0] 176 | switch api.action { 177 | case "init": 178 | return api.init() 179 | case "attach": 180 | if len(args) < 3 { 181 | return tooFewArgsResponse(args) 182 | } 183 | return api.attach(args[1], args[2]) 184 | case "waitforattach": 185 | return api.waitForAttach() 186 | case "detach": 187 | if len(args) < 3 { 188 | return tooFewArgsResponse(args) 189 | } 190 | return api.detach(args[1], args[2]) 191 | case "mountdevice": 192 | if len(args) < 4 { 193 | return tooFewArgsResponse(args) 194 | } 195 | return api.mountDevice(args[1], args[3]) 196 | case "unmountdevice": 197 | if len(args) < 2 { 198 | return tooFewArgsResponse(args) 199 | } 200 | return api.unmountDevice(args[1]) 201 | case "unmount": 202 | if len(args) < 2 { 203 | return tooFewArgsResponse(args) 204 | } 205 | return api.unmount(args[1]) 206 | case "isattached": 207 | if len(args) < 3 { 208 | return tooFewArgsResponse(args) 209 | } 210 | return api.isAttached(args[1], args[2]) 211 | default: 212 | res, _ := json.Marshal(response{ 213 | Status: "Not supported", 214 | Message: flexAPIErr{fmt.Sprintf("Unsupported driver action: %s", api.action)}.Error(), 215 | }) 216 | return string(res), EXITBADAPICALL 217 | } 218 | } 219 | 220 | func (api FlexVolumeApi) init() (string, int) { 221 | res, _ := json.Marshal(response{Status: "Success"}) 222 | return string(res), EXITSUCCESS 223 | } 224 | 225 | func (api FlexVolumeApi) attach(rawOpts, node string) (string, int) { 226 | opts, err := parseOptions(rawOpts) 227 | if err != nil { 228 | return api.fmtAPIError(err) 229 | } 230 | 231 | resource := linstor.NewResourceDeployment(linstor.ResourceDeploymentConfig{ 232 | Name: opts.getResource(), 233 | ClientList: []string{node}, 234 | DisklessStoragePool: opts.DisklessStoragePool, 235 | LogOut: logOutput, 236 | }) 237 | 238 | err = resource.Assign() 239 | if err != nil { 240 | res, _ := json.Marshal(response{ 241 | Status: "Failure", 242 | Message: flexAPIErr{fmt.Sprintf( 243 | "%s: failed to assign resource %s: %v", api.action, resource.Name, err)}.Error(), 244 | }) 245 | return string(res), EXITDRBDFAILURE 246 | } 247 | 248 | path, err := resource.GetDevPath(node, false) 249 | if err != nil { 250 | res, _ := json.Marshal(response{ 251 | Status: "Failure", 252 | Message: flexAPIErr{fmt.Sprintf("%s: unable to find device path for resource %s: %v", api.action, resource.Name, err)}.Error(), 253 | }) 254 | return string(res), EXITDRBDFAILURE 255 | } 256 | 257 | res, _ := json.Marshal(attachResponse{ 258 | Device: path, 259 | response: response{ 260 | Status: "Success", 261 | }, 262 | }) 263 | return string(res), EXITSUCCESS 264 | } 265 | 266 | func (api FlexVolumeApi) waitForAttach() (string, int) { 267 | res, _ := json.Marshal(response{Status: "Success"}) 268 | return string(res), EXITSUCCESS 269 | } 270 | 271 | func (api FlexVolumeApi) detach(name, node string) (string, int) { 272 | 273 | resource := linstor.NewResourceDeployment( 274 | linstor.ResourceDeploymentConfig{ 275 | Name: name, 276 | LogOut: logOutput, 277 | }) 278 | 279 | // Do not unassign resources that have local storage. 280 | if !resource.IsClient(node) { 281 | res, _ := json.Marshal(response{Status: "Success"}) 282 | return string(res), EXITSUCCESS 283 | } 284 | 285 | err := resource.Unassign(node) 286 | if err != nil { 287 | api.fmtAPIError(err) 288 | } 289 | 290 | res, _ := json.Marshal(response{Status: "Success"}) 291 | return string(res), EXITSUCCESS 292 | } 293 | 294 | func (api FlexVolumeApi) mountDevice(path, rawOpts string) (string, int) { 295 | opts, err := parseOptions(rawOpts) 296 | if err != nil { 297 | return api.fmtAPIError(err) 298 | } 299 | r := linstor.NewResourceDeployment( 300 | linstor.ResourceDeploymentConfig{Name: opts.getResource(), 301 | LogOut: logOutput, 302 | }) 303 | 304 | mounter := linstor.FSUtil{ 305 | ResourceDeployment: &r, 306 | FSType: opts.FsType, 307 | BlockSize: opts.blockSize, 308 | Force: opts.force, 309 | XFSDiscardBlocks: opts.xfsdiscardblocks, 310 | XFSDataSU: opts.XFSDataSU, 311 | XFSDataSW: opts.xfsDataSW, 312 | XFSLogDev: opts.XFSLogDev, 313 | MountOpts: opts.MountOpts, 314 | FSOpts: opts.FSOpts, 315 | } 316 | 317 | localNode, err := os.Hostname() 318 | if err != nil { 319 | return api.fmtAPIError(err) 320 | } 321 | 322 | err = mounter.Mount(path, localNode) 323 | if err != nil { 324 | return api.fmtAPIError(err) 325 | } 326 | 327 | res, _ := json.Marshal(response{Status: "Success"}) 328 | return string(res), EXITSUCCESS 329 | } 330 | 331 | func (api FlexVolumeApi) unmountDevice(path string) (string, int) { 332 | return api.unmount(path) 333 | } 334 | 335 | func (api FlexVolumeApi) unmount(path string) (string, int) { 336 | umounter := linstor.FSUtil{} 337 | 338 | err := umounter.UnMount(path) 339 | if err != nil { 340 | return api.fmtAPIError(err) 341 | } 342 | res, _ := json.Marshal(response{Status: "Success"}) 343 | return string(res), EXITSUCCESS 344 | } 345 | 346 | func (api FlexVolumeApi) getVolumeName(s []string) (string, int) { 347 | opts, err := parseOptions(s[1]) 348 | if err != nil { 349 | res, _ := json.Marshal(response{ 350 | Status: "Failure", 351 | Message: flexAPIErr{fmt.Sprintf("%s: %v", api.action, err)}.Error(), 352 | }) 353 | return string(res), EXITBADAPICALL 354 | } 355 | 356 | res, _ := json.Marshal(getVolNameResponse{ 357 | VolumeName: opts.getResource(), 358 | response: response{ 359 | Status: "Success", 360 | }, 361 | }) 362 | return string(res), EXITSUCCESS 363 | } 364 | 365 | func (api FlexVolumeApi) isAttached(rawOpts, node string) (string, int) { 366 | opts, err := parseOptions(rawOpts) 367 | if err != nil { 368 | return api.fmtAPIError(err) 369 | } 370 | 371 | resource := linstor.NewResourceDeployment( 372 | linstor.ResourceDeploymentConfig{Name: opts.getResource(), 373 | LogOut: logOutput, 374 | }) 375 | 376 | ok, err := resource.OnNode(node) 377 | if err != nil { 378 | return api.fmtAPIError(err) 379 | } 380 | 381 | if !ok { 382 | res, _ := json.Marshal(isAttachedResponse{ 383 | Attached: ok, 384 | response: response{Status: "Failure"}, 385 | }) 386 | return string(res), EXITSUCCESS 387 | } 388 | 389 | res, _ := json.Marshal(isAttachedResponse{ 390 | Attached: ok, 391 | response: response{Status: "Success"}, 392 | }) 393 | 394 | return string(res), EXITSUCCESS 395 | } 396 | 397 | func tooFewArgsResponse(s []string) (string, int) { 398 | res, _ := json.Marshal(response{ 399 | Status: "Failure", 400 | Message: flexAPIErr{fmt.Sprintf("%s: too few arguments passed: %s", s[0], s)}.Error(), 401 | }) 402 | return string(res), EXITBADAPICALL 403 | } 404 | -------------------------------------------------------------------------------- /vendor/github.com/LINBIT/golinstor/README.md: -------------------------------------------------------------------------------- 1 | # golinstor 2 | 3 | This library aims to be a simple go interface for 4 | [Linstor](https://github.com/LINBIT/linstor-server) 5 | 6 | This library is in an early stage and does not yet have a stable API: vendor 7 | this package, should you use it. 8 | 9 | # Documentation 10 | 11 | [godocs](https://godoc.org/github.com/LINBIT/golinstor) 12 | 13 | # License 14 | GPL2 15 | -------------------------------------------------------------------------------- /vendor/github.com/LINBIT/golinstor/go.mod: -------------------------------------------------------------------------------- 1 | module github.com/LINBIT/golinstor 2 | 3 | require ( 4 | github.com/satori/go.uuid v1.2.0 5 | gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405 6 | ) 7 | -------------------------------------------------------------------------------- /vendor/github.com/LINBIT/golinstor/linstor_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * A helpful library to interact with Linstor 3 | * Copyright © 2018 LINBIT USA LCC 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, see . 17 | */ 18 | 19 | package linstor 20 | 21 | import ( 22 | "encoding/json" 23 | "io/ioutil" 24 | "reflect" 25 | "testing" 26 | 27 | "github.com/satori/go.uuid" 28 | ) 29 | 30 | func TestNewResourceDeployment(t *testing.T) { 31 | // Test totally unconfigured deployment. 32 | res := NewResourceDeployment(ResourceDeploymentConfig{}) 33 | if _, err := uuid.FromString(res.Name); err != nil { 34 | t.Errorf("Expected a UUID got %s", res.Name) 35 | } 36 | if res.AutoPlace != 1 { 37 | t.Errorf("Expected autoplace to be %d, got %d", 1, res.AutoPlace) 38 | } 39 | if res.SizeKiB != 4096 { 40 | t.Errorf("Expected SizeKiB to be %d, got %d", 4096, res.SizeKiB) 41 | } 42 | if res.StoragePool != "DfltStorPool" { 43 | t.Errorf("Expected StoragePool to be %s, got %s", "DfltStorPool", res.StoragePool) 44 | } 45 | if res.DisklessStoragePool != "DfltDisklessStorPool" { 46 | t.Errorf("Expected DisklessStoragePool to be %s, got %s", "DfltDisklessStorPool", res.DisklessStoragePool) 47 | } 48 | if res.Controllers != "" { 49 | t.Errorf("Expected Controllers to be %s, got %s", "", res.Controllers) 50 | } 51 | 52 | // Test regularly configured deployment autoplace. 53 | name := "Agamemnon" 54 | res = NewResourceDeployment( 55 | ResourceDeploymentConfig{ 56 | Name: name, 57 | AutoPlace: 5, 58 | SizeKiB: 10000, 59 | Controllers: "192.168.100.100:9001,172.5.1.30:5605,192.168.5.1:8080", 60 | }, 61 | ) 62 | if res.Name != name { 63 | t.Errorf("Expected %s to equal %s", res.Name, name) 64 | } 65 | if res.AutoPlace != 5 { 66 | t.Errorf("Expected autoplace to be %d, got %d", 5, res.AutoPlace) 67 | } 68 | if res.SizeKiB != 10000 { 69 | t.Errorf("Expected SizeKiB to be %d, got %d", 10000, res.SizeKiB) 70 | } 71 | if res.Controllers != "192.168.100.100:9001,172.5.1.30:5605,192.168.5.1:8080" { 72 | t.Errorf("Expected Controllers to be %s, got %s", "192.168.100.100:9001,172.5.1.30:5605,192.168.5.1:8080", res.Controllers) 73 | } 74 | 75 | // Test regularly configured deployment autoplace. 76 | name = "Agamemnon" 77 | res = NewResourceDeployment( 78 | ResourceDeploymentConfig{ 79 | Name: name, 80 | AutoPlace: 5, 81 | SizeKiB: 10000, 82 | Controllers: "192.168.100.100:9001,172.5.1.30:5605,192.168.5.1:8080", 83 | ReplicasOnSame: []string{"foo", "bar", "baz"}, 84 | ReplicasOnDifferent: []string{"fee", "fie", "foe"}, 85 | }, 86 | ) 87 | 88 | expected := []string{"--replicas-on-same", "foo bar baz", "--replicas-on-different", "fee fie foe"} 89 | if reflect.DeepEqual(res.autoPlaceArgs, expected) { 90 | t.Errorf("Expected autoPlaceArgs to be %s, got %s", expected, res.autoPlaceArgs) 91 | 92 | } 93 | 94 | // Test regularly configured deployment manual. 95 | nodes := []string{"host1", "host2"} 96 | res = NewResourceDeployment( 97 | ResourceDeploymentConfig{ 98 | NodeList: nodes, 99 | SizeKiB: 10000, 100 | }) 101 | if res.AutoPlace != 0 { 102 | t.Errorf("Expected autoplace to be %d, got %d", 0, res.AutoPlace) 103 | } 104 | if !reflect.DeepEqual(res.NodeList, nodes) { 105 | t.Errorf("Expected: %v, Got: %v", nodes, res.NodeList) 106 | } 107 | } 108 | 109 | func TestPrependOpts(t *testing.T) { 110 | var optsTests = []struct { 111 | in []string 112 | out []string 113 | }{ 114 | {[]string{"resource", "list"}, 115 | []string{"-m", "resource", "list"}}, 116 | {[]string{"fee", "fie", "fo", "fum"}, 117 | []string{"-m", "fee", "fie", "fo", "fum"}}, 118 | } 119 | 120 | r1 := NewResourceDeployment(ResourceDeploymentConfig{}) 121 | 122 | for _, tt := range optsTests { 123 | result := r1.prependOpts(tt.in...) 124 | if !reflect.DeepEqual(result, tt.out) { 125 | t.Errorf("Called: prependOpts(%v), Expected: %v, Got: %v. %+v", tt.in, tt.out, result, r1) 126 | } 127 | } 128 | 129 | r2 := NewResourceDeployment( 130 | ResourceDeploymentConfig{ 131 | Controllers: "192.168.100.100:9001,172.5.1.30:5605", 132 | }, 133 | ) 134 | 135 | var optsTestsControllers = []struct { 136 | in []string 137 | out []string 138 | }{ 139 | {[]string{"resource", "list"}, 140 | []string{"-m", "--controllers", r2.Controllers, "resource", "list"}}, 141 | {[]string{"fee", "fie", "fo", "fum"}, 142 | []string{"-m", "--controllers", r2.Controllers, "fee", "fie", "fo", "fum"}}, 143 | } 144 | 145 | for _, tt := range optsTestsControllers { 146 | result := r2.prependOpts(tt.in...) 147 | if !reflect.DeepEqual(result, tt.out) { 148 | t.Errorf("Called: prependOpts(%v), Expected: %v, Got: %v. %+v", tt.in, tt.out, result, r2) 149 | } 150 | } 151 | } 152 | 153 | func TestUniq(t *testing.T) { 154 | 155 | var uniqTests = []struct { 156 | in []string 157 | out []string 158 | }{ 159 | {[]string{"foo", "bar", "foo", "baz", "baz"}, 160 | []string{"foo", "bar", "baz"}}, 161 | {[]string{"fee", "fie", "fo", "fum"}, 162 | []string{"fee", "fie", "fo", "fum"}}, 163 | } 164 | 165 | for _, tt := range uniqTests { 166 | result := uniq(tt.in) 167 | if !reflect.DeepEqual(result, tt.out) { 168 | t.Errorf("Called: uniq(%v), Expected: %v, Got: %v", tt.in, tt.out, result) 169 | } 170 | } 171 | } 172 | 173 | func TestSubtract(t *testing.T) { 174 | 175 | var subTests = []struct { 176 | s1 []string 177 | s2 []string 178 | out []string 179 | }{ 180 | {[]string{"foo", "bar", "foo", "baz", "baz"}, 181 | []string{"foo", "bar", "baz"}, 182 | []string{}}, 183 | {[]string{"foo", "bar", "foo", "baz", "baz"}, 184 | []string{"fee", "fie", "fo", "fum"}, 185 | []string{"fee", "fie", "fo", "fum"}}, 186 | {[]string{"cat", "dog", "monkey"}, 187 | []string{"pineapple", "peach", "dog", "mango"}, 188 | []string{"pineapple", "peach", "mango"}}, 189 | } 190 | 191 | for _, tt := range subTests { 192 | result := subtract(tt.s1, tt.s2) 193 | if !reflect.DeepEqual(result, tt.out) { 194 | t.Errorf("Called: uniq(%v, %v), Expected: %v, Got: %v", tt.s1, tt.s2, tt.out, result) 195 | } 196 | } 197 | } 198 | 199 | func TestDoResExists(t *testing.T) { 200 | 201 | testOut := []byte("[\n {\n \"resources\": [\n {\n \"vlms\": [\n {\n \"vlm_dfn_uuid\": \"8000558f-9061-4256-b0fe-ec8d3b7fc051\", \n \"stor_pool_uuid\": \"2d840084-f071-4173-a509-9a56d695a606\", \n \"vlm_uuid\": \"ff382153-d47c-4a9f-a466-4ef4b3268656\", \n \"vlm_nr\": 0, \n \"stor_pool_name\": \"drbdpool\"\n }, \n {\n \"vlm_dfn_uuid\": \"f763311c-3eb2-4f0e-ad55-361d4d026346\", \n \"stor_pool_uuid\": \"2d840084-f071-4173-a509-9a56d695a606\", \n \"vlm_uuid\": \"02a24f94-03a8-4918-8173-506b4cca369c\", \n \"vlm_nr\": 1, \n \"stor_pool_name\": \"drbdpool\"\n }\n ], \n \"node_uuid\": \"1efa3fdf-129a-4018-a3f2-3d0f46571c5b\", \n \"uuid\": \"d34e324a-54d8-4c79-adf5-3da33eca3371\", \n \"node_name\": \"kubelet-a\", \n \"props\": [\n {\n \"value\": \"drbdpool\", \n \"key\": \"StorPoolName\"\n }\n ], \n \"rsc_dfn_uuid\": \"83c4ce34-1bb5-48a7-a153-457f056223e1\", \n \"name\": \"r00\"\n }, \n {\n \"rsc_flags\": [\n \"DELETE\"\n ], \n \"vlms\": [\n {\n \"vlm_nr\": 0, \n \"stor_pool_name\": \"drbdpool\", \n \"stor_pool_uuid\": \"ea3ddc0b-bc4f-4860-ae38-744c65cb3d18\", \n \"vlm_uuid\": \"aebe934e-cda3-4b67-8d08-48c9444d12eb\", \n \"vlm_dfn_uuid\": \"8000558f-9061-4256-b0fe-ec8d3b7fc051\", \n \"vlm_flags\": [\n \"DELETE\"\n ]\n }, \n {\n \"vlm_nr\": 1, \n \"stor_pool_name\": \"drbdpool\", \n \"stor_pool_uuid\": \"ea3ddc0b-bc4f-4860-ae38-744c65cb3d18\", \n \"vlm_uuid\": \"36e679a3-d59a-4147-8f1e-299ae689c1d1\", \n \"vlm_dfn_uuid\": \"f763311c-3eb2-4f0e-ad55-361d4d026346\", \n \"vlm_flags\": [\n \"DELETE\"\n ]\n }\n ], \n \"node_uuid\": \"c361253c-4e75-48d5-b00a-8a3df5eb3a69\", \n \"uuid\": \"12a54b0c-5d76-4766-b973-26cfb1beaae4\", \n \"node_name\": \"kubelet-b\", \n \"props\": [\n {\n \"value\": \"drbdpool\", \n \"key\": \"StorPoolName\"\n }\n ], \n \"rsc_dfn_uuid\": \"83c4ce34-1bb5-48a7-a153-457f056223e1\", \n \"name\": \"r00\"\n }\n ]\n }\n]") 202 | list := resList{} 203 | if !json.Valid(testOut) { 204 | t.Errorf("invalid json") 205 | } 206 | if err := json.Unmarshal(testOut, &list); err != nil { 207 | t.Errorf("couldn't Unmarshal '%s' :%v", testOut, err) 208 | } 209 | 210 | var resInfoTests = []struct { 211 | resource string 212 | resInfo resList 213 | out bool 214 | }{ 215 | {"r00", list, true}, 216 | {"wrong-o", list, false}, 217 | } 218 | 219 | for _, tt := range resInfoTests { 220 | ok, _ := doResExists(tt.resource, tt.resInfo) 221 | if ok != tt.out { 222 | t.Errorf("Called: doResExists(%q, %v), Expected: %v, Got: %v", tt.resource, tt.resInfo, tt.out, ok) 223 | } 224 | } 225 | } 226 | 227 | func TestDoCheckFSType(t *testing.T) { 228 | var blkidOutputStringTests = []struct { 229 | in string 230 | out string 231 | }{ 232 | {"ID_FS_UUID=15336bdb-4584-4c30-9719-754f5c4744e1\nID_FS_UUID_ENC=15336bdb-4584-4c30-9719-754f5c4744e1\nID_FS_TYPE=ext4\n", "ext4"}, 233 | {"ID_FS_UUID=15336bdb-4584-4c30-9719-754f5c4744e1\nID_FS_UUID_ENC=15336bdb-4584-4c30-9719-754f5c4744e1\nID_FS_TYPE=xfs\n", "xfs"}, 234 | {"\n", ""}, 235 | } 236 | 237 | for _, tt := range blkidOutputStringTests { 238 | FSType, _ := doCheckFSType(tt.in) 239 | if FSType != tt.out { 240 | t.Errorf("Called: doCheckFSType(%q), Expected: %q, Got: %q", tt.in, tt.out, FSType) 241 | } 242 | } 243 | } 244 | 245 | func TestPopulateArgs(t *testing.T) { 246 | var populateArgsTests = []struct { 247 | in FSUtil 248 | out []string 249 | }{ 250 | {FSUtil{ 251 | FSType: "xfs", 252 | BlockSize: 4096, 253 | XFSDiscardBlocks: true, 254 | }, []string{"-b", "size=4096"}}, 255 | {FSUtil{ 256 | FSType: "xfs", 257 | BlockSize: 2048, 258 | }, []string{"-b", "size=2048", "-K"}}, 259 | {FSUtil{ 260 | FSType: "ext4", 261 | BlockSize: 2048, 262 | }, []string{"-b", "2048"}}, 263 | {FSUtil{ 264 | FSType: "xfs", 265 | Force: true, 266 | XFSDiscardBlocks: true, 267 | }, []string{"-f"}}, 268 | {FSUtil{ 269 | FSType: "ext4", 270 | Force: true, 271 | XFSDiscardBlocks: true, 272 | }, []string{"-F"}}, 273 | {FSUtil{ 274 | FSType: "xfs", 275 | XFSDataSU: "128k", 276 | XFSDiscardBlocks: true, 277 | }, []string{"-d", "su=128k"}}, 278 | {FSUtil{ 279 | FSType: "xfs", 280 | XFSDataSW: 1, 281 | XFSDiscardBlocks: true, 282 | }, []string{"-d", "sw=1"}}, 283 | {FSUtil{ 284 | FSType: "xfs", 285 | XFSDataSU: "128k", 286 | XFSDataSW: 1, 287 | XFSDiscardBlocks: true, 288 | Force: true, 289 | // Sadly, the order here matters based on how this []string is built in 290 | // function. It's a little bit fragile, but probably not worth messing 291 | // with right now. 292 | }, []string{"-f", "-d", "su=128k", "-d", "sw=1"}}, 293 | {FSUtil{ 294 | FSType: "xfs", 295 | XFSLogDev: "/dev/example", 296 | XFSDiscardBlocks: true, 297 | }, []string{"-l", "logdev=/dev/example"}}, 298 | {FSUtil{ 299 | FSType: "xfs", 300 | XFSDataSU: "128k", 301 | XFSDataSW: 1, 302 | XFSDiscardBlocks: true, 303 | Force: true, 304 | // Ignore all other options is FSOpts is present. 305 | FSOpts: "-d su=128k size=4000 noalign -i sparse=0", 306 | }, []string{"-d", "su=128k", "size=4000", "noalign", "-i", "sparse=0"}}, 307 | } 308 | 309 | for _, tt := range populateArgsTests { 310 | 311 | tt.in.populateArgs() 312 | 313 | if !reflect.DeepEqual(tt.in.args, tt.out) { 314 | t.Errorf("Expected: %v Got: %v", tt.out, tt.in.args) 315 | } 316 | 317 | } 318 | 319 | } 320 | 321 | func TestDoIsClient(t *testing.T) { 322 | 323 | out, err := ioutil.ReadFile("test_json/heterogeneous_device_paths.json") 324 | if err != nil { 325 | t.Error(err) 326 | } 327 | 328 | list := resList{} 329 | if err := json.Unmarshal(out, &list); err != nil { 330 | } 331 | 332 | var isClientTests = []struct { 333 | resource string 334 | node string 335 | l resList 336 | out bool 337 | }{ 338 | {"swan", "node-1", list, false}, 339 | {"goose", "node-2", list, false}, 340 | {"duck", "node-0", list, true}, 341 | {"duck", "node-1", list, false}, 342 | } 343 | 344 | for _, tt := range isClientTests { 345 | r := NewResourceDeployment(ResourceDeploymentConfig{Name: tt.resource}) 346 | 347 | ok := r.doIsClient(tt.l, tt.node) 348 | 349 | if tt.out != ok { 350 | t.Errorf("Expected: %v on %s Got: %v", tt.out, tt.node, ok) 351 | } 352 | } 353 | } 354 | 355 | func TestDoResOnNode(t *testing.T) { 356 | 357 | out, err := ioutil.ReadFile("./test_json/mixed_diskless.json") 358 | if err != nil { 359 | t.Error(err) 360 | } 361 | 362 | list := resList{} 363 | if err := json.Unmarshal(out, &list); err != nil { 364 | t.Error(err) 365 | } 366 | 367 | var isClientTests = []struct { 368 | resource string 369 | node string 370 | l resList 371 | out bool 372 | }{ 373 | {"default-william", "kubelet-a", list, true}, 374 | {"default-william", "kubelet-x", list, false}, 375 | {"default-william", "kubelet-c", list, true}, 376 | } 377 | 378 | for _, tt := range isClientTests { 379 | 380 | ok := doResOnNode(tt.l, tt.resource, tt.node) 381 | if tt.out != ok { 382 | t.Errorf("Expected: %v on %s Got: %v", tt.out, tt.node, ok) 383 | } 384 | } 385 | 386 | } 387 | 388 | func TestGetDevPath(t *testing.T) { 389 | out, err := ioutil.ReadFile("./test_json/heterogeneous_device_paths.json") 390 | if err != nil { 391 | t.Error(err) 392 | } 393 | 394 | list := resList{} 395 | if err := json.Unmarshal(out, &list); err != nil { 396 | t.Error(err) 397 | } 398 | 399 | var devPathTests = []struct { 400 | resource string 401 | node string 402 | l resList 403 | expected string 404 | }{ 405 | {"duck", "node-0", list, "/dev/nvme2n1"}, 406 | {"duck", "node-1", list, "/dev/null"}, 407 | } 408 | 409 | for _, tt := range devPathTests { 410 | 411 | path, _ := getDevPath(tt.l, tt.resource, tt.node) 412 | if path != tt.expected { 413 | t.Errorf("Expected: %s on %s Got: %v", tt.expected, tt.node, path) 414 | } 415 | } 416 | } 417 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | sudo: false 3 | go: 4 | - 1.2 5 | - 1.3 6 | - 1.4 7 | - 1.5 8 | - 1.6 9 | - 1.7 10 | - 1.8 11 | - 1.9 12 | - tip 13 | matrix: 14 | allow_failures: 15 | - go: tip 16 | fast_finish: true 17 | before_install: 18 | - go get github.com/mattn/goveralls 19 | - go get golang.org/x/tools/cmd/cover 20 | script: 21 | - $HOME/gopath/bin/goveralls -service=travis-ci 22 | notifications: 23 | email: false 24 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013-2018 by Maxim Bublis 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/README.md: -------------------------------------------------------------------------------- 1 | # UUID package for Go language 2 | 3 | [![Build Status](https://travis-ci.org/satori/go.uuid.png?branch=master)](https://travis-ci.org/satori/go.uuid) 4 | [![Coverage Status](https://coveralls.io/repos/github/satori/go.uuid/badge.svg?branch=master)](https://coveralls.io/github/satori/go.uuid) 5 | [![GoDoc](http://godoc.org/github.com/satori/go.uuid?status.png)](http://godoc.org/github.com/satori/go.uuid) 6 | 7 | This package provides pure Go implementation of Universally Unique Identifier (UUID). Supported both creation and parsing of UUIDs. 8 | 9 | With 100% test coverage and benchmarks out of box. 10 | 11 | Supported versions: 12 | * Version 1, based on timestamp and MAC address (RFC 4122) 13 | * Version 2, based on timestamp, MAC address and POSIX UID/GID (DCE 1.1) 14 | * Version 3, based on MD5 hashing (RFC 4122) 15 | * Version 4, based on random numbers (RFC 4122) 16 | * Version 5, based on SHA-1 hashing (RFC 4122) 17 | 18 | ## Installation 19 | 20 | Use the `go` command: 21 | 22 | $ go get github.com/satori/go.uuid 23 | 24 | ## Requirements 25 | 26 | UUID package requires Go >= 1.2. 27 | 28 | ## Example 29 | 30 | ```go 31 | package main 32 | 33 | import ( 34 | "fmt" 35 | "github.com/satori/go.uuid" 36 | ) 37 | 38 | func main() { 39 | // Creating UUID Version 4 40 | u1 := uuid.NewV4() 41 | fmt.Printf("UUIDv4: %s\n", u1) 42 | 43 | // Parsing UUID from string input 44 | u2, err := uuid.FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 45 | if err != nil { 46 | fmt.Printf("Something gone wrong: %s", err) 47 | } 48 | fmt.Printf("Successfully parsed: %s", u2) 49 | } 50 | ``` 51 | 52 | ## Documentation 53 | 54 | [Documentation](http://godoc.org/github.com/satori/go.uuid) is hosted at GoDoc project. 55 | 56 | ## Links 57 | * [RFC 4122](http://tools.ietf.org/html/rfc4122) 58 | * [DCE 1.1: Authentication and Security Services](http://pubs.opengroup.org/onlinepubs/9696989899/chap5.htm#tagcjh_08_02_01_01) 59 | 60 | ## Copyright 61 | 62 | Copyright (C) 2013-2018 by Maxim Bublis . 63 | 64 | UUID package released under MIT License. 65 | See [LICENSE](https://github.com/satori/go.uuid/blob/master/LICENSE) for details. 66 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/codec.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | package uuid 23 | 24 | import ( 25 | "bytes" 26 | "encoding/hex" 27 | "fmt" 28 | ) 29 | 30 | // FromBytes returns UUID converted from raw byte slice input. 31 | // It will return error if the slice isn't 16 bytes long. 32 | func FromBytes(input []byte) (u UUID, err error) { 33 | err = u.UnmarshalBinary(input) 34 | return 35 | } 36 | 37 | // FromBytesOrNil returns UUID converted from raw byte slice input. 38 | // Same behavior as FromBytes, but returns a Nil UUID on error. 39 | func FromBytesOrNil(input []byte) UUID { 40 | uuid, err := FromBytes(input) 41 | if err != nil { 42 | return Nil 43 | } 44 | return uuid 45 | } 46 | 47 | // FromString returns UUID parsed from string input. 48 | // Input is expected in a form accepted by UnmarshalText. 49 | func FromString(input string) (u UUID, err error) { 50 | err = u.UnmarshalText([]byte(input)) 51 | return 52 | } 53 | 54 | // FromStringOrNil returns UUID parsed from string input. 55 | // Same behavior as FromString, but returns a Nil UUID on error. 56 | func FromStringOrNil(input string) UUID { 57 | uuid, err := FromString(input) 58 | if err != nil { 59 | return Nil 60 | } 61 | return uuid 62 | } 63 | 64 | // MarshalText implements the encoding.TextMarshaler interface. 65 | // The encoding is the same as returned by String. 66 | func (u UUID) MarshalText() (text []byte, err error) { 67 | text = []byte(u.String()) 68 | return 69 | } 70 | 71 | // UnmarshalText implements the encoding.TextUnmarshaler interface. 72 | // Following formats are supported: 73 | // "6ba7b810-9dad-11d1-80b4-00c04fd430c8", 74 | // "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", 75 | // "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" 76 | // "6ba7b8109dad11d180b400c04fd430c8" 77 | // ABNF for supported UUID text representation follows: 78 | // uuid := canonical | hashlike | braced | urn 79 | // plain := canonical | hashlike 80 | // canonical := 4hexoct '-' 2hexoct '-' 2hexoct '-' 6hexoct 81 | // hashlike := 12hexoct 82 | // braced := '{' plain '}' 83 | // urn := URN ':' UUID-NID ':' plain 84 | // URN := 'urn' 85 | // UUID-NID := 'uuid' 86 | // 12hexoct := 6hexoct 6hexoct 87 | // 6hexoct := 4hexoct 2hexoct 88 | // 4hexoct := 2hexoct 2hexoct 89 | // 2hexoct := hexoct hexoct 90 | // hexoct := hexdig hexdig 91 | // hexdig := '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | 92 | // 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 93 | // 'A' | 'B' | 'C' | 'D' | 'E' | 'F' 94 | func (u *UUID) UnmarshalText(text []byte) (err error) { 95 | switch len(text) { 96 | case 32: 97 | return u.decodeHashLike(text) 98 | case 36: 99 | return u.decodeCanonical(text) 100 | case 38: 101 | return u.decodeBraced(text) 102 | case 41: 103 | fallthrough 104 | case 45: 105 | return u.decodeURN(text) 106 | default: 107 | return fmt.Errorf("uuid: incorrect UUID length: %s", text) 108 | } 109 | } 110 | 111 | // decodeCanonical decodes UUID string in format 112 | // "6ba7b810-9dad-11d1-80b4-00c04fd430c8". 113 | func (u *UUID) decodeCanonical(t []byte) (err error) { 114 | if t[8] != '-' || t[13] != '-' || t[18] != '-' || t[23] != '-' { 115 | return fmt.Errorf("uuid: incorrect UUID format %s", t) 116 | } 117 | 118 | src := t[:] 119 | dst := u[:] 120 | 121 | for i, byteGroup := range byteGroups { 122 | if i > 0 { 123 | src = src[1:] // skip dash 124 | } 125 | _, err = hex.Decode(dst[:byteGroup/2], src[:byteGroup]) 126 | if err != nil { 127 | return 128 | } 129 | src = src[byteGroup:] 130 | dst = dst[byteGroup/2:] 131 | } 132 | 133 | return 134 | } 135 | 136 | // decodeHashLike decodes UUID string in format 137 | // "6ba7b8109dad11d180b400c04fd430c8". 138 | func (u *UUID) decodeHashLike(t []byte) (err error) { 139 | src := t[:] 140 | dst := u[:] 141 | 142 | if _, err = hex.Decode(dst, src); err != nil { 143 | return err 144 | } 145 | return 146 | } 147 | 148 | // decodeBraced decodes UUID string in format 149 | // "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" or in format 150 | // "{6ba7b8109dad11d180b400c04fd430c8}". 151 | func (u *UUID) decodeBraced(t []byte) (err error) { 152 | l := len(t) 153 | 154 | if t[0] != '{' || t[l-1] != '}' { 155 | return fmt.Errorf("uuid: incorrect UUID format %s", t) 156 | } 157 | 158 | return u.decodePlain(t[1 : l-1]) 159 | } 160 | 161 | // decodeURN decodes UUID string in format 162 | // "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in format 163 | // "urn:uuid:6ba7b8109dad11d180b400c04fd430c8". 164 | func (u *UUID) decodeURN(t []byte) (err error) { 165 | total := len(t) 166 | 167 | urn_uuid_prefix := t[:9] 168 | 169 | if !bytes.Equal(urn_uuid_prefix, urnPrefix) { 170 | return fmt.Errorf("uuid: incorrect UUID format: %s", t) 171 | } 172 | 173 | return u.decodePlain(t[9:total]) 174 | } 175 | 176 | // decodePlain decodes UUID string in canonical format 177 | // "6ba7b810-9dad-11d1-80b4-00c04fd430c8" or in hash-like format 178 | // "6ba7b8109dad11d180b400c04fd430c8". 179 | func (u *UUID) decodePlain(t []byte) (err error) { 180 | switch len(t) { 181 | case 32: 182 | return u.decodeHashLike(t) 183 | case 36: 184 | return u.decodeCanonical(t) 185 | default: 186 | return fmt.Errorf("uuid: incorrrect UUID length: %s", t) 187 | } 188 | } 189 | 190 | // MarshalBinary implements the encoding.BinaryMarshaler interface. 191 | func (u UUID) MarshalBinary() (data []byte, err error) { 192 | data = u.Bytes() 193 | return 194 | } 195 | 196 | // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. 197 | // It will return error if the slice isn't 16 bytes long. 198 | func (u *UUID) UnmarshalBinary(data []byte) (err error) { 199 | if len(data) != Size { 200 | err = fmt.Errorf("uuid: UUID must be exactly 16 bytes long, got %d bytes", len(data)) 201 | return 202 | } 203 | copy(u[:], data) 204 | 205 | return 206 | } 207 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/codec_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | package uuid 23 | 24 | import ( 25 | "bytes" 26 | 27 | . "gopkg.in/check.v1" 28 | ) 29 | 30 | type codecTestSuite struct{} 31 | 32 | var _ = Suite(&codecTestSuite{}) 33 | 34 | func (s *codecTestSuite) TestFromBytes(c *C) { 35 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 36 | b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 37 | 38 | u1, err := FromBytes(b1) 39 | c.Assert(err, IsNil) 40 | c.Assert(u1, Equals, u) 41 | 42 | b2 := []byte{} 43 | _, err = FromBytes(b2) 44 | c.Assert(err, NotNil) 45 | } 46 | 47 | func (s *codecTestSuite) BenchmarkFromBytes(c *C) { 48 | bytes := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 49 | for i := 0; i < c.N; i++ { 50 | FromBytes(bytes) 51 | } 52 | } 53 | 54 | func (s *codecTestSuite) TestMarshalBinary(c *C) { 55 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 56 | b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 57 | 58 | b2, err := u.MarshalBinary() 59 | c.Assert(err, IsNil) 60 | c.Assert(bytes.Equal(b1, b2), Equals, true) 61 | } 62 | 63 | func (s *codecTestSuite) BenchmarkMarshalBinary(c *C) { 64 | u := NewV4() 65 | for i := 0; i < c.N; i++ { 66 | u.MarshalBinary() 67 | } 68 | } 69 | 70 | func (s *codecTestSuite) TestUnmarshalBinary(c *C) { 71 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 72 | b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 73 | 74 | u1 := UUID{} 75 | err := u1.UnmarshalBinary(b1) 76 | c.Assert(err, IsNil) 77 | c.Assert(u1, Equals, u) 78 | 79 | b2 := []byte{} 80 | u2 := UUID{} 81 | err = u2.UnmarshalBinary(b2) 82 | c.Assert(err, NotNil) 83 | } 84 | 85 | func (s *codecTestSuite) TestFromString(c *C) { 86 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 87 | 88 | s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" 89 | s2 := "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" 90 | s3 := "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" 91 | s4 := "6ba7b8109dad11d180b400c04fd430c8" 92 | s5 := "urn:uuid:6ba7b8109dad11d180b400c04fd430c8" 93 | 94 | _, err := FromString("") 95 | c.Assert(err, NotNil) 96 | 97 | u1, err := FromString(s1) 98 | c.Assert(err, IsNil) 99 | c.Assert(u1, Equals, u) 100 | 101 | u2, err := FromString(s2) 102 | c.Assert(err, IsNil) 103 | c.Assert(u2, Equals, u) 104 | 105 | u3, err := FromString(s3) 106 | c.Assert(err, IsNil) 107 | c.Assert(u3, Equals, u) 108 | 109 | u4, err := FromString(s4) 110 | c.Assert(err, IsNil) 111 | c.Assert(u4, Equals, u) 112 | 113 | u5, err := FromString(s5) 114 | c.Assert(err, IsNil) 115 | c.Assert(u5, Equals, u) 116 | } 117 | 118 | func (s *codecTestSuite) BenchmarkFromString(c *C) { 119 | str := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" 120 | for i := 0; i < c.N; i++ { 121 | FromString(str) 122 | } 123 | } 124 | 125 | func (s *codecTestSuite) BenchmarkFromStringUrn(c *C) { 126 | str := "urn:uuid:6ba7b810-9dad-11d1-80b4-00c04fd430c8" 127 | for i := 0; i < c.N; i++ { 128 | FromString(str) 129 | } 130 | } 131 | 132 | func (s *codecTestSuite) BenchmarkFromStringWithBrackets(c *C) { 133 | str := "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}" 134 | for i := 0; i < c.N; i++ { 135 | FromString(str) 136 | } 137 | } 138 | 139 | func (s *codecTestSuite) TestFromStringShort(c *C) { 140 | // Invalid 35-character UUID string 141 | s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c" 142 | 143 | for i := len(s1); i >= 0; i-- { 144 | _, err := FromString(s1[:i]) 145 | c.Assert(err, NotNil) 146 | } 147 | } 148 | 149 | func (s *codecTestSuite) TestFromStringLong(c *C) { 150 | // Invalid 37+ character UUID string 151 | strings := []string{ 152 | "6ba7b810-9dad-11d1-80b4-00c04fd430c8=", 153 | "6ba7b810-9dad-11d1-80b4-00c04fd430c8}", 154 | "{6ba7b810-9dad-11d1-80b4-00c04fd430c8}f", 155 | "6ba7b810-9dad-11d1-80b4-00c04fd430c800c04fd430c8", 156 | } 157 | 158 | for _, str := range strings { 159 | _, err := FromString(str) 160 | c.Assert(err, NotNil) 161 | } 162 | } 163 | 164 | func (s *codecTestSuite) TestFromStringInvalid(c *C) { 165 | // Invalid UUID string formats 166 | strings := []string{ 167 | "6ba7b8109dad11d180b400c04fd430c86ba7b8109dad11d180b400c04fd430c8", 168 | "urn:uuid:{6ba7b810-9dad-11d1-80b4-00c04fd430c8}", 169 | "uuid:urn:6ba7b810-9dad-11d1-80b4-00c04fd430c8", 170 | "uuid:urn:6ba7b8109dad11d180b400c04fd430c8", 171 | "6ba7b8109-dad-11d1-80b4-00c04fd430c8", 172 | "6ba7b810-9dad1-1d1-80b4-00c04fd430c8", 173 | "6ba7b810-9dad-11d18-0b4-00c04fd430c8", 174 | "6ba7b810-9dad-11d1-80b40-0c04fd430c8", 175 | "6ba7b810+9dad+11d1+80b4+00c04fd430c8", 176 | "(6ba7b810-9dad-11d1-80b4-00c04fd430c8}", 177 | "{6ba7b810-9dad-11d1-80b4-00c04fd430c8>", 178 | "zba7b810-9dad-11d1-80b4-00c04fd430c8", 179 | "6ba7b810-9dad11d180b400c04fd430c8", 180 | "6ba7b8109dad-11d180b400c04fd430c8", 181 | "6ba7b8109dad11d1-80b400c04fd430c8", 182 | "6ba7b8109dad11d180b4-00c04fd430c8", 183 | } 184 | 185 | for _, str := range strings { 186 | _, err := FromString(str) 187 | c.Assert(err, NotNil) 188 | } 189 | } 190 | 191 | func (s *codecTestSuite) TestFromStringOrNil(c *C) { 192 | u := FromStringOrNil("") 193 | c.Assert(u, Equals, Nil) 194 | } 195 | 196 | func (s *codecTestSuite) TestFromBytesOrNil(c *C) { 197 | b := []byte{} 198 | u := FromBytesOrNil(b) 199 | c.Assert(u, Equals, Nil) 200 | } 201 | 202 | func (s *codecTestSuite) TestMarshalText(c *C) { 203 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 204 | b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 205 | 206 | b2, err := u.MarshalText() 207 | c.Assert(err, IsNil) 208 | c.Assert(bytes.Equal(b1, b2), Equals, true) 209 | } 210 | 211 | func (s *codecTestSuite) BenchmarkMarshalText(c *C) { 212 | u := NewV4() 213 | for i := 0; i < c.N; i++ { 214 | u.MarshalText() 215 | } 216 | } 217 | 218 | func (s *codecTestSuite) TestUnmarshalText(c *C) { 219 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 220 | b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 221 | 222 | u1 := UUID{} 223 | err := u1.UnmarshalText(b1) 224 | c.Assert(err, IsNil) 225 | c.Assert(u1, Equals, u) 226 | 227 | b2 := []byte("") 228 | u2 := UUID{} 229 | err = u2.UnmarshalText(b2) 230 | c.Assert(err, NotNil) 231 | } 232 | 233 | func (s *codecTestSuite) BenchmarkUnmarshalText(c *C) { 234 | bytes := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 235 | u := UUID{} 236 | for i := 0; i < c.N; i++ { 237 | u.UnmarshalText(bytes) 238 | } 239 | } 240 | 241 | var sink string 242 | 243 | func (s *codecTestSuite) BenchmarkMarshalToString(c *C) { 244 | u := NewV4() 245 | for i := 0; i < c.N; i++ { 246 | sink = u.String() 247 | } 248 | } 249 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/generator.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | package uuid 23 | 24 | import ( 25 | "crypto/md5" 26 | "crypto/rand" 27 | "crypto/sha1" 28 | "encoding/binary" 29 | "hash" 30 | "net" 31 | "os" 32 | "sync" 33 | "time" 34 | ) 35 | 36 | // Difference in 100-nanosecond intervals between 37 | // UUID epoch (October 15, 1582) and Unix epoch (January 1, 1970). 38 | const epochStart = 122192928000000000 39 | 40 | var ( 41 | global = newDefaultGenerator() 42 | 43 | epochFunc = unixTimeFunc 44 | posixUID = uint32(os.Getuid()) 45 | posixGID = uint32(os.Getgid()) 46 | ) 47 | 48 | // NewV1 returns UUID based on current timestamp and MAC address. 49 | func NewV1() UUID { 50 | return global.NewV1() 51 | } 52 | 53 | // NewV2 returns DCE Security UUID based on POSIX UID/GID. 54 | func NewV2(domain byte) UUID { 55 | return global.NewV2(domain) 56 | } 57 | 58 | // NewV3 returns UUID based on MD5 hash of namespace UUID and name. 59 | func NewV3(ns UUID, name string) UUID { 60 | return global.NewV3(ns, name) 61 | } 62 | 63 | // NewV4 returns random generated UUID. 64 | func NewV4() UUID { 65 | return global.NewV4() 66 | } 67 | 68 | // NewV5 returns UUID based on SHA-1 hash of namespace UUID and name. 69 | func NewV5(ns UUID, name string) UUID { 70 | return global.NewV5(ns, name) 71 | } 72 | 73 | // Generator provides interface for generating UUIDs. 74 | type Generator interface { 75 | NewV1() UUID 76 | NewV2(domain byte) UUID 77 | NewV3(ns UUID, name string) UUID 78 | NewV4() UUID 79 | NewV5(ns UUID, name string) UUID 80 | } 81 | 82 | // Default generator implementation. 83 | type generator struct { 84 | storageOnce sync.Once 85 | storageMutex sync.Mutex 86 | 87 | lastTime uint64 88 | clockSequence uint16 89 | hardwareAddr [6]byte 90 | } 91 | 92 | func newDefaultGenerator() Generator { 93 | return &generator{} 94 | } 95 | 96 | // NewV1 returns UUID based on current timestamp and MAC address. 97 | func (g *generator) NewV1() UUID { 98 | u := UUID{} 99 | 100 | timeNow, clockSeq, hardwareAddr := g.getStorage() 101 | 102 | binary.BigEndian.PutUint32(u[0:], uint32(timeNow)) 103 | binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32)) 104 | binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) 105 | binary.BigEndian.PutUint16(u[8:], clockSeq) 106 | 107 | copy(u[10:], hardwareAddr) 108 | 109 | u.SetVersion(V1) 110 | u.SetVariant(VariantRFC4122) 111 | 112 | return u 113 | } 114 | 115 | // NewV2 returns DCE Security UUID based on POSIX UID/GID. 116 | func (g *generator) NewV2(domain byte) UUID { 117 | u := UUID{} 118 | 119 | timeNow, clockSeq, hardwareAddr := g.getStorage() 120 | 121 | switch domain { 122 | case DomainPerson: 123 | binary.BigEndian.PutUint32(u[0:], posixUID) 124 | case DomainGroup: 125 | binary.BigEndian.PutUint32(u[0:], posixGID) 126 | } 127 | 128 | binary.BigEndian.PutUint16(u[4:], uint16(timeNow>>32)) 129 | binary.BigEndian.PutUint16(u[6:], uint16(timeNow>>48)) 130 | binary.BigEndian.PutUint16(u[8:], clockSeq) 131 | u[9] = domain 132 | 133 | copy(u[10:], hardwareAddr) 134 | 135 | u.SetVersion(V2) 136 | u.SetVariant(VariantRFC4122) 137 | 138 | return u 139 | } 140 | 141 | // NewV3 returns UUID based on MD5 hash of namespace UUID and name. 142 | func (g *generator) NewV3(ns UUID, name string) UUID { 143 | u := newFromHash(md5.New(), ns, name) 144 | u.SetVersion(V3) 145 | u.SetVariant(VariantRFC4122) 146 | 147 | return u 148 | } 149 | 150 | // NewV4 returns random generated UUID. 151 | func (g *generator) NewV4() UUID { 152 | u := UUID{} 153 | g.safeRandom(u[:]) 154 | u.SetVersion(V4) 155 | u.SetVariant(VariantRFC4122) 156 | 157 | return u 158 | } 159 | 160 | // NewV5 returns UUID based on SHA-1 hash of namespace UUID and name. 161 | func (g *generator) NewV5(ns UUID, name string) UUID { 162 | u := newFromHash(sha1.New(), ns, name) 163 | u.SetVersion(V5) 164 | u.SetVariant(VariantRFC4122) 165 | 166 | return u 167 | } 168 | 169 | func (g *generator) initStorage() { 170 | g.initClockSequence() 171 | g.initHardwareAddr() 172 | } 173 | 174 | func (g *generator) initClockSequence() { 175 | buf := make([]byte, 2) 176 | g.safeRandom(buf) 177 | g.clockSequence = binary.BigEndian.Uint16(buf) 178 | } 179 | 180 | func (g *generator) initHardwareAddr() { 181 | interfaces, err := net.Interfaces() 182 | if err == nil { 183 | for _, iface := range interfaces { 184 | if len(iface.HardwareAddr) >= 6 { 185 | copy(g.hardwareAddr[:], iface.HardwareAddr) 186 | return 187 | } 188 | } 189 | } 190 | 191 | // Initialize hardwareAddr randomly in case 192 | // of real network interfaces absence 193 | g.safeRandom(g.hardwareAddr[:]) 194 | 195 | // Set multicast bit as recommended in RFC 4122 196 | g.hardwareAddr[0] |= 0x01 197 | } 198 | 199 | func (g *generator) safeRandom(dest []byte) { 200 | if _, err := rand.Read(dest); err != nil { 201 | panic(err) 202 | } 203 | } 204 | 205 | // Returns UUID v1/v2 storage state. 206 | // Returns epoch timestamp, clock sequence, and hardware address. 207 | func (g *generator) getStorage() (uint64, uint16, []byte) { 208 | g.storageOnce.Do(g.initStorage) 209 | 210 | g.storageMutex.Lock() 211 | defer g.storageMutex.Unlock() 212 | 213 | timeNow := epochFunc() 214 | // Clock changed backwards since last UUID generation. 215 | // Should increase clock sequence. 216 | if timeNow <= g.lastTime { 217 | g.clockSequence++ 218 | } 219 | g.lastTime = timeNow 220 | 221 | return timeNow, g.clockSequence, g.hardwareAddr[:] 222 | } 223 | 224 | // Returns difference in 100-nanosecond intervals between 225 | // UUID epoch (October 15, 1582) and current time. 226 | // This is default epoch calculation function. 227 | func unixTimeFunc() uint64 { 228 | return epochStart + uint64(time.Now().UnixNano()/100) 229 | } 230 | 231 | // Returns UUID based on hashing of namespace UUID and name. 232 | func newFromHash(h hash.Hash, ns UUID, name string) UUID { 233 | u := UUID{} 234 | h.Write(ns[:]) 235 | h.Write([]byte(name)) 236 | copy(u[:], h.Sum(nil)) 237 | 238 | return u 239 | } 240 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/generator_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | package uuid 23 | 24 | import ( 25 | . "gopkg.in/check.v1" 26 | ) 27 | 28 | type genTestSuite struct{} 29 | 30 | var _ = Suite(&genTestSuite{}) 31 | 32 | func (s *genTestSuite) TestNewV1(c *C) { 33 | u := NewV1() 34 | c.Assert(u.Version(), Equals, V1) 35 | c.Assert(u.Variant(), Equals, VariantRFC4122) 36 | 37 | u1 := NewV1() 38 | u2 := NewV1() 39 | c.Assert(u1, Not(Equals), u2) 40 | 41 | oldFunc := epochFunc 42 | epochFunc = func() uint64 { return 0 } 43 | 44 | u3 := NewV1() 45 | u4 := NewV1() 46 | c.Assert(u3, Not(Equals), u4) 47 | 48 | epochFunc = oldFunc 49 | } 50 | 51 | func (s *genTestSuite) BenchmarkNewV1(c *C) { 52 | for i := 0; i < c.N; i++ { 53 | NewV1() 54 | } 55 | } 56 | 57 | func (s *genTestSuite) TestNewV2(c *C) { 58 | u1 := NewV2(DomainPerson) 59 | c.Assert(u1.Version(), Equals, V2) 60 | c.Assert(u1.Variant(), Equals, VariantRFC4122) 61 | 62 | u2 := NewV2(DomainGroup) 63 | c.Assert(u2.Version(), Equals, V2) 64 | c.Assert(u2.Variant(), Equals, VariantRFC4122) 65 | } 66 | 67 | func (s *genTestSuite) BenchmarkNewV2(c *C) { 68 | for i := 0; i < c.N; i++ { 69 | NewV2(DomainPerson) 70 | } 71 | } 72 | 73 | func (s *genTestSuite) TestNewV3(c *C) { 74 | u := NewV3(NamespaceDNS, "www.example.com") 75 | c.Assert(u.Version(), Equals, V3) 76 | c.Assert(u.Variant(), Equals, VariantRFC4122) 77 | c.Assert(u.String(), Equals, "5df41881-3aed-3515-88a7-2f4a814cf09e") 78 | 79 | u = NewV3(NamespaceDNS, "python.org") 80 | c.Assert(u.String(), Equals, "6fa459ea-ee8a-3ca4-894e-db77e160355e") 81 | 82 | u1 := NewV3(NamespaceDNS, "golang.org") 83 | u2 := NewV3(NamespaceDNS, "golang.org") 84 | c.Assert(u1, Equals, u2) 85 | 86 | u3 := NewV3(NamespaceDNS, "example.com") 87 | c.Assert(u1, Not(Equals), u3) 88 | 89 | u4 := NewV3(NamespaceURL, "golang.org") 90 | c.Assert(u1, Not(Equals), u4) 91 | } 92 | 93 | func (s *genTestSuite) BenchmarkNewV3(c *C) { 94 | for i := 0; i < c.N; i++ { 95 | NewV3(NamespaceDNS, "www.example.com") 96 | } 97 | } 98 | 99 | func (s *genTestSuite) TestNewV4(c *C) { 100 | u := NewV4() 101 | c.Assert(u.Version(), Equals, V4) 102 | c.Assert(u.Variant(), Equals, VariantRFC4122) 103 | } 104 | 105 | func (s *genTestSuite) BenchmarkNewV4(c *C) { 106 | for i := 0; i < c.N; i++ { 107 | NewV4() 108 | } 109 | } 110 | 111 | func (s *genTestSuite) TestNewV5(c *C) { 112 | u := NewV5(NamespaceDNS, "www.example.com") 113 | c.Assert(u.Version(), Equals, V5) 114 | c.Assert(u.Variant(), Equals, VariantRFC4122) 115 | 116 | u = NewV5(NamespaceDNS, "python.org") 117 | c.Assert(u.String(), Equals, "886313e1-3b8a-5372-9b90-0c9aee199e5d") 118 | 119 | u1 := NewV5(NamespaceDNS, "golang.org") 120 | u2 := NewV5(NamespaceDNS, "golang.org") 121 | c.Assert(u1, Equals, u2) 122 | 123 | u3 := NewV5(NamespaceDNS, "example.com") 124 | c.Assert(u1, Not(Equals), u3) 125 | 126 | u4 := NewV5(NamespaceURL, "golang.org") 127 | c.Assert(u1, Not(Equals), u4) 128 | } 129 | 130 | func (s *genTestSuite) BenchmarkNewV5(c *C) { 131 | for i := 0; i < c.N; i++ { 132 | NewV5(NamespaceDNS, "www.example.com") 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/sql.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | package uuid 23 | 24 | import ( 25 | "database/sql/driver" 26 | "fmt" 27 | ) 28 | 29 | // Value implements the driver.Valuer interface. 30 | func (u UUID) Value() (driver.Value, error) { 31 | return u.String(), nil 32 | } 33 | 34 | // Scan implements the sql.Scanner interface. 35 | // A 16-byte slice is handled by UnmarshalBinary, while 36 | // a longer byte slice or a string is handled by UnmarshalText. 37 | func (u *UUID) Scan(src interface{}) error { 38 | switch src := src.(type) { 39 | case []byte: 40 | if len(src) == Size { 41 | return u.UnmarshalBinary(src) 42 | } 43 | return u.UnmarshalText(src) 44 | 45 | case string: 46 | return u.UnmarshalText([]byte(src)) 47 | } 48 | 49 | return fmt.Errorf("uuid: cannot convert %T to UUID", src) 50 | } 51 | 52 | // NullUUID can be used with the standard sql package to represent a 53 | // UUID value that can be NULL in the database 54 | type NullUUID struct { 55 | UUID UUID 56 | Valid bool 57 | } 58 | 59 | // Value implements the driver.Valuer interface. 60 | func (u NullUUID) Value() (driver.Value, error) { 61 | if !u.Valid { 62 | return nil, nil 63 | } 64 | // Delegate to UUID Value function 65 | return u.UUID.Value() 66 | } 67 | 68 | // Scan implements the sql.Scanner interface. 69 | func (u *NullUUID) Scan(src interface{}) error { 70 | if src == nil { 71 | u.UUID, u.Valid = Nil, false 72 | return nil 73 | } 74 | 75 | // Delegate to UUID Scan function 76 | u.Valid = true 77 | return u.UUID.Scan(src) 78 | } 79 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/sql_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | package uuid 23 | 24 | import ( 25 | . "gopkg.in/check.v1" 26 | ) 27 | 28 | type sqlTestSuite struct{} 29 | 30 | var _ = Suite(&sqlTestSuite{}) 31 | 32 | func (s *sqlTestSuite) TestValue(c *C) { 33 | u, err := FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 34 | c.Assert(err, IsNil) 35 | 36 | val, err := u.Value() 37 | c.Assert(err, IsNil) 38 | c.Assert(val, Equals, u.String()) 39 | } 40 | 41 | func (s *sqlTestSuite) TestValueNil(c *C) { 42 | u := UUID{} 43 | 44 | val, err := u.Value() 45 | c.Assert(err, IsNil) 46 | c.Assert(val, Equals, Nil.String()) 47 | } 48 | 49 | func (s *sqlTestSuite) TestNullUUIDValueNil(c *C) { 50 | u := NullUUID{} 51 | 52 | val, err := u.Value() 53 | c.Assert(err, IsNil) 54 | c.Assert(val, IsNil) 55 | } 56 | 57 | func (s *sqlTestSuite) TestScanBinary(c *C) { 58 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 59 | b1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 60 | 61 | u1 := UUID{} 62 | err := u1.Scan(b1) 63 | c.Assert(err, IsNil) 64 | c.Assert(u, Equals, u1) 65 | 66 | b2 := []byte{} 67 | u2 := UUID{} 68 | 69 | err = u2.Scan(b2) 70 | c.Assert(err, NotNil) 71 | } 72 | 73 | func (s *sqlTestSuite) TestScanString(c *C) { 74 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 75 | s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" 76 | 77 | u1 := UUID{} 78 | err := u1.Scan(s1) 79 | c.Assert(err, IsNil) 80 | c.Assert(u, Equals, u1) 81 | 82 | s2 := "" 83 | u2 := UUID{} 84 | 85 | err = u2.Scan(s2) 86 | c.Assert(err, NotNil) 87 | } 88 | 89 | func (s *sqlTestSuite) TestScanText(c *C) { 90 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 91 | b1 := []byte("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 92 | 93 | u1 := UUID{} 94 | err := u1.Scan(b1) 95 | c.Assert(err, IsNil) 96 | c.Assert(u, Equals, u1) 97 | 98 | b2 := []byte("") 99 | u2 := UUID{} 100 | err = u2.Scan(b2) 101 | c.Assert(err, NotNil) 102 | } 103 | 104 | func (s *sqlTestSuite) TestScanUnsupported(c *C) { 105 | u := UUID{} 106 | 107 | err := u.Scan(true) 108 | c.Assert(err, NotNil) 109 | } 110 | 111 | func (s *sqlTestSuite) TestScanNil(c *C) { 112 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 113 | 114 | err := u.Scan(nil) 115 | c.Assert(err, NotNil) 116 | } 117 | 118 | func (s *sqlTestSuite) TestNullUUIDScanValid(c *C) { 119 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 120 | s1 := "6ba7b810-9dad-11d1-80b4-00c04fd430c8" 121 | 122 | u1 := NullUUID{} 123 | err := u1.Scan(s1) 124 | c.Assert(err, IsNil) 125 | c.Assert(u1.Valid, Equals, true) 126 | c.Assert(u1.UUID, Equals, u) 127 | } 128 | 129 | func (s *sqlTestSuite) TestNullUUIDScanNil(c *C) { 130 | u := NullUUID{UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8}, true} 131 | 132 | err := u.Scan(nil) 133 | c.Assert(err, IsNil) 134 | c.Assert(u.Valid, Equals, false) 135 | c.Assert(u.UUID, Equals, Nil) 136 | } 137 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/uuid.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | // Package uuid provides implementation of Universally Unique Identifier (UUID). 23 | // Supported versions are 1, 3, 4 and 5 (as specified in RFC 4122) and 24 | // version 2 (as specified in DCE 1.1). 25 | package uuid 26 | 27 | import ( 28 | "bytes" 29 | "encoding/hex" 30 | ) 31 | 32 | // Size of a UUID in bytes. 33 | const Size = 16 34 | 35 | // UUID representation compliant with specification 36 | // described in RFC 4122. 37 | type UUID [Size]byte 38 | 39 | // UUID versions 40 | const ( 41 | _ byte = iota 42 | V1 43 | V2 44 | V3 45 | V4 46 | V5 47 | ) 48 | 49 | // UUID layout variants. 50 | const ( 51 | VariantNCS byte = iota 52 | VariantRFC4122 53 | VariantMicrosoft 54 | VariantFuture 55 | ) 56 | 57 | // UUID DCE domains. 58 | const ( 59 | DomainPerson = iota 60 | DomainGroup 61 | DomainOrg 62 | ) 63 | 64 | // String parse helpers. 65 | var ( 66 | urnPrefix = []byte("urn:uuid:") 67 | byteGroups = []int{8, 4, 4, 4, 12} 68 | ) 69 | 70 | // Nil is special form of UUID that is specified to have all 71 | // 128 bits set to zero. 72 | var Nil = UUID{} 73 | 74 | // Predefined namespace UUIDs. 75 | var ( 76 | NamespaceDNS = Must(FromString("6ba7b810-9dad-11d1-80b4-00c04fd430c8")) 77 | NamespaceURL = Must(FromString("6ba7b811-9dad-11d1-80b4-00c04fd430c8")) 78 | NamespaceOID = Must(FromString("6ba7b812-9dad-11d1-80b4-00c04fd430c8")) 79 | NamespaceX500 = Must(FromString("6ba7b814-9dad-11d1-80b4-00c04fd430c8")) 80 | ) 81 | 82 | // Equal returns true if u1 and u2 equals, otherwise returns false. 83 | func Equal(u1 UUID, u2 UUID) bool { 84 | return bytes.Equal(u1[:], u2[:]) 85 | } 86 | 87 | // Version returns algorithm version used to generate UUID. 88 | func (u UUID) Version() byte { 89 | return u[6] >> 4 90 | } 91 | 92 | // Variant returns UUID layout variant. 93 | func (u UUID) Variant() byte { 94 | switch { 95 | case (u[8] >> 7) == 0x00: 96 | return VariantNCS 97 | case (u[8] >> 6) == 0x02: 98 | return VariantRFC4122 99 | case (u[8] >> 5) == 0x06: 100 | return VariantMicrosoft 101 | case (u[8] >> 5) == 0x07: 102 | fallthrough 103 | default: 104 | return VariantFuture 105 | } 106 | } 107 | 108 | // Bytes returns bytes slice representation of UUID. 109 | func (u UUID) Bytes() []byte { 110 | return u[:] 111 | } 112 | 113 | // Returns canonical string representation of UUID: 114 | // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. 115 | func (u UUID) String() string { 116 | buf := make([]byte, 36) 117 | 118 | hex.Encode(buf[0:8], u[0:4]) 119 | buf[8] = '-' 120 | hex.Encode(buf[9:13], u[4:6]) 121 | buf[13] = '-' 122 | hex.Encode(buf[14:18], u[6:8]) 123 | buf[18] = '-' 124 | hex.Encode(buf[19:23], u[8:10]) 125 | buf[23] = '-' 126 | hex.Encode(buf[24:], u[10:]) 127 | 128 | return string(buf) 129 | } 130 | 131 | // SetVersion sets version bits. 132 | func (u *UUID) SetVersion(v byte) { 133 | u[6] = (u[6] & 0x0f) | (v << 4) 134 | } 135 | 136 | // SetVariant sets variant bits. 137 | func (u *UUID) SetVariant(v byte) { 138 | switch v { 139 | case VariantNCS: 140 | u[8] = (u[8]&(0xff>>1) | (0x00 << 7)) 141 | case VariantRFC4122: 142 | u[8] = (u[8]&(0xff>>2) | (0x02 << 6)) 143 | case VariantMicrosoft: 144 | u[8] = (u[8]&(0xff>>3) | (0x06 << 5)) 145 | case VariantFuture: 146 | fallthrough 147 | default: 148 | u[8] = (u[8]&(0xff>>3) | (0x07 << 5)) 149 | } 150 | } 151 | 152 | // Must is a helper that wraps a call to a function returning (UUID, error) 153 | // and panics if the error is non-nil. It is intended for use in variable 154 | // initializations such as 155 | // var packageUUID = uuid.Must(uuid.FromString("123e4567-e89b-12d3-a456-426655440000")); 156 | func Must(u UUID, err error) UUID { 157 | if err != nil { 158 | panic(err) 159 | } 160 | return u 161 | } 162 | -------------------------------------------------------------------------------- /vendor/github.com/satori/go.uuid/uuid_test.go: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2013-2018 by Maxim Bublis 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining 4 | // a copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to 8 | // permit persons to whom the Software is furnished to do so, subject to 9 | // the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be 12 | // included in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | package uuid 23 | 24 | import ( 25 | "bytes" 26 | "testing" 27 | 28 | . "gopkg.in/check.v1" 29 | ) 30 | 31 | // Hook up gocheck into the "go test" runner. 32 | func TestUUID(t *testing.T) { TestingT(t) } 33 | 34 | type testSuite struct{} 35 | 36 | var _ = Suite(&testSuite{}) 37 | 38 | func (s *testSuite) TestBytes(c *C) { 39 | u := UUID{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 40 | 41 | bytes1 := []byte{0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1, 0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8} 42 | 43 | c.Assert(bytes.Equal(u.Bytes(), bytes1), Equals, true) 44 | } 45 | 46 | func (s *testSuite) TestString(c *C) { 47 | c.Assert(NamespaceDNS.String(), Equals, "6ba7b810-9dad-11d1-80b4-00c04fd430c8") 48 | } 49 | 50 | func (s *testSuite) TestEqual(c *C) { 51 | c.Assert(Equal(NamespaceDNS, NamespaceDNS), Equals, true) 52 | c.Assert(Equal(NamespaceDNS, NamespaceURL), Equals, false) 53 | } 54 | 55 | func (s *testSuite) TestVersion(c *C) { 56 | u := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 57 | c.Assert(u.Version(), Equals, V1) 58 | } 59 | 60 | func (s *testSuite) TestSetVersion(c *C) { 61 | u := UUID{} 62 | u.SetVersion(4) 63 | c.Assert(u.Version(), Equals, V4) 64 | } 65 | 66 | func (s *testSuite) TestVariant(c *C) { 67 | u1 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 68 | c.Assert(u1.Variant(), Equals, VariantNCS) 69 | 70 | u2 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 71 | c.Assert(u2.Variant(), Equals, VariantRFC4122) 72 | 73 | u3 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 74 | c.Assert(u3.Variant(), Equals, VariantMicrosoft) 75 | 76 | u4 := UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 77 | c.Assert(u4.Variant(), Equals, VariantFuture) 78 | } 79 | 80 | func (s *testSuite) TestSetVariant(c *C) { 81 | u := UUID{} 82 | u.SetVariant(VariantNCS) 83 | c.Assert(u.Variant(), Equals, VariantNCS) 84 | u.SetVariant(VariantRFC4122) 85 | c.Assert(u.Variant(), Equals, VariantRFC4122) 86 | u.SetVariant(VariantMicrosoft) 87 | c.Assert(u.Variant(), Equals, VariantMicrosoft) 88 | u.SetVariant(VariantFuture) 89 | c.Assert(u.Variant(), Equals, VariantFuture) 90 | } 91 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/.gitignore: -------------------------------------------------------------------------------- 1 | _* 2 | *.swp 3 | *.[568] 4 | [568].out 5 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go_import_path: gopkg.in/check.v1 4 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/LICENSE: -------------------------------------------------------------------------------- 1 | Gocheck - A rich testing framework for Go 2 | 3 | Copyright (c) 2010-2013 Gustavo Niemeyer 4 | 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | 1. Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | 2. Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 20 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 25 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/README.md: -------------------------------------------------------------------------------- 1 | Instructions 2 | ============ 3 | 4 | Install the package with: 5 | 6 | go get gopkg.in/check.v1 7 | 8 | Import it with: 9 | 10 | import "gopkg.in/check.v1" 11 | 12 | and use _check_ as the package name inside the code. 13 | 14 | For more details, visit the project page: 15 | 16 | * http://labix.org/gocheck 17 | 18 | and the API documentation: 19 | 20 | * https://gopkg.in/check.v1 21 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/TODO: -------------------------------------------------------------------------------- 1 | - Assert(slice, Contains, item) 2 | - Parallel test support 3 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/benchmark.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 The Go Authors. All rights reserved. 2 | // 3 | // Redistribution and use in source and binary forms, with or without 4 | // modification, are permitted provided that the following conditions are 5 | // met: 6 | // 7 | // * Redistributions of source code must retain the above copyright 8 | // notice, this list of conditions and the following disclaimer. 9 | // * Redistributions in binary form must reproduce the above 10 | // copyright notice, this list of conditions and the following disclaimer 11 | // in the documentation and/or other materials provided with the 12 | // distribution. 13 | // * Neither the name of Google Inc. nor the names of its 14 | // contributors may be used to endorse or promote products derived from 15 | // this software without specific prior written permission. 16 | // 17 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | 29 | package check 30 | 31 | import ( 32 | "fmt" 33 | "runtime" 34 | "time" 35 | ) 36 | 37 | var memStats runtime.MemStats 38 | 39 | // testingB is a type passed to Benchmark functions to manage benchmark 40 | // timing and to specify the number of iterations to run. 41 | type timer struct { 42 | start time.Time // Time test or benchmark started 43 | duration time.Duration 44 | N int 45 | bytes int64 46 | timerOn bool 47 | benchTime time.Duration 48 | // The initial states of memStats.Mallocs and memStats.TotalAlloc. 49 | startAllocs uint64 50 | startBytes uint64 51 | // The net total of this test after being run. 52 | netAllocs uint64 53 | netBytes uint64 54 | } 55 | 56 | // StartTimer starts timing a test. This function is called automatically 57 | // before a benchmark starts, but it can also used to resume timing after 58 | // a call to StopTimer. 59 | func (c *C) StartTimer() { 60 | if !c.timerOn { 61 | c.start = time.Now() 62 | c.timerOn = true 63 | 64 | runtime.ReadMemStats(&memStats) 65 | c.startAllocs = memStats.Mallocs 66 | c.startBytes = memStats.TotalAlloc 67 | } 68 | } 69 | 70 | // StopTimer stops timing a test. This can be used to pause the timer 71 | // while performing complex initialization that you don't 72 | // want to measure. 73 | func (c *C) StopTimer() { 74 | if c.timerOn { 75 | c.duration += time.Now().Sub(c.start) 76 | c.timerOn = false 77 | runtime.ReadMemStats(&memStats) 78 | c.netAllocs += memStats.Mallocs - c.startAllocs 79 | c.netBytes += memStats.TotalAlloc - c.startBytes 80 | } 81 | } 82 | 83 | // ResetTimer sets the elapsed benchmark time to zero. 84 | // It does not affect whether the timer is running. 85 | func (c *C) ResetTimer() { 86 | if c.timerOn { 87 | c.start = time.Now() 88 | runtime.ReadMemStats(&memStats) 89 | c.startAllocs = memStats.Mallocs 90 | c.startBytes = memStats.TotalAlloc 91 | } 92 | c.duration = 0 93 | c.netAllocs = 0 94 | c.netBytes = 0 95 | } 96 | 97 | // SetBytes informs the number of bytes that the benchmark processes 98 | // on each iteration. If this is called in a benchmark it will also 99 | // report MB/s. 100 | func (c *C) SetBytes(n int64) { 101 | c.bytes = n 102 | } 103 | 104 | func (c *C) nsPerOp() int64 { 105 | if c.N <= 0 { 106 | return 0 107 | } 108 | return c.duration.Nanoseconds() / int64(c.N) 109 | } 110 | 111 | func (c *C) mbPerSec() float64 { 112 | if c.bytes <= 0 || c.duration <= 0 || c.N <= 0 { 113 | return 0 114 | } 115 | return (float64(c.bytes) * float64(c.N) / 1e6) / c.duration.Seconds() 116 | } 117 | 118 | func (c *C) timerString() string { 119 | if c.N <= 0 { 120 | return fmt.Sprintf("%3.3fs", float64(c.duration.Nanoseconds())/1e9) 121 | } 122 | mbs := c.mbPerSec() 123 | mb := "" 124 | if mbs != 0 { 125 | mb = fmt.Sprintf("\t%7.2f MB/s", mbs) 126 | } 127 | nsop := c.nsPerOp() 128 | ns := fmt.Sprintf("%10d ns/op", nsop) 129 | if c.N > 0 && nsop < 100 { 130 | // The format specifiers here make sure that 131 | // the ones digits line up for all three possible formats. 132 | if nsop < 10 { 133 | ns = fmt.Sprintf("%13.2f ns/op", float64(c.duration.Nanoseconds())/float64(c.N)) 134 | } else { 135 | ns = fmt.Sprintf("%12.1f ns/op", float64(c.duration.Nanoseconds())/float64(c.N)) 136 | } 137 | } 138 | memStats := "" 139 | if c.benchMem { 140 | allocedBytes := fmt.Sprintf("%8d B/op", int64(c.netBytes)/int64(c.N)) 141 | allocs := fmt.Sprintf("%8d allocs/op", int64(c.netAllocs)/int64(c.N)) 142 | memStats = fmt.Sprintf("\t%s\t%s", allocedBytes, allocs) 143 | } 144 | return fmt.Sprintf("%8d\t%s%s%s", c.N, ns, mb, memStats) 145 | } 146 | 147 | func min(x, y int) int { 148 | if x > y { 149 | return y 150 | } 151 | return x 152 | } 153 | 154 | func max(x, y int) int { 155 | if x < y { 156 | return y 157 | } 158 | return x 159 | } 160 | 161 | // roundDown10 rounds a number down to the nearest power of 10. 162 | func roundDown10(n int) int { 163 | var tens = 0 164 | // tens = floor(log_10(n)) 165 | for n > 10 { 166 | n = n / 10 167 | tens++ 168 | } 169 | // result = 10^tens 170 | result := 1 171 | for i := 0; i < tens; i++ { 172 | result *= 10 173 | } 174 | return result 175 | } 176 | 177 | // roundUp rounds x up to a number of the form [1eX, 2eX, 5eX]. 178 | func roundUp(n int) int { 179 | base := roundDown10(n) 180 | if n < (2 * base) { 181 | return 2 * base 182 | } 183 | if n < (5 * base) { 184 | return 5 * base 185 | } 186 | return 10 * base 187 | } 188 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/benchmark_test.go: -------------------------------------------------------------------------------- 1 | // These tests verify the test running logic. 2 | 3 | package check_test 4 | 5 | import ( 6 | "time" 7 | . "gopkg.in/check.v1" 8 | ) 9 | 10 | var benchmarkS = Suite(&BenchmarkS{}) 11 | 12 | type BenchmarkS struct{} 13 | 14 | func (s *BenchmarkS) TestCountSuite(c *C) { 15 | suitesRun += 1 16 | } 17 | 18 | func (s *BenchmarkS) TestBasicTestTiming(c *C) { 19 | helper := FixtureHelper{sleepOn: "Test1", sleep: 1000000 * time.Nanosecond} 20 | output := String{} 21 | runConf := RunConf{Output: &output, Verbose: true} 22 | Run(&helper, &runConf) 23 | 24 | expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test1\t0\\.0[0-9]+s\n" + 25 | "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t0\\.0[0-9]+s\n" 26 | c.Assert(output.value, Matches, expected) 27 | } 28 | 29 | func (s *BenchmarkS) TestStreamTestTiming(c *C) { 30 | helper := FixtureHelper{sleepOn: "SetUpSuite", sleep: 1000000 * time.Nanosecond} 31 | output := String{} 32 | runConf := RunConf{Output: &output, Stream: true} 33 | Run(&helper, &runConf) 34 | 35 | expected := "(?s).*\nPASS: check_test\\.go:[0-9]+: FixtureHelper\\.SetUpSuite\t[0-9]+\\.[0-9]+s\n.*" 36 | c.Assert(output.value, Matches, expected) 37 | } 38 | 39 | func (s *BenchmarkS) TestBenchmark(c *C) { 40 | helper := FixtureHelper{sleep: 100000} 41 | output := String{} 42 | runConf := RunConf{ 43 | Output: &output, 44 | Benchmark: true, 45 | BenchmarkTime: 10000000, 46 | Filter: "Benchmark1", 47 | } 48 | Run(&helper, &runConf) 49 | c.Check(helper.calls[0], Equals, "SetUpSuite") 50 | c.Check(helper.calls[1], Equals, "SetUpTest") 51 | c.Check(helper.calls[2], Equals, "Benchmark1") 52 | c.Check(helper.calls[3], Equals, "TearDownTest") 53 | c.Check(helper.calls[4], Equals, "SetUpTest") 54 | c.Check(helper.calls[5], Equals, "Benchmark1") 55 | c.Check(helper.calls[6], Equals, "TearDownTest") 56 | // ... and more. 57 | 58 | expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark1\t\\s+[0-9]+\t\\s+[0-9]+ ns/op\n" 59 | c.Assert(output.value, Matches, expected) 60 | } 61 | 62 | func (s *BenchmarkS) TestBenchmarkBytes(c *C) { 63 | helper := FixtureHelper{sleep: 100000} 64 | output := String{} 65 | runConf := RunConf{ 66 | Output: &output, 67 | Benchmark: true, 68 | BenchmarkTime: 10000000, 69 | Filter: "Benchmark2", 70 | } 71 | Run(&helper, &runConf) 72 | 73 | expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark2\t\\s+[0-9]+\t\\s+[0-9]+ ns/op\t\\s+ *[1-9]\\.[0-9]{2} MB/s\n" 74 | c.Assert(output.value, Matches, expected) 75 | } 76 | 77 | func (s *BenchmarkS) TestBenchmarkMem(c *C) { 78 | helper := FixtureHelper{sleep: 100000} 79 | output := String{} 80 | runConf := RunConf{ 81 | Output: &output, 82 | Benchmark: true, 83 | BenchmarkMem: true, 84 | BenchmarkTime: 10000000, 85 | Filter: "Benchmark3", 86 | } 87 | Run(&helper, &runConf) 88 | 89 | expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Benchmark3\t\\s+ [0-9]+\t\\s+ *[0-9]+ ns/op\t\\s+ [0-9]+ B/op\t\\s+ [1-9]+ allocs/op\n" 90 | c.Assert(output.value, Matches, expected) 91 | } 92 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/bootstrap_test.go: -------------------------------------------------------------------------------- 1 | // These initial tests are for bootstrapping. They verify that we can 2 | // basically use the testing infrastructure itself to check if the test 3 | // system is working. 4 | // 5 | // These tests use will break down the test runner badly in case of 6 | // errors because if they simply fail, we can't be sure the developer 7 | // will ever see anything (because failing means the failing system 8 | // somehow isn't working! :-) 9 | // 10 | // Do not assume *any* internal functionality works as expected besides 11 | // what's actually tested here. 12 | 13 | package check_test 14 | 15 | import ( 16 | "fmt" 17 | "gopkg.in/check.v1" 18 | "strings" 19 | ) 20 | 21 | type BootstrapS struct{} 22 | 23 | var boostrapS = check.Suite(&BootstrapS{}) 24 | 25 | func (s *BootstrapS) TestCountSuite(c *check.C) { 26 | suitesRun += 1 27 | } 28 | 29 | func (s *BootstrapS) TestFailedAndFail(c *check.C) { 30 | if c.Failed() { 31 | critical("c.Failed() must be false first!") 32 | } 33 | c.Fail() 34 | if !c.Failed() { 35 | critical("c.Fail() didn't put the test in a failed state!") 36 | } 37 | c.Succeed() 38 | } 39 | 40 | func (s *BootstrapS) TestFailedAndSucceed(c *check.C) { 41 | c.Fail() 42 | c.Succeed() 43 | if c.Failed() { 44 | critical("c.Succeed() didn't put the test back in a non-failed state") 45 | } 46 | } 47 | 48 | func (s *BootstrapS) TestLogAndGetTestLog(c *check.C) { 49 | c.Log("Hello there!") 50 | log := c.GetTestLog() 51 | if log != "Hello there!\n" { 52 | critical(fmt.Sprintf("Log() or GetTestLog() is not working! Got: %#v", log)) 53 | } 54 | } 55 | 56 | func (s *BootstrapS) TestLogfAndGetTestLog(c *check.C) { 57 | c.Logf("Hello %v", "there!") 58 | log := c.GetTestLog() 59 | if log != "Hello there!\n" { 60 | critical(fmt.Sprintf("Logf() or GetTestLog() is not working! Got: %#v", log)) 61 | } 62 | } 63 | 64 | func (s *BootstrapS) TestRunShowsErrors(c *check.C) { 65 | output := String{} 66 | check.Run(&FailHelper{}, &check.RunConf{Output: &output}) 67 | if strings.Index(output.value, "Expected failure!") == -1 { 68 | critical(fmt.Sprintf("RunWithWriter() output did not contain the "+ 69 | "expected failure! Got: %#v", 70 | output.value)) 71 | } 72 | } 73 | 74 | func (s *BootstrapS) TestRunDoesntShowSuccesses(c *check.C) { 75 | output := String{} 76 | check.Run(&SuccessHelper{}, &check.RunConf{Output: &output}) 77 | if strings.Index(output.value, "Expected success!") != -1 { 78 | critical(fmt.Sprintf("RunWithWriter() output contained a successful "+ 79 | "test! Got: %#v", 80 | output.value)) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/check_test.go: -------------------------------------------------------------------------------- 1 | // This file contains just a few generic helpers which are used by the 2 | // other test files. 3 | 4 | package check_test 5 | 6 | import ( 7 | "flag" 8 | "fmt" 9 | "os" 10 | "regexp" 11 | "runtime" 12 | "testing" 13 | "time" 14 | 15 | "gopkg.in/check.v1" 16 | ) 17 | 18 | // We count the number of suites run at least to get a vague hint that the 19 | // test suite is behaving as it should. Otherwise a bug introduced at the 20 | // very core of the system could go unperceived. 21 | const suitesRunExpected = 8 22 | 23 | var suitesRun int = 0 24 | 25 | func Test(t *testing.T) { 26 | check.TestingT(t) 27 | if suitesRun != suitesRunExpected && flag.Lookup("check.f").Value.String() == "" { 28 | critical(fmt.Sprintf("Expected %d suites to run rather than %d", 29 | suitesRunExpected, suitesRun)) 30 | } 31 | } 32 | 33 | // ----------------------------------------------------------------------- 34 | // Helper functions. 35 | 36 | // Break down badly. This is used in test cases which can't yet assume 37 | // that the fundamental bits are working. 38 | func critical(error string) { 39 | fmt.Fprintln(os.Stderr, "CRITICAL: "+error) 40 | os.Exit(1) 41 | } 42 | 43 | // Return the file line where it's called. 44 | func getMyLine() int { 45 | if _, _, line, ok := runtime.Caller(1); ok { 46 | return line 47 | } 48 | return -1 49 | } 50 | 51 | // ----------------------------------------------------------------------- 52 | // Helper type implementing a basic io.Writer for testing output. 53 | 54 | // Type implementing the io.Writer interface for analyzing output. 55 | type String struct { 56 | value string 57 | } 58 | 59 | // The only function required by the io.Writer interface. Will append 60 | // written data to the String.value string. 61 | func (s *String) Write(p []byte) (n int, err error) { 62 | s.value += string(p) 63 | return len(p), nil 64 | } 65 | 66 | // Trivial wrapper to test errors happening on a different file 67 | // than the test itself. 68 | func checkEqualWrapper(c *check.C, obtained, expected interface{}) (result bool, line int) { 69 | return c.Check(obtained, check.Equals, expected), getMyLine() 70 | } 71 | 72 | // ----------------------------------------------------------------------- 73 | // Helper suite for testing basic fail behavior. 74 | 75 | type FailHelper struct { 76 | testLine int 77 | } 78 | 79 | func (s *FailHelper) TestLogAndFail(c *check.C) { 80 | s.testLine = getMyLine() - 1 81 | c.Log("Expected failure!") 82 | c.Fail() 83 | } 84 | 85 | // ----------------------------------------------------------------------- 86 | // Helper suite for testing basic success behavior. 87 | 88 | type SuccessHelper struct{} 89 | 90 | func (s *SuccessHelper) TestLogAndSucceed(c *check.C) { 91 | c.Log("Expected success!") 92 | } 93 | 94 | // ----------------------------------------------------------------------- 95 | // Helper suite for testing ordering and behavior of fixture. 96 | 97 | type FixtureHelper struct { 98 | calls []string 99 | panicOn string 100 | skip bool 101 | skipOnN int 102 | sleepOn string 103 | sleep time.Duration 104 | bytes int64 105 | } 106 | 107 | func (s *FixtureHelper) trace(name string, c *check.C) { 108 | s.calls = append(s.calls, name) 109 | if name == s.panicOn { 110 | panic(name) 111 | } 112 | if s.sleep > 0 && s.sleepOn == name { 113 | time.Sleep(s.sleep) 114 | } 115 | if s.skip && s.skipOnN == len(s.calls)-1 { 116 | c.Skip("skipOnN == n") 117 | } 118 | } 119 | 120 | func (s *FixtureHelper) SetUpSuite(c *check.C) { 121 | s.trace("SetUpSuite", c) 122 | } 123 | 124 | func (s *FixtureHelper) TearDownSuite(c *check.C) { 125 | s.trace("TearDownSuite", c) 126 | } 127 | 128 | func (s *FixtureHelper) SetUpTest(c *check.C) { 129 | s.trace("SetUpTest", c) 130 | } 131 | 132 | func (s *FixtureHelper) TearDownTest(c *check.C) { 133 | s.trace("TearDownTest", c) 134 | } 135 | 136 | func (s *FixtureHelper) Test1(c *check.C) { 137 | s.trace("Test1", c) 138 | } 139 | 140 | func (s *FixtureHelper) Test2(c *check.C) { 141 | s.trace("Test2", c) 142 | } 143 | 144 | func (s *FixtureHelper) Benchmark1(c *check.C) { 145 | s.trace("Benchmark1", c) 146 | for i := 0; i < c.N; i++ { 147 | time.Sleep(s.sleep) 148 | } 149 | } 150 | 151 | func (s *FixtureHelper) Benchmark2(c *check.C) { 152 | s.trace("Benchmark2", c) 153 | c.SetBytes(1024) 154 | for i := 0; i < c.N; i++ { 155 | time.Sleep(s.sleep) 156 | } 157 | } 158 | 159 | func (s *FixtureHelper) Benchmark3(c *check.C) { 160 | var x []int64 161 | s.trace("Benchmark3", c) 162 | for i := 0; i < c.N; i++ { 163 | time.Sleep(s.sleep) 164 | x = make([]int64, 5) 165 | _ = x 166 | } 167 | } 168 | 169 | // ----------------------------------------------------------------------- 170 | // Helper which checks the state of the test and ensures that it matches 171 | // the given expectations. Depends on c.Errorf() working, so shouldn't 172 | // be used to test this one function. 173 | 174 | type expectedState struct { 175 | name string 176 | result interface{} 177 | failed bool 178 | log string 179 | } 180 | 181 | // Verify the state of the test. Note that since this also verifies if 182 | // the test is supposed to be in a failed state, no other checks should 183 | // be done in addition to what is being tested. 184 | func checkState(c *check.C, result interface{}, expected *expectedState) { 185 | failed := c.Failed() 186 | c.Succeed() 187 | log := c.GetTestLog() 188 | matched, matchError := regexp.MatchString("^"+expected.log+"$", log) 189 | if matchError != nil { 190 | c.Errorf("Error in matching expression used in testing %s", 191 | expected.name) 192 | } else if !matched { 193 | c.Errorf("%s logged:\n----------\n%s----------\n\nExpected:\n----------\n%s\n----------", 194 | expected.name, log, expected.log) 195 | } 196 | if result != expected.result { 197 | c.Errorf("%s returned %#v rather than %#v", 198 | expected.name, result, expected.result) 199 | } 200 | if failed != expected.failed { 201 | if failed { 202 | c.Errorf("%s has failed when it shouldn't", expected.name) 203 | } else { 204 | c.Errorf("%s has not failed when it should", expected.name) 205 | } 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/checkers.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "regexp" 7 | ) 8 | 9 | // ----------------------------------------------------------------------- 10 | // CommentInterface and Commentf helper, to attach extra information to checks. 11 | 12 | type comment struct { 13 | format string 14 | args []interface{} 15 | } 16 | 17 | // Commentf returns an infomational value to use with Assert or Check calls. 18 | // If the checker test fails, the provided arguments will be passed to 19 | // fmt.Sprintf, and will be presented next to the logged failure. 20 | // 21 | // For example: 22 | // 23 | // c.Assert(v, Equals, 42, Commentf("Iteration #%d failed.", i)) 24 | // 25 | // Note that if the comment is constant, a better option is to 26 | // simply use a normal comment right above or next to the line, as 27 | // it will also get printed with any errors: 28 | // 29 | // c.Assert(l, Equals, 8192) // Ensure buffer size is correct (bug #123) 30 | // 31 | func Commentf(format string, args ...interface{}) CommentInterface { 32 | return &comment{format, args} 33 | } 34 | 35 | // CommentInterface must be implemented by types that attach extra 36 | // information to failed checks. See the Commentf function for details. 37 | type CommentInterface interface { 38 | CheckCommentString() string 39 | } 40 | 41 | func (c *comment) CheckCommentString() string { 42 | return fmt.Sprintf(c.format, c.args...) 43 | } 44 | 45 | // ----------------------------------------------------------------------- 46 | // The Checker interface. 47 | 48 | // The Checker interface must be provided by checkers used with 49 | // the Assert and Check verification methods. 50 | type Checker interface { 51 | Info() *CheckerInfo 52 | Check(params []interface{}, names []string) (result bool, error string) 53 | } 54 | 55 | // See the Checker interface. 56 | type CheckerInfo struct { 57 | Name string 58 | Params []string 59 | } 60 | 61 | func (info *CheckerInfo) Info() *CheckerInfo { 62 | return info 63 | } 64 | 65 | // ----------------------------------------------------------------------- 66 | // Not checker logic inverter. 67 | 68 | // The Not checker inverts the logic of the provided checker. The 69 | // resulting checker will succeed where the original one failed, and 70 | // vice-versa. 71 | // 72 | // For example: 73 | // 74 | // c.Assert(a, Not(Equals), b) 75 | // 76 | func Not(checker Checker) Checker { 77 | return ¬Checker{checker} 78 | } 79 | 80 | type notChecker struct { 81 | sub Checker 82 | } 83 | 84 | func (checker *notChecker) Info() *CheckerInfo { 85 | info := *checker.sub.Info() 86 | info.Name = "Not(" + info.Name + ")" 87 | return &info 88 | } 89 | 90 | func (checker *notChecker) Check(params []interface{}, names []string) (result bool, error string) { 91 | result, error = checker.sub.Check(params, names) 92 | result = !result 93 | return 94 | } 95 | 96 | // ----------------------------------------------------------------------- 97 | // IsNil checker. 98 | 99 | type isNilChecker struct { 100 | *CheckerInfo 101 | } 102 | 103 | // The IsNil checker tests whether the obtained value is nil. 104 | // 105 | // For example: 106 | // 107 | // c.Assert(err, IsNil) 108 | // 109 | var IsNil Checker = &isNilChecker{ 110 | &CheckerInfo{Name: "IsNil", Params: []string{"value"}}, 111 | } 112 | 113 | func (checker *isNilChecker) Check(params []interface{}, names []string) (result bool, error string) { 114 | return isNil(params[0]), "" 115 | } 116 | 117 | func isNil(obtained interface{}) (result bool) { 118 | if obtained == nil { 119 | result = true 120 | } else { 121 | switch v := reflect.ValueOf(obtained); v.Kind() { 122 | case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: 123 | return v.IsNil() 124 | } 125 | } 126 | return 127 | } 128 | 129 | // ----------------------------------------------------------------------- 130 | // NotNil checker. Alias for Not(IsNil), since it's so common. 131 | 132 | type notNilChecker struct { 133 | *CheckerInfo 134 | } 135 | 136 | // The NotNil checker verifies that the obtained value is not nil. 137 | // 138 | // For example: 139 | // 140 | // c.Assert(iface, NotNil) 141 | // 142 | // This is an alias for Not(IsNil), made available since it's a 143 | // fairly common check. 144 | // 145 | var NotNil Checker = ¬NilChecker{ 146 | &CheckerInfo{Name: "NotNil", Params: []string{"value"}}, 147 | } 148 | 149 | func (checker *notNilChecker) Check(params []interface{}, names []string) (result bool, error string) { 150 | return !isNil(params[0]), "" 151 | } 152 | 153 | // ----------------------------------------------------------------------- 154 | // Equals checker. 155 | 156 | type equalsChecker struct { 157 | *CheckerInfo 158 | } 159 | 160 | // The Equals checker verifies that the obtained value is equal to 161 | // the expected value, according to usual Go semantics for ==. 162 | // 163 | // For example: 164 | // 165 | // c.Assert(value, Equals, 42) 166 | // 167 | var Equals Checker = &equalsChecker{ 168 | &CheckerInfo{Name: "Equals", Params: []string{"obtained", "expected"}}, 169 | } 170 | 171 | func (checker *equalsChecker) Check(params []interface{}, names []string) (result bool, error string) { 172 | defer func() { 173 | if v := recover(); v != nil { 174 | result = false 175 | error = fmt.Sprint(v) 176 | } 177 | }() 178 | return params[0] == params[1], "" 179 | } 180 | 181 | // ----------------------------------------------------------------------- 182 | // DeepEquals checker. 183 | 184 | type deepEqualsChecker struct { 185 | *CheckerInfo 186 | } 187 | 188 | // The DeepEquals checker verifies that the obtained value is deep-equal to 189 | // the expected value. The check will work correctly even when facing 190 | // slices, interfaces, and values of different types (which always fail 191 | // the test). 192 | // 193 | // For example: 194 | // 195 | // c.Assert(value, DeepEquals, 42) 196 | // c.Assert(array, DeepEquals, []string{"hi", "there"}) 197 | // 198 | var DeepEquals Checker = &deepEqualsChecker{ 199 | &CheckerInfo{Name: "DeepEquals", Params: []string{"obtained", "expected"}}, 200 | } 201 | 202 | func (checker *deepEqualsChecker) Check(params []interface{}, names []string) (result bool, error string) { 203 | return reflect.DeepEqual(params[0], params[1]), "" 204 | } 205 | 206 | // ----------------------------------------------------------------------- 207 | // HasLen checker. 208 | 209 | type hasLenChecker struct { 210 | *CheckerInfo 211 | } 212 | 213 | // The HasLen checker verifies that the obtained value has the 214 | // provided length. In many cases this is superior to using Equals 215 | // in conjunction with the len function because in case the check 216 | // fails the value itself will be printed, instead of its length, 217 | // providing more details for figuring the problem. 218 | // 219 | // For example: 220 | // 221 | // c.Assert(list, HasLen, 5) 222 | // 223 | var HasLen Checker = &hasLenChecker{ 224 | &CheckerInfo{Name: "HasLen", Params: []string{"obtained", "n"}}, 225 | } 226 | 227 | func (checker *hasLenChecker) Check(params []interface{}, names []string) (result bool, error string) { 228 | n, ok := params[1].(int) 229 | if !ok { 230 | return false, "n must be an int" 231 | } 232 | value := reflect.ValueOf(params[0]) 233 | switch value.Kind() { 234 | case reflect.Map, reflect.Array, reflect.Slice, reflect.Chan, reflect.String: 235 | default: 236 | return false, "obtained value type has no length" 237 | } 238 | return value.Len() == n, "" 239 | } 240 | 241 | // ----------------------------------------------------------------------- 242 | // ErrorMatches checker. 243 | 244 | type errorMatchesChecker struct { 245 | *CheckerInfo 246 | } 247 | 248 | // The ErrorMatches checker verifies that the error value 249 | // is non nil and matches the regular expression provided. 250 | // 251 | // For example: 252 | // 253 | // c.Assert(err, ErrorMatches, "perm.*denied") 254 | // 255 | var ErrorMatches Checker = errorMatchesChecker{ 256 | &CheckerInfo{Name: "ErrorMatches", Params: []string{"value", "regex"}}, 257 | } 258 | 259 | func (checker errorMatchesChecker) Check(params []interface{}, names []string) (result bool, errStr string) { 260 | if params[0] == nil { 261 | return false, "Error value is nil" 262 | } 263 | err, ok := params[0].(error) 264 | if !ok { 265 | return false, "Value is not an error" 266 | } 267 | params[0] = err.Error() 268 | names[0] = "error" 269 | return matches(params[0], params[1]) 270 | } 271 | 272 | // ----------------------------------------------------------------------- 273 | // Matches checker. 274 | 275 | type matchesChecker struct { 276 | *CheckerInfo 277 | } 278 | 279 | // The Matches checker verifies that the string provided as the obtained 280 | // value (or the string resulting from obtained.String()) matches the 281 | // regular expression provided. 282 | // 283 | // For example: 284 | // 285 | // c.Assert(err, Matches, "perm.*denied") 286 | // 287 | var Matches Checker = &matchesChecker{ 288 | &CheckerInfo{Name: "Matches", Params: []string{"value", "regex"}}, 289 | } 290 | 291 | func (checker *matchesChecker) Check(params []interface{}, names []string) (result bool, error string) { 292 | return matches(params[0], params[1]) 293 | } 294 | 295 | func matches(value, regex interface{}) (result bool, error string) { 296 | reStr, ok := regex.(string) 297 | if !ok { 298 | return false, "Regex must be a string" 299 | } 300 | valueStr, valueIsStr := value.(string) 301 | if !valueIsStr { 302 | if valueWithStr, valueHasStr := value.(fmt.Stringer); valueHasStr { 303 | valueStr, valueIsStr = valueWithStr.String(), true 304 | } 305 | } 306 | if valueIsStr { 307 | matches, err := regexp.MatchString("^"+reStr+"$", valueStr) 308 | if err != nil { 309 | return false, "Can't compile regex: " + err.Error() 310 | } 311 | return matches, "" 312 | } 313 | return false, "Obtained value is not a string and has no .String()" 314 | } 315 | 316 | // ----------------------------------------------------------------------- 317 | // Panics checker. 318 | 319 | type panicsChecker struct { 320 | *CheckerInfo 321 | } 322 | 323 | // The Panics checker verifies that calling the provided zero-argument 324 | // function will cause a panic which is deep-equal to the provided value. 325 | // 326 | // For example: 327 | // 328 | // c.Assert(func() { f(1, 2) }, Panics, &SomeErrorType{"BOOM"}). 329 | // 330 | // 331 | var Panics Checker = &panicsChecker{ 332 | &CheckerInfo{Name: "Panics", Params: []string{"function", "expected"}}, 333 | } 334 | 335 | func (checker *panicsChecker) Check(params []interface{}, names []string) (result bool, error string) { 336 | f := reflect.ValueOf(params[0]) 337 | if f.Kind() != reflect.Func || f.Type().NumIn() != 0 { 338 | return false, "Function must take zero arguments" 339 | } 340 | defer func() { 341 | // If the function has not panicked, then don't do the check. 342 | if error != "" { 343 | return 344 | } 345 | params[0] = recover() 346 | names[0] = "panic" 347 | result = reflect.DeepEqual(params[0], params[1]) 348 | }() 349 | f.Call(nil) 350 | return false, "Function has not panicked" 351 | } 352 | 353 | type panicMatchesChecker struct { 354 | *CheckerInfo 355 | } 356 | 357 | // The PanicMatches checker verifies that calling the provided zero-argument 358 | // function will cause a panic with an error value matching 359 | // the regular expression provided. 360 | // 361 | // For example: 362 | // 363 | // c.Assert(func() { f(1, 2) }, PanicMatches, `open.*: no such file or directory`). 364 | // 365 | // 366 | var PanicMatches Checker = &panicMatchesChecker{ 367 | &CheckerInfo{Name: "PanicMatches", Params: []string{"function", "expected"}}, 368 | } 369 | 370 | func (checker *panicMatchesChecker) Check(params []interface{}, names []string) (result bool, errmsg string) { 371 | f := reflect.ValueOf(params[0]) 372 | if f.Kind() != reflect.Func || f.Type().NumIn() != 0 { 373 | return false, "Function must take zero arguments" 374 | } 375 | defer func() { 376 | // If the function has not panicked, then don't do the check. 377 | if errmsg != "" { 378 | return 379 | } 380 | obtained := recover() 381 | names[0] = "panic" 382 | if e, ok := obtained.(error); ok { 383 | params[0] = e.Error() 384 | } else if _, ok := obtained.(string); ok { 385 | params[0] = obtained 386 | } else { 387 | errmsg = "Panic value is not a string or an error" 388 | return 389 | } 390 | result, errmsg = matches(params[0], params[1]) 391 | }() 392 | f.Call(nil) 393 | return false, "Function has not panicked" 394 | } 395 | 396 | // ----------------------------------------------------------------------- 397 | // FitsTypeOf checker. 398 | 399 | type fitsTypeChecker struct { 400 | *CheckerInfo 401 | } 402 | 403 | // The FitsTypeOf checker verifies that the obtained value is 404 | // assignable to a variable with the same type as the provided 405 | // sample value. 406 | // 407 | // For example: 408 | // 409 | // c.Assert(value, FitsTypeOf, int64(0)) 410 | // c.Assert(value, FitsTypeOf, os.Error(nil)) 411 | // 412 | var FitsTypeOf Checker = &fitsTypeChecker{ 413 | &CheckerInfo{Name: "FitsTypeOf", Params: []string{"obtained", "sample"}}, 414 | } 415 | 416 | func (checker *fitsTypeChecker) Check(params []interface{}, names []string) (result bool, error string) { 417 | obtained := reflect.ValueOf(params[0]) 418 | sample := reflect.ValueOf(params[1]) 419 | if !obtained.IsValid() { 420 | return false, "" 421 | } 422 | if !sample.IsValid() { 423 | return false, "Invalid sample value" 424 | } 425 | return obtained.Type().AssignableTo(sample.Type()), "" 426 | } 427 | 428 | // ----------------------------------------------------------------------- 429 | // Implements checker. 430 | 431 | type implementsChecker struct { 432 | *CheckerInfo 433 | } 434 | 435 | // The Implements checker verifies that the obtained value 436 | // implements the interface specified via a pointer to an interface 437 | // variable. 438 | // 439 | // For example: 440 | // 441 | // var e os.Error 442 | // c.Assert(err, Implements, &e) 443 | // 444 | var Implements Checker = &implementsChecker{ 445 | &CheckerInfo{Name: "Implements", Params: []string{"obtained", "ifaceptr"}}, 446 | } 447 | 448 | func (checker *implementsChecker) Check(params []interface{}, names []string) (result bool, error string) { 449 | obtained := reflect.ValueOf(params[0]) 450 | ifaceptr := reflect.ValueOf(params[1]) 451 | if !obtained.IsValid() { 452 | return false, "" 453 | } 454 | if !ifaceptr.IsValid() || ifaceptr.Kind() != reflect.Ptr || ifaceptr.Elem().Kind() != reflect.Interface { 455 | return false, "ifaceptr should be a pointer to an interface variable" 456 | } 457 | return obtained.Type().Implements(ifaceptr.Elem().Type()), "" 458 | } 459 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/checkers_test.go: -------------------------------------------------------------------------------- 1 | package check_test 2 | 3 | import ( 4 | "errors" 5 | "gopkg.in/check.v1" 6 | "reflect" 7 | "runtime" 8 | ) 9 | 10 | type CheckersS struct{} 11 | 12 | var _ = check.Suite(&CheckersS{}) 13 | 14 | func testInfo(c *check.C, checker check.Checker, name string, paramNames []string) { 15 | info := checker.Info() 16 | if info.Name != name { 17 | c.Fatalf("Got name %s, expected %s", info.Name, name) 18 | } 19 | if !reflect.DeepEqual(info.Params, paramNames) { 20 | c.Fatalf("Got param names %#v, expected %#v", info.Params, paramNames) 21 | } 22 | } 23 | 24 | func testCheck(c *check.C, checker check.Checker, result bool, error string, params ...interface{}) ([]interface{}, []string) { 25 | info := checker.Info() 26 | if len(params) != len(info.Params) { 27 | c.Fatalf("unexpected param count in test; expected %d got %d", len(info.Params), len(params)) 28 | } 29 | names := append([]string{}, info.Params...) 30 | result_, error_ := checker.Check(params, names) 31 | if result_ != result || error_ != error { 32 | c.Fatalf("%s.Check(%#v) returned (%#v, %#v) rather than (%#v, %#v)", 33 | info.Name, params, result_, error_, result, error) 34 | } 35 | return params, names 36 | } 37 | 38 | func (s *CheckersS) TestComment(c *check.C) { 39 | bug := check.Commentf("a %d bc", 42) 40 | comment := bug.CheckCommentString() 41 | if comment != "a 42 bc" { 42 | c.Fatalf("Commentf returned %#v", comment) 43 | } 44 | } 45 | 46 | func (s *CheckersS) TestIsNil(c *check.C) { 47 | testInfo(c, check.IsNil, "IsNil", []string{"value"}) 48 | 49 | testCheck(c, check.IsNil, true, "", nil) 50 | testCheck(c, check.IsNil, false, "", "a") 51 | 52 | testCheck(c, check.IsNil, true, "", (chan int)(nil)) 53 | testCheck(c, check.IsNil, false, "", make(chan int)) 54 | testCheck(c, check.IsNil, true, "", (error)(nil)) 55 | testCheck(c, check.IsNil, false, "", errors.New("")) 56 | testCheck(c, check.IsNil, true, "", ([]int)(nil)) 57 | testCheck(c, check.IsNil, false, "", make([]int, 1)) 58 | testCheck(c, check.IsNil, false, "", int(0)) 59 | } 60 | 61 | func (s *CheckersS) TestNotNil(c *check.C) { 62 | testInfo(c, check.NotNil, "NotNil", []string{"value"}) 63 | 64 | testCheck(c, check.NotNil, false, "", nil) 65 | testCheck(c, check.NotNil, true, "", "a") 66 | 67 | testCheck(c, check.NotNil, false, "", (chan int)(nil)) 68 | testCheck(c, check.NotNil, true, "", make(chan int)) 69 | testCheck(c, check.NotNil, false, "", (error)(nil)) 70 | testCheck(c, check.NotNil, true, "", errors.New("")) 71 | testCheck(c, check.NotNil, false, "", ([]int)(nil)) 72 | testCheck(c, check.NotNil, true, "", make([]int, 1)) 73 | } 74 | 75 | func (s *CheckersS) TestNot(c *check.C) { 76 | testInfo(c, check.Not(check.IsNil), "Not(IsNil)", []string{"value"}) 77 | 78 | testCheck(c, check.Not(check.IsNil), false, "", nil) 79 | testCheck(c, check.Not(check.IsNil), true, "", "a") 80 | } 81 | 82 | type simpleStruct struct { 83 | i int 84 | } 85 | 86 | func (s *CheckersS) TestEquals(c *check.C) { 87 | testInfo(c, check.Equals, "Equals", []string{"obtained", "expected"}) 88 | 89 | // The simplest. 90 | testCheck(c, check.Equals, true, "", 42, 42) 91 | testCheck(c, check.Equals, false, "", 42, 43) 92 | 93 | // Different native types. 94 | testCheck(c, check.Equals, false, "", int32(42), int64(42)) 95 | 96 | // With nil. 97 | testCheck(c, check.Equals, false, "", 42, nil) 98 | 99 | // Slices 100 | testCheck(c, check.Equals, false, "runtime error: comparing uncomparable type []uint8", []byte{1, 2}, []byte{1, 2}) 101 | 102 | // Struct values 103 | testCheck(c, check.Equals, true, "", simpleStruct{1}, simpleStruct{1}) 104 | testCheck(c, check.Equals, false, "", simpleStruct{1}, simpleStruct{2}) 105 | 106 | // Struct pointers 107 | testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{1}) 108 | testCheck(c, check.Equals, false, "", &simpleStruct{1}, &simpleStruct{2}) 109 | } 110 | 111 | func (s *CheckersS) TestDeepEquals(c *check.C) { 112 | testInfo(c, check.DeepEquals, "DeepEquals", []string{"obtained", "expected"}) 113 | 114 | // The simplest. 115 | testCheck(c, check.DeepEquals, true, "", 42, 42) 116 | testCheck(c, check.DeepEquals, false, "", 42, 43) 117 | 118 | // Different native types. 119 | testCheck(c, check.DeepEquals, false, "", int32(42), int64(42)) 120 | 121 | // With nil. 122 | testCheck(c, check.DeepEquals, false, "", 42, nil) 123 | 124 | // Slices 125 | testCheck(c, check.DeepEquals, true, "", []byte{1, 2}, []byte{1, 2}) 126 | testCheck(c, check.DeepEquals, false, "", []byte{1, 2}, []byte{1, 3}) 127 | 128 | // Struct values 129 | testCheck(c, check.DeepEquals, true, "", simpleStruct{1}, simpleStruct{1}) 130 | testCheck(c, check.DeepEquals, false, "", simpleStruct{1}, simpleStruct{2}) 131 | 132 | // Struct pointers 133 | testCheck(c, check.DeepEquals, true, "", &simpleStruct{1}, &simpleStruct{1}) 134 | testCheck(c, check.DeepEquals, false, "", &simpleStruct{1}, &simpleStruct{2}) 135 | } 136 | 137 | func (s *CheckersS) TestHasLen(c *check.C) { 138 | testInfo(c, check.HasLen, "HasLen", []string{"obtained", "n"}) 139 | 140 | testCheck(c, check.HasLen, true, "", "abcd", 4) 141 | testCheck(c, check.HasLen, true, "", []int{1, 2}, 2) 142 | testCheck(c, check.HasLen, false, "", []int{1, 2}, 3) 143 | 144 | testCheck(c, check.HasLen, false, "n must be an int", []int{1, 2}, "2") 145 | testCheck(c, check.HasLen, false, "obtained value type has no length", nil, 2) 146 | } 147 | 148 | func (s *CheckersS) TestErrorMatches(c *check.C) { 149 | testInfo(c, check.ErrorMatches, "ErrorMatches", []string{"value", "regex"}) 150 | 151 | testCheck(c, check.ErrorMatches, false, "Error value is nil", nil, "some error") 152 | testCheck(c, check.ErrorMatches, false, "Value is not an error", 1, "some error") 153 | testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "some error") 154 | testCheck(c, check.ErrorMatches, true, "", errors.New("some error"), "so.*or") 155 | 156 | // Verify params mutation 157 | params, names := testCheck(c, check.ErrorMatches, false, "", errors.New("some error"), "other error") 158 | c.Assert(params[0], check.Equals, "some error") 159 | c.Assert(names[0], check.Equals, "error") 160 | } 161 | 162 | func (s *CheckersS) TestMatches(c *check.C) { 163 | testInfo(c, check.Matches, "Matches", []string{"value", "regex"}) 164 | 165 | // Simple matching 166 | testCheck(c, check.Matches, true, "", "abc", "abc") 167 | testCheck(c, check.Matches, true, "", "abc", "a.c") 168 | 169 | // Must match fully 170 | testCheck(c, check.Matches, false, "", "abc", "ab") 171 | testCheck(c, check.Matches, false, "", "abc", "bc") 172 | 173 | // String()-enabled values accepted 174 | testCheck(c, check.Matches, true, "", reflect.ValueOf("abc"), "a.c") 175 | testCheck(c, check.Matches, false, "", reflect.ValueOf("abc"), "a.d") 176 | 177 | // Some error conditions. 178 | testCheck(c, check.Matches, false, "Obtained value is not a string and has no .String()", 1, "a.c") 179 | testCheck(c, check.Matches, false, "Can't compile regex: error parsing regexp: missing closing ]: `[c$`", "abc", "a[c") 180 | } 181 | 182 | func (s *CheckersS) TestPanics(c *check.C) { 183 | testInfo(c, check.Panics, "Panics", []string{"function", "expected"}) 184 | 185 | // Some errors. 186 | testCheck(c, check.Panics, false, "Function has not panicked", func() bool { return false }, "BOOM") 187 | testCheck(c, check.Panics, false, "Function must take zero arguments", 1, "BOOM") 188 | 189 | // Plain strings. 190 | testCheck(c, check.Panics, true, "", func() { panic("BOOM") }, "BOOM") 191 | testCheck(c, check.Panics, false, "", func() { panic("KABOOM") }, "BOOM") 192 | testCheck(c, check.Panics, true, "", func() bool { panic("BOOM") }, "BOOM") 193 | 194 | // Error values. 195 | testCheck(c, check.Panics, true, "", func() { panic(errors.New("BOOM")) }, errors.New("BOOM")) 196 | testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM")) 197 | 198 | type deep struct{ i int } 199 | // Deep value 200 | testCheck(c, check.Panics, true, "", func() { panic(&deep{99}) }, &deep{99}) 201 | 202 | // Verify params/names mutation 203 | params, names := testCheck(c, check.Panics, false, "", func() { panic(errors.New("KABOOM")) }, errors.New("BOOM")) 204 | c.Assert(params[0], check.ErrorMatches, "KABOOM") 205 | c.Assert(names[0], check.Equals, "panic") 206 | 207 | // Verify a nil panic 208 | testCheck(c, check.Panics, true, "", func() { panic(nil) }, nil) 209 | testCheck(c, check.Panics, false, "", func() { panic(nil) }, "NOPE") 210 | } 211 | 212 | func (s *CheckersS) TestPanicMatches(c *check.C) { 213 | testInfo(c, check.PanicMatches, "PanicMatches", []string{"function", "expected"}) 214 | 215 | // Error matching. 216 | testCheck(c, check.PanicMatches, true, "", func() { panic(errors.New("BOOM")) }, "BO.M") 217 | testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BO.M") 218 | 219 | // Some errors. 220 | testCheck(c, check.PanicMatches, false, "Function has not panicked", func() bool { return false }, "BOOM") 221 | testCheck(c, check.PanicMatches, false, "Function must take zero arguments", 1, "BOOM") 222 | 223 | // Plain strings. 224 | testCheck(c, check.PanicMatches, true, "", func() { panic("BOOM") }, "BO.M") 225 | testCheck(c, check.PanicMatches, false, "", func() { panic("KABOOM") }, "BOOM") 226 | testCheck(c, check.PanicMatches, true, "", func() bool { panic("BOOM") }, "BO.M") 227 | 228 | // Verify params/names mutation 229 | params, names := testCheck(c, check.PanicMatches, false, "", func() { panic(errors.New("KABOOM")) }, "BOOM") 230 | c.Assert(params[0], check.Equals, "KABOOM") 231 | c.Assert(names[0], check.Equals, "panic") 232 | 233 | // Verify a nil panic 234 | testCheck(c, check.PanicMatches, false, "Panic value is not a string or an error", func() { panic(nil) }, "") 235 | } 236 | 237 | func (s *CheckersS) TestFitsTypeOf(c *check.C) { 238 | testInfo(c, check.FitsTypeOf, "FitsTypeOf", []string{"obtained", "sample"}) 239 | 240 | // Basic types 241 | testCheck(c, check.FitsTypeOf, true, "", 1, 0) 242 | testCheck(c, check.FitsTypeOf, false, "", 1, int64(0)) 243 | 244 | // Aliases 245 | testCheck(c, check.FitsTypeOf, false, "", 1, errors.New("")) 246 | testCheck(c, check.FitsTypeOf, false, "", "error", errors.New("")) 247 | testCheck(c, check.FitsTypeOf, true, "", errors.New("error"), errors.New("")) 248 | 249 | // Structures 250 | testCheck(c, check.FitsTypeOf, false, "", 1, simpleStruct{}) 251 | testCheck(c, check.FitsTypeOf, false, "", simpleStruct{42}, &simpleStruct{}) 252 | testCheck(c, check.FitsTypeOf, true, "", simpleStruct{42}, simpleStruct{}) 253 | testCheck(c, check.FitsTypeOf, true, "", &simpleStruct{42}, &simpleStruct{}) 254 | 255 | // Some bad values 256 | testCheck(c, check.FitsTypeOf, false, "Invalid sample value", 1, interface{}(nil)) 257 | testCheck(c, check.FitsTypeOf, false, "", interface{}(nil), 0) 258 | } 259 | 260 | func (s *CheckersS) TestImplements(c *check.C) { 261 | testInfo(c, check.Implements, "Implements", []string{"obtained", "ifaceptr"}) 262 | 263 | var e error 264 | var re runtime.Error 265 | testCheck(c, check.Implements, true, "", errors.New(""), &e) 266 | testCheck(c, check.Implements, false, "", errors.New(""), &re) 267 | 268 | // Some bad values 269 | testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, errors.New("")) 270 | testCheck(c, check.Implements, false, "ifaceptr should be a pointer to an interface variable", 0, interface{}(nil)) 271 | testCheck(c, check.Implements, false, "", interface{}(nil), &e) 272 | } 273 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/export_test.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import "io" 4 | 5 | func PrintLine(filename string, line int) (string, error) { 6 | return printLine(filename, line) 7 | } 8 | 9 | func Indent(s, with string) string { 10 | return indent(s, with) 11 | } 12 | 13 | func NewOutputWriter(writer io.Writer, stream, verbose bool) *outputWriter { 14 | return newOutputWriter(writer, stream, verbose) 15 | } 16 | 17 | func (c *C) FakeSkip(reason string) { 18 | c.reason = reason 19 | } 20 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/fixture_test.go: -------------------------------------------------------------------------------- 1 | // Tests for the behavior of the test fixture system. 2 | 3 | package check_test 4 | 5 | import ( 6 | . "gopkg.in/check.v1" 7 | ) 8 | 9 | // ----------------------------------------------------------------------- 10 | // Fixture test suite. 11 | 12 | type FixtureS struct{} 13 | 14 | var fixtureS = Suite(&FixtureS{}) 15 | 16 | func (s *FixtureS) TestCountSuite(c *C) { 17 | suitesRun += 1 18 | } 19 | 20 | // ----------------------------------------------------------------------- 21 | // Basic fixture ordering verification. 22 | 23 | func (s *FixtureS) TestOrder(c *C) { 24 | helper := FixtureHelper{} 25 | Run(&helper, nil) 26 | c.Check(helper.calls[0], Equals, "SetUpSuite") 27 | c.Check(helper.calls[1], Equals, "SetUpTest") 28 | c.Check(helper.calls[2], Equals, "Test1") 29 | c.Check(helper.calls[3], Equals, "TearDownTest") 30 | c.Check(helper.calls[4], Equals, "SetUpTest") 31 | c.Check(helper.calls[5], Equals, "Test2") 32 | c.Check(helper.calls[6], Equals, "TearDownTest") 33 | c.Check(helper.calls[7], Equals, "TearDownSuite") 34 | c.Check(len(helper.calls), Equals, 8) 35 | } 36 | 37 | // ----------------------------------------------------------------------- 38 | // Check the behavior when panics occur within tests and fixtures. 39 | 40 | func (s *FixtureS) TestPanicOnTest(c *C) { 41 | helper := FixtureHelper{panicOn: "Test1"} 42 | output := String{} 43 | Run(&helper, &RunConf{Output: &output}) 44 | c.Check(helper.calls[0], Equals, "SetUpSuite") 45 | c.Check(helper.calls[1], Equals, "SetUpTest") 46 | c.Check(helper.calls[2], Equals, "Test1") 47 | c.Check(helper.calls[3], Equals, "TearDownTest") 48 | c.Check(helper.calls[4], Equals, "SetUpTest") 49 | c.Check(helper.calls[5], Equals, "Test2") 50 | c.Check(helper.calls[6], Equals, "TearDownTest") 51 | c.Check(helper.calls[7], Equals, "TearDownSuite") 52 | c.Check(len(helper.calls), Equals, 8) 53 | 54 | expected := "^\n-+\n" + 55 | "PANIC: check_test\\.go:[0-9]+: FixtureHelper.Test1\n\n" + 56 | "\\.\\.\\. Panic: Test1 \\(PC=[xA-F0-9]+\\)\n\n" + 57 | ".+:[0-9]+\n" + 58 | " in (go)?panic\n" + 59 | ".*check_test.go:[0-9]+\n" + 60 | " in FixtureHelper.trace\n" + 61 | ".*check_test.go:[0-9]+\n" + 62 | " in FixtureHelper.Test1\n" + 63 | "(.|\n)*$" 64 | 65 | c.Check(output.value, Matches, expected) 66 | } 67 | 68 | func (s *FixtureS) TestPanicOnSetUpTest(c *C) { 69 | helper := FixtureHelper{panicOn: "SetUpTest"} 70 | output := String{} 71 | Run(&helper, &RunConf{Output: &output}) 72 | c.Check(helper.calls[0], Equals, "SetUpSuite") 73 | c.Check(helper.calls[1], Equals, "SetUpTest") 74 | c.Check(helper.calls[2], Equals, "TearDownTest") 75 | c.Check(helper.calls[3], Equals, "TearDownSuite") 76 | c.Check(len(helper.calls), Equals, 4) 77 | 78 | expected := "^\n-+\n" + 79 | "PANIC: check_test\\.go:[0-9]+: " + 80 | "FixtureHelper\\.SetUpTest\n\n" + 81 | "\\.\\.\\. Panic: SetUpTest \\(PC=[xA-F0-9]+\\)\n\n" + 82 | ".+:[0-9]+\n" + 83 | " in (go)?panic\n" + 84 | ".*check_test.go:[0-9]+\n" + 85 | " in FixtureHelper.trace\n" + 86 | ".*check_test.go:[0-9]+\n" + 87 | " in FixtureHelper.SetUpTest\n" + 88 | "(.|\n)*" + 89 | "\n-+\n" + 90 | "PANIC: check_test\\.go:[0-9]+: " + 91 | "FixtureHelper\\.Test1\n\n" + 92 | "\\.\\.\\. Panic: Fixture has panicked " + 93 | "\\(see related PANIC\\)\n$" 94 | 95 | c.Check(output.value, Matches, expected) 96 | } 97 | 98 | func (s *FixtureS) TestPanicOnTearDownTest(c *C) { 99 | helper := FixtureHelper{panicOn: "TearDownTest"} 100 | output := String{} 101 | Run(&helper, &RunConf{Output: &output}) 102 | c.Check(helper.calls[0], Equals, "SetUpSuite") 103 | c.Check(helper.calls[1], Equals, "SetUpTest") 104 | c.Check(helper.calls[2], Equals, "Test1") 105 | c.Check(helper.calls[3], Equals, "TearDownTest") 106 | c.Check(helper.calls[4], Equals, "TearDownSuite") 107 | c.Check(len(helper.calls), Equals, 5) 108 | 109 | expected := "^\n-+\n" + 110 | "PANIC: check_test\\.go:[0-9]+: " + 111 | "FixtureHelper.TearDownTest\n\n" + 112 | "\\.\\.\\. Panic: TearDownTest \\(PC=[xA-F0-9]+\\)\n\n" + 113 | ".+:[0-9]+\n" + 114 | " in (go)?panic\n" + 115 | ".*check_test.go:[0-9]+\n" + 116 | " in FixtureHelper.trace\n" + 117 | ".*check_test.go:[0-9]+\n" + 118 | " in FixtureHelper.TearDownTest\n" + 119 | "(.|\n)*" + 120 | "\n-+\n" + 121 | "PANIC: check_test\\.go:[0-9]+: " + 122 | "FixtureHelper\\.Test1\n\n" + 123 | "\\.\\.\\. Panic: Fixture has panicked " + 124 | "\\(see related PANIC\\)\n$" 125 | 126 | c.Check(output.value, Matches, expected) 127 | } 128 | 129 | func (s *FixtureS) TestPanicOnSetUpSuite(c *C) { 130 | helper := FixtureHelper{panicOn: "SetUpSuite"} 131 | output := String{} 132 | Run(&helper, &RunConf{Output: &output}) 133 | c.Check(helper.calls[0], Equals, "SetUpSuite") 134 | c.Check(helper.calls[1], Equals, "TearDownSuite") 135 | c.Check(len(helper.calls), Equals, 2) 136 | 137 | expected := "^\n-+\n" + 138 | "PANIC: check_test\\.go:[0-9]+: " + 139 | "FixtureHelper.SetUpSuite\n\n" + 140 | "\\.\\.\\. Panic: SetUpSuite \\(PC=[xA-F0-9]+\\)\n\n" + 141 | ".+:[0-9]+\n" + 142 | " in (go)?panic\n" + 143 | ".*check_test.go:[0-9]+\n" + 144 | " in FixtureHelper.trace\n" + 145 | ".*check_test.go:[0-9]+\n" + 146 | " in FixtureHelper.SetUpSuite\n" + 147 | "(.|\n)*$" 148 | 149 | c.Check(output.value, Matches, expected) 150 | } 151 | 152 | func (s *FixtureS) TestPanicOnTearDownSuite(c *C) { 153 | helper := FixtureHelper{panicOn: "TearDownSuite"} 154 | output := String{} 155 | Run(&helper, &RunConf{Output: &output}) 156 | c.Check(helper.calls[0], Equals, "SetUpSuite") 157 | c.Check(helper.calls[1], Equals, "SetUpTest") 158 | c.Check(helper.calls[2], Equals, "Test1") 159 | c.Check(helper.calls[3], Equals, "TearDownTest") 160 | c.Check(helper.calls[4], Equals, "SetUpTest") 161 | c.Check(helper.calls[5], Equals, "Test2") 162 | c.Check(helper.calls[6], Equals, "TearDownTest") 163 | c.Check(helper.calls[7], Equals, "TearDownSuite") 164 | c.Check(len(helper.calls), Equals, 8) 165 | 166 | expected := "^\n-+\n" + 167 | "PANIC: check_test\\.go:[0-9]+: " + 168 | "FixtureHelper.TearDownSuite\n\n" + 169 | "\\.\\.\\. Panic: TearDownSuite \\(PC=[xA-F0-9]+\\)\n\n" + 170 | ".+:[0-9]+\n" + 171 | " in (go)?panic\n" + 172 | ".*check_test.go:[0-9]+\n" + 173 | " in FixtureHelper.trace\n" + 174 | ".*check_test.go:[0-9]+\n" + 175 | " in FixtureHelper.TearDownSuite\n" + 176 | "(.|\n)*$" 177 | 178 | c.Check(output.value, Matches, expected) 179 | } 180 | 181 | // ----------------------------------------------------------------------- 182 | // A wrong argument on a test or fixture will produce a nice error. 183 | 184 | func (s *FixtureS) TestPanicOnWrongTestArg(c *C) { 185 | helper := WrongTestArgHelper{} 186 | output := String{} 187 | Run(&helper, &RunConf{Output: &output}) 188 | c.Check(helper.calls[0], Equals, "SetUpSuite") 189 | c.Check(helper.calls[1], Equals, "SetUpTest") 190 | c.Check(helper.calls[2], Equals, "TearDownTest") 191 | c.Check(helper.calls[3], Equals, "SetUpTest") 192 | c.Check(helper.calls[4], Equals, "Test2") 193 | c.Check(helper.calls[5], Equals, "TearDownTest") 194 | c.Check(helper.calls[6], Equals, "TearDownSuite") 195 | c.Check(len(helper.calls), Equals, 7) 196 | 197 | expected := "^\n-+\n" + 198 | "PANIC: fixture_test\\.go:[0-9]+: " + 199 | "WrongTestArgHelper\\.Test1\n\n" + 200 | "\\.\\.\\. Panic: WrongTestArgHelper\\.Test1 argument " + 201 | "should be \\*check\\.C\n" 202 | 203 | c.Check(output.value, Matches, expected) 204 | } 205 | 206 | func (s *FixtureS) TestPanicOnWrongSetUpTestArg(c *C) { 207 | helper := WrongSetUpTestArgHelper{} 208 | output := String{} 209 | Run(&helper, &RunConf{Output: &output}) 210 | c.Check(len(helper.calls), Equals, 0) 211 | 212 | expected := 213 | "^\n-+\n" + 214 | "PANIC: fixture_test\\.go:[0-9]+: " + 215 | "WrongSetUpTestArgHelper\\.SetUpTest\n\n" + 216 | "\\.\\.\\. Panic: WrongSetUpTestArgHelper\\.SetUpTest argument " + 217 | "should be \\*check\\.C\n" 218 | 219 | c.Check(output.value, Matches, expected) 220 | } 221 | 222 | func (s *FixtureS) TestPanicOnWrongSetUpSuiteArg(c *C) { 223 | helper := WrongSetUpSuiteArgHelper{} 224 | output := String{} 225 | Run(&helper, &RunConf{Output: &output}) 226 | c.Check(len(helper.calls), Equals, 0) 227 | 228 | expected := 229 | "^\n-+\n" + 230 | "PANIC: fixture_test\\.go:[0-9]+: " + 231 | "WrongSetUpSuiteArgHelper\\.SetUpSuite\n\n" + 232 | "\\.\\.\\. Panic: WrongSetUpSuiteArgHelper\\.SetUpSuite argument " + 233 | "should be \\*check\\.C\n" 234 | 235 | c.Check(output.value, Matches, expected) 236 | } 237 | 238 | // ----------------------------------------------------------------------- 239 | // Nice errors also when tests or fixture have wrong arg count. 240 | 241 | func (s *FixtureS) TestPanicOnWrongTestArgCount(c *C) { 242 | helper := WrongTestArgCountHelper{} 243 | output := String{} 244 | Run(&helper, &RunConf{Output: &output}) 245 | c.Check(helper.calls[0], Equals, "SetUpSuite") 246 | c.Check(helper.calls[1], Equals, "SetUpTest") 247 | c.Check(helper.calls[2], Equals, "TearDownTest") 248 | c.Check(helper.calls[3], Equals, "SetUpTest") 249 | c.Check(helper.calls[4], Equals, "Test2") 250 | c.Check(helper.calls[5], Equals, "TearDownTest") 251 | c.Check(helper.calls[6], Equals, "TearDownSuite") 252 | c.Check(len(helper.calls), Equals, 7) 253 | 254 | expected := "^\n-+\n" + 255 | "PANIC: fixture_test\\.go:[0-9]+: " + 256 | "WrongTestArgCountHelper\\.Test1\n\n" + 257 | "\\.\\.\\. Panic: WrongTestArgCountHelper\\.Test1 argument " + 258 | "should be \\*check\\.C\n" 259 | 260 | c.Check(output.value, Matches, expected) 261 | } 262 | 263 | func (s *FixtureS) TestPanicOnWrongSetUpTestArgCount(c *C) { 264 | helper := WrongSetUpTestArgCountHelper{} 265 | output := String{} 266 | Run(&helper, &RunConf{Output: &output}) 267 | c.Check(len(helper.calls), Equals, 0) 268 | 269 | expected := 270 | "^\n-+\n" + 271 | "PANIC: fixture_test\\.go:[0-9]+: " + 272 | "WrongSetUpTestArgCountHelper\\.SetUpTest\n\n" + 273 | "\\.\\.\\. Panic: WrongSetUpTestArgCountHelper\\.SetUpTest argument " + 274 | "should be \\*check\\.C\n" 275 | 276 | c.Check(output.value, Matches, expected) 277 | } 278 | 279 | func (s *FixtureS) TestPanicOnWrongSetUpSuiteArgCount(c *C) { 280 | helper := WrongSetUpSuiteArgCountHelper{} 281 | output := String{} 282 | Run(&helper, &RunConf{Output: &output}) 283 | c.Check(len(helper.calls), Equals, 0) 284 | 285 | expected := 286 | "^\n-+\n" + 287 | "PANIC: fixture_test\\.go:[0-9]+: " + 288 | "WrongSetUpSuiteArgCountHelper\\.SetUpSuite\n\n" + 289 | "\\.\\.\\. Panic: WrongSetUpSuiteArgCountHelper" + 290 | "\\.SetUpSuite argument should be \\*check\\.C\n" 291 | 292 | c.Check(output.value, Matches, expected) 293 | } 294 | 295 | // ----------------------------------------------------------------------- 296 | // Helper test suites with wrong function arguments. 297 | 298 | type WrongTestArgHelper struct { 299 | FixtureHelper 300 | } 301 | 302 | func (s *WrongTestArgHelper) Test1(t int) { 303 | } 304 | 305 | type WrongSetUpTestArgHelper struct { 306 | FixtureHelper 307 | } 308 | 309 | func (s *WrongSetUpTestArgHelper) SetUpTest(t int) { 310 | } 311 | 312 | type WrongSetUpSuiteArgHelper struct { 313 | FixtureHelper 314 | } 315 | 316 | func (s *WrongSetUpSuiteArgHelper) SetUpSuite(t int) { 317 | } 318 | 319 | type WrongTestArgCountHelper struct { 320 | FixtureHelper 321 | } 322 | 323 | func (s *WrongTestArgCountHelper) Test1(c *C, i int) { 324 | } 325 | 326 | type WrongSetUpTestArgCountHelper struct { 327 | FixtureHelper 328 | } 329 | 330 | func (s *WrongSetUpTestArgCountHelper) SetUpTest(c *C, i int) { 331 | } 332 | 333 | type WrongSetUpSuiteArgCountHelper struct { 334 | FixtureHelper 335 | } 336 | 337 | func (s *WrongSetUpSuiteArgCountHelper) SetUpSuite(c *C, i int) { 338 | } 339 | 340 | // ----------------------------------------------------------------------- 341 | // Ensure fixture doesn't run without tests. 342 | 343 | type NoTestsHelper struct { 344 | hasRun bool 345 | } 346 | 347 | func (s *NoTestsHelper) SetUpSuite(c *C) { 348 | s.hasRun = true 349 | } 350 | 351 | func (s *NoTestsHelper) TearDownSuite(c *C) { 352 | s.hasRun = true 353 | } 354 | 355 | func (s *FixtureS) TestFixtureDoesntRunWithoutTests(c *C) { 356 | helper := NoTestsHelper{} 357 | output := String{} 358 | Run(&helper, &RunConf{Output: &output}) 359 | c.Check(helper.hasRun, Equals, false) 360 | } 361 | 362 | // ----------------------------------------------------------------------- 363 | // Verify that checks and assertions work correctly inside the fixture. 364 | 365 | type FixtureCheckHelper struct { 366 | fail string 367 | completed bool 368 | } 369 | 370 | func (s *FixtureCheckHelper) SetUpSuite(c *C) { 371 | switch s.fail { 372 | case "SetUpSuiteAssert": 373 | c.Assert(false, Equals, true) 374 | case "SetUpSuiteCheck": 375 | c.Check(false, Equals, true) 376 | } 377 | s.completed = true 378 | } 379 | 380 | func (s *FixtureCheckHelper) SetUpTest(c *C) { 381 | switch s.fail { 382 | case "SetUpTestAssert": 383 | c.Assert(false, Equals, true) 384 | case "SetUpTestCheck": 385 | c.Check(false, Equals, true) 386 | } 387 | s.completed = true 388 | } 389 | 390 | func (s *FixtureCheckHelper) Test(c *C) { 391 | // Do nothing. 392 | } 393 | 394 | func (s *FixtureS) TestSetUpSuiteCheck(c *C) { 395 | helper := FixtureCheckHelper{fail: "SetUpSuiteCheck"} 396 | output := String{} 397 | Run(&helper, &RunConf{Output: &output}) 398 | c.Assert(output.value, Matches, 399 | "\n---+\n"+ 400 | "FAIL: fixture_test\\.go:[0-9]+: "+ 401 | "FixtureCheckHelper\\.SetUpSuite\n\n"+ 402 | "fixture_test\\.go:[0-9]+:\n"+ 403 | " c\\.Check\\(false, Equals, true\\)\n"+ 404 | "\\.+ obtained bool = false\n"+ 405 | "\\.+ expected bool = true\n\n") 406 | c.Assert(helper.completed, Equals, true) 407 | } 408 | 409 | func (s *FixtureS) TestSetUpSuiteAssert(c *C) { 410 | helper := FixtureCheckHelper{fail: "SetUpSuiteAssert"} 411 | output := String{} 412 | Run(&helper, &RunConf{Output: &output}) 413 | c.Assert(output.value, Matches, 414 | "\n---+\n"+ 415 | "FAIL: fixture_test\\.go:[0-9]+: "+ 416 | "FixtureCheckHelper\\.SetUpSuite\n\n"+ 417 | "fixture_test\\.go:[0-9]+:\n"+ 418 | " c\\.Assert\\(false, Equals, true\\)\n"+ 419 | "\\.+ obtained bool = false\n"+ 420 | "\\.+ expected bool = true\n\n") 421 | c.Assert(helper.completed, Equals, false) 422 | } 423 | 424 | // ----------------------------------------------------------------------- 425 | // Verify that logging within SetUpTest() persists within the test log itself. 426 | 427 | type FixtureLogHelper struct { 428 | c *C 429 | } 430 | 431 | func (s *FixtureLogHelper) SetUpTest(c *C) { 432 | s.c = c 433 | c.Log("1") 434 | } 435 | 436 | func (s *FixtureLogHelper) Test(c *C) { 437 | c.Log("2") 438 | s.c.Log("3") 439 | c.Log("4") 440 | c.Fail() 441 | } 442 | 443 | func (s *FixtureLogHelper) TearDownTest(c *C) { 444 | s.c.Log("5") 445 | } 446 | 447 | func (s *FixtureS) TestFixtureLogging(c *C) { 448 | helper := FixtureLogHelper{} 449 | output := String{} 450 | Run(&helper, &RunConf{Output: &output}) 451 | c.Assert(output.value, Matches, 452 | "\n---+\n"+ 453 | "FAIL: fixture_test\\.go:[0-9]+: "+ 454 | "FixtureLogHelper\\.Test\n\n"+ 455 | "1\n2\n3\n4\n5\n") 456 | } 457 | 458 | // ----------------------------------------------------------------------- 459 | // Skip() within fixture methods. 460 | 461 | func (s *FixtureS) TestSkipSuite(c *C) { 462 | helper := FixtureHelper{skip: true, skipOnN: 0} 463 | output := String{} 464 | result := Run(&helper, &RunConf{Output: &output}) 465 | c.Assert(output.value, Equals, "") 466 | c.Assert(helper.calls[0], Equals, "SetUpSuite") 467 | c.Assert(helper.calls[1], Equals, "TearDownSuite") 468 | c.Assert(len(helper.calls), Equals, 2) 469 | c.Assert(result.Skipped, Equals, 2) 470 | } 471 | 472 | func (s *FixtureS) TestSkipTest(c *C) { 473 | helper := FixtureHelper{skip: true, skipOnN: 1} 474 | output := String{} 475 | result := Run(&helper, &RunConf{Output: &output}) 476 | c.Assert(helper.calls[0], Equals, "SetUpSuite") 477 | c.Assert(helper.calls[1], Equals, "SetUpTest") 478 | c.Assert(helper.calls[2], Equals, "SetUpTest") 479 | c.Assert(helper.calls[3], Equals, "Test2") 480 | c.Assert(helper.calls[4], Equals, "TearDownTest") 481 | c.Assert(helper.calls[5], Equals, "TearDownSuite") 482 | c.Assert(len(helper.calls), Equals, 6) 483 | c.Assert(result.Skipped, Equals, 1) 484 | } 485 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/foundation_test.go: -------------------------------------------------------------------------------- 1 | // These tests check that the foundations of gocheck are working properly. 2 | // They already assume that fundamental failing is working already, though, 3 | // since this was tested in bootstrap_test.go. Even then, some care may 4 | // still have to be taken when using external functions, since they should 5 | // of course not rely on functionality tested here. 6 | 7 | package check_test 8 | 9 | import ( 10 | "fmt" 11 | "gopkg.in/check.v1" 12 | "log" 13 | "os" 14 | "regexp" 15 | "strings" 16 | ) 17 | 18 | // ----------------------------------------------------------------------- 19 | // Foundation test suite. 20 | 21 | type FoundationS struct{} 22 | 23 | var foundationS = check.Suite(&FoundationS{}) 24 | 25 | func (s *FoundationS) TestCountSuite(c *check.C) { 26 | suitesRun += 1 27 | } 28 | 29 | func (s *FoundationS) TestErrorf(c *check.C) { 30 | // Do not use checkState() here. It depends on Errorf() working. 31 | expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+ 32 | " c.Errorf(\"Error %%v!\", \"message\")\n"+ 33 | "... Error: Error message!\n\n", 34 | getMyLine()+1) 35 | c.Errorf("Error %v!", "message") 36 | failed := c.Failed() 37 | c.Succeed() 38 | if log := c.GetTestLog(); log != expectedLog { 39 | c.Logf("Errorf() logged %#v rather than %#v", log, expectedLog) 40 | c.Fail() 41 | } 42 | if !failed { 43 | c.Logf("Errorf() didn't put the test in a failed state") 44 | c.Fail() 45 | } 46 | } 47 | 48 | func (s *FoundationS) TestError(c *check.C) { 49 | expectedLog := fmt.Sprintf("foundation_test.go:%d:\n"+ 50 | " c\\.Error\\(\"Error \", \"message!\"\\)\n"+ 51 | "\\.\\.\\. Error: Error message!\n\n", 52 | getMyLine()+1) 53 | c.Error("Error ", "message!") 54 | checkState(c, nil, 55 | &expectedState{ 56 | name: "Error(`Error `, `message!`)", 57 | failed: true, 58 | log: expectedLog, 59 | }) 60 | } 61 | 62 | func (s *FoundationS) TestFailNow(c *check.C) { 63 | defer (func() { 64 | if !c.Failed() { 65 | c.Error("FailNow() didn't fail the test") 66 | } else { 67 | c.Succeed() 68 | if c.GetTestLog() != "" { 69 | c.Error("Something got logged:\n" + c.GetTestLog()) 70 | } 71 | } 72 | })() 73 | 74 | c.FailNow() 75 | c.Log("FailNow() didn't stop the test") 76 | } 77 | 78 | func (s *FoundationS) TestSucceedNow(c *check.C) { 79 | defer (func() { 80 | if c.Failed() { 81 | c.Error("SucceedNow() didn't succeed the test") 82 | } 83 | if c.GetTestLog() != "" { 84 | c.Error("Something got logged:\n" + c.GetTestLog()) 85 | } 86 | })() 87 | 88 | c.Fail() 89 | c.SucceedNow() 90 | c.Log("SucceedNow() didn't stop the test") 91 | } 92 | 93 | func (s *FoundationS) TestFailureHeader(c *check.C) { 94 | output := String{} 95 | failHelper := FailHelper{} 96 | check.Run(&failHelper, &check.RunConf{Output: &output}) 97 | header := fmt.Sprintf(""+ 98 | "\n-----------------------------------"+ 99 | "-----------------------------------\n"+ 100 | "FAIL: check_test.go:%d: FailHelper.TestLogAndFail\n", 101 | failHelper.testLine) 102 | if strings.Index(output.value, header) == -1 { 103 | c.Errorf(""+ 104 | "Failure didn't print a proper header.\n"+ 105 | "... Got:\n%s... Expected something with:\n%s", 106 | output.value, header) 107 | } 108 | } 109 | 110 | func (s *FoundationS) TestFatal(c *check.C) { 111 | var line int 112 | defer (func() { 113 | if !c.Failed() { 114 | c.Error("Fatal() didn't fail the test") 115 | } else { 116 | c.Succeed() 117 | expected := fmt.Sprintf("foundation_test.go:%d:\n"+ 118 | " c.Fatal(\"Die \", \"now!\")\n"+ 119 | "... Error: Die now!\n\n", 120 | line) 121 | if c.GetTestLog() != expected { 122 | c.Error("Incorrect log:", c.GetTestLog()) 123 | } 124 | } 125 | })() 126 | 127 | line = getMyLine() + 1 128 | c.Fatal("Die ", "now!") 129 | c.Log("Fatal() didn't stop the test") 130 | } 131 | 132 | func (s *FoundationS) TestFatalf(c *check.C) { 133 | var line int 134 | defer (func() { 135 | if !c.Failed() { 136 | c.Error("Fatalf() didn't fail the test") 137 | } else { 138 | c.Succeed() 139 | expected := fmt.Sprintf("foundation_test.go:%d:\n"+ 140 | " c.Fatalf(\"Die %%s!\", \"now\")\n"+ 141 | "... Error: Die now!\n\n", 142 | line) 143 | if c.GetTestLog() != expected { 144 | c.Error("Incorrect log:", c.GetTestLog()) 145 | } 146 | } 147 | })() 148 | 149 | line = getMyLine() + 1 150 | c.Fatalf("Die %s!", "now") 151 | c.Log("Fatalf() didn't stop the test") 152 | } 153 | 154 | func (s *FoundationS) TestCallerLoggingInsideTest(c *check.C) { 155 | log := fmt.Sprintf(""+ 156 | "foundation_test.go:%d:\n"+ 157 | " result := c.Check\\(10, check.Equals, 20\\)\n"+ 158 | "\\.\\.\\. obtained int = 10\n"+ 159 | "\\.\\.\\. expected int = 20\n\n", 160 | getMyLine()+1) 161 | result := c.Check(10, check.Equals, 20) 162 | checkState(c, result, 163 | &expectedState{ 164 | name: "Check(10, Equals, 20)", 165 | result: false, 166 | failed: true, 167 | log: log, 168 | }) 169 | } 170 | 171 | func (s *FoundationS) TestCallerLoggingInDifferentFile(c *check.C) { 172 | result, line := checkEqualWrapper(c, 10, 20) 173 | testLine := getMyLine() - 1 174 | log := fmt.Sprintf(""+ 175 | "foundation_test.go:%d:\n"+ 176 | " result, line := checkEqualWrapper\\(c, 10, 20\\)\n"+ 177 | "check_test.go:%d:\n"+ 178 | " return c.Check\\(obtained, check.Equals, expected\\), getMyLine\\(\\)\n"+ 179 | "\\.\\.\\. obtained int = 10\n"+ 180 | "\\.\\.\\. expected int = 20\n\n", 181 | testLine, line) 182 | checkState(c, result, 183 | &expectedState{ 184 | name: "Check(10, Equals, 20)", 185 | result: false, 186 | failed: true, 187 | log: log, 188 | }) 189 | } 190 | 191 | // ----------------------------------------------------------------------- 192 | // ExpectFailure() inverts the logic of failure. 193 | 194 | type ExpectFailureSucceedHelper struct{} 195 | 196 | func (s *ExpectFailureSucceedHelper) TestSucceed(c *check.C) { 197 | c.ExpectFailure("It booms!") 198 | c.Error("Boom!") 199 | } 200 | 201 | type ExpectFailureFailHelper struct{} 202 | 203 | func (s *ExpectFailureFailHelper) TestFail(c *check.C) { 204 | c.ExpectFailure("Bug #XYZ") 205 | } 206 | 207 | func (s *FoundationS) TestExpectFailureFail(c *check.C) { 208 | helper := ExpectFailureFailHelper{} 209 | output := String{} 210 | result := check.Run(&helper, &check.RunConf{Output: &output}) 211 | 212 | expected := "" + 213 | "^\n-+\n" + 214 | "FAIL: foundation_test\\.go:[0-9]+:" + 215 | " ExpectFailureFailHelper\\.TestFail\n\n" + 216 | "\\.\\.\\. Error: Test succeeded, but was expected to fail\n" + 217 | "\\.\\.\\. Reason: Bug #XYZ\n$" 218 | 219 | matched, err := regexp.MatchString(expected, output.value) 220 | if err != nil { 221 | c.Error("Bad expression: ", expected) 222 | } else if !matched { 223 | c.Error("ExpectFailure() didn't log properly:\n", output.value) 224 | } 225 | 226 | c.Assert(result.ExpectedFailures, check.Equals, 0) 227 | } 228 | 229 | func (s *FoundationS) TestExpectFailureSucceed(c *check.C) { 230 | helper := ExpectFailureSucceedHelper{} 231 | output := String{} 232 | result := check.Run(&helper, &check.RunConf{Output: &output}) 233 | 234 | c.Assert(output.value, check.Equals, "") 235 | c.Assert(result.ExpectedFailures, check.Equals, 1) 236 | } 237 | 238 | func (s *FoundationS) TestExpectFailureSucceedVerbose(c *check.C) { 239 | helper := ExpectFailureSucceedHelper{} 240 | output := String{} 241 | result := check.Run(&helper, &check.RunConf{Output: &output, Verbose: true}) 242 | 243 | expected := "" + 244 | "FAIL EXPECTED: foundation_test\\.go:[0-9]+:" + 245 | " ExpectFailureSucceedHelper\\.TestSucceed \\(It booms!\\)\t *[.0-9]+s\n" 246 | 247 | matched, err := regexp.MatchString(expected, output.value) 248 | if err != nil { 249 | c.Error("Bad expression: ", expected) 250 | } else if !matched { 251 | c.Error("ExpectFailure() didn't log properly:\n", output.value) 252 | } 253 | 254 | c.Assert(result.ExpectedFailures, check.Equals, 1) 255 | } 256 | 257 | // ----------------------------------------------------------------------- 258 | // Skip() allows stopping a test without positive/negative results. 259 | 260 | type SkipTestHelper struct{} 261 | 262 | func (s *SkipTestHelper) TestFail(c *check.C) { 263 | c.Skip("Wrong platform or whatever") 264 | c.Error("Boom!") 265 | } 266 | 267 | func (s *FoundationS) TestSkip(c *check.C) { 268 | helper := SkipTestHelper{} 269 | output := String{} 270 | check.Run(&helper, &check.RunConf{Output: &output}) 271 | 272 | if output.value != "" { 273 | c.Error("Skip() logged something:\n", output.value) 274 | } 275 | } 276 | 277 | func (s *FoundationS) TestSkipVerbose(c *check.C) { 278 | helper := SkipTestHelper{} 279 | output := String{} 280 | check.Run(&helper, &check.RunConf{Output: &output, Verbose: true}) 281 | 282 | expected := "SKIP: foundation_test\\.go:[0-9]+: SkipTestHelper\\.TestFail" + 283 | " \\(Wrong platform or whatever\\)" 284 | matched, err := regexp.MatchString(expected, output.value) 285 | if err != nil { 286 | c.Error("Bad expression: ", expected) 287 | } else if !matched { 288 | c.Error("Skip() didn't log properly:\n", output.value) 289 | } 290 | } 291 | 292 | // ----------------------------------------------------------------------- 293 | // Check minimum *log.Logger interface provided by *check.C. 294 | 295 | type minLogger interface { 296 | Output(calldepth int, s string) error 297 | } 298 | 299 | func (s *BootstrapS) TestMinLogger(c *check.C) { 300 | var logger minLogger 301 | logger = log.New(os.Stderr, "", 0) 302 | logger = c 303 | logger.Output(0, "Hello there") 304 | expected := `\[LOG\] [0-9]+:[0-9][0-9]\.[0-9][0-9][0-9] +Hello there\n` 305 | output := c.GetTestLog() 306 | c.Assert(output, check.Matches, expected) 307 | } 308 | 309 | // ----------------------------------------------------------------------- 310 | // Ensure that suites with embedded types are working fine, including the 311 | // the workaround for issue 906. 312 | 313 | type EmbeddedInternalS struct { 314 | called bool 315 | } 316 | 317 | type EmbeddedS struct { 318 | EmbeddedInternalS 319 | } 320 | 321 | var embeddedS = check.Suite(&EmbeddedS{}) 322 | 323 | func (s *EmbeddedS) TestCountSuite(c *check.C) { 324 | suitesRun += 1 325 | } 326 | 327 | func (s *EmbeddedInternalS) TestMethod(c *check.C) { 328 | c.Error("TestMethod() of the embedded type was called!?") 329 | } 330 | 331 | func (s *EmbeddedS) TestMethod(c *check.C) { 332 | // http://code.google.com/p/go/issues/detail?id=906 333 | c.Check(s.called, check.Equals, false) // Go issue 906 is affecting the runner? 334 | s.called = true 335 | } 336 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/helpers.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | "time" 7 | ) 8 | 9 | // TestName returns the current test name in the form "SuiteName.TestName" 10 | func (c *C) TestName() string { 11 | return c.testName 12 | } 13 | 14 | // ----------------------------------------------------------------------- 15 | // Basic succeeding/failing logic. 16 | 17 | // Failed returns whether the currently running test has already failed. 18 | func (c *C) Failed() bool { 19 | return c.status() == failedSt 20 | } 21 | 22 | // Fail marks the currently running test as failed. 23 | // 24 | // Something ought to have been previously logged so the developer can tell 25 | // what went wrong. The higher level helper functions will fail the test 26 | // and do the logging properly. 27 | func (c *C) Fail() { 28 | c.setStatus(failedSt) 29 | } 30 | 31 | // FailNow marks the currently running test as failed and stops running it. 32 | // Something ought to have been previously logged so the developer can tell 33 | // what went wrong. The higher level helper functions will fail the test 34 | // and do the logging properly. 35 | func (c *C) FailNow() { 36 | c.Fail() 37 | c.stopNow() 38 | } 39 | 40 | // Succeed marks the currently running test as succeeded, undoing any 41 | // previous failures. 42 | func (c *C) Succeed() { 43 | c.setStatus(succeededSt) 44 | } 45 | 46 | // SucceedNow marks the currently running test as succeeded, undoing any 47 | // previous failures, and stops running the test. 48 | func (c *C) SucceedNow() { 49 | c.Succeed() 50 | c.stopNow() 51 | } 52 | 53 | // ExpectFailure informs that the running test is knowingly broken for 54 | // the provided reason. If the test does not fail, an error will be reported 55 | // to raise attention to this fact. This method is useful to temporarily 56 | // disable tests which cover well known problems until a better time to 57 | // fix the problem is found, without forgetting about the fact that a 58 | // failure still exists. 59 | func (c *C) ExpectFailure(reason string) { 60 | if reason == "" { 61 | panic("Missing reason why the test is expected to fail") 62 | } 63 | c.mustFail = true 64 | c.reason = reason 65 | } 66 | 67 | // Skip skips the running test for the provided reason. If run from within 68 | // SetUpTest, the individual test being set up will be skipped, and if run 69 | // from within SetUpSuite, the whole suite is skipped. 70 | func (c *C) Skip(reason string) { 71 | if reason == "" { 72 | panic("Missing reason why the test is being skipped") 73 | } 74 | c.reason = reason 75 | c.setStatus(skippedSt) 76 | c.stopNow() 77 | } 78 | 79 | // ----------------------------------------------------------------------- 80 | // Basic logging. 81 | 82 | // GetTestLog returns the current test error output. 83 | func (c *C) GetTestLog() string { 84 | return c.logb.String() 85 | } 86 | 87 | // Log logs some information into the test error output. 88 | // The provided arguments are assembled together into a string with fmt.Sprint. 89 | func (c *C) Log(args ...interface{}) { 90 | c.log(args...) 91 | } 92 | 93 | // Log logs some information into the test error output. 94 | // The provided arguments are assembled together into a string with fmt.Sprintf. 95 | func (c *C) Logf(format string, args ...interface{}) { 96 | c.logf(format, args...) 97 | } 98 | 99 | // Output enables *C to be used as a logger in functions that require only 100 | // the minimum interface of *log.Logger. 101 | func (c *C) Output(calldepth int, s string) error { 102 | d := time.Now().Sub(c.startTime) 103 | msec := d / time.Millisecond 104 | sec := d / time.Second 105 | min := d / time.Minute 106 | 107 | c.Logf("[LOG] %d:%02d.%03d %s", min, sec%60, msec%1000, s) 108 | return nil 109 | } 110 | 111 | // Error logs an error into the test error output and marks the test as failed. 112 | // The provided arguments are assembled together into a string with fmt.Sprint. 113 | func (c *C) Error(args ...interface{}) { 114 | c.logCaller(1) 115 | c.logString(fmt.Sprint("Error: ", fmt.Sprint(args...))) 116 | c.logNewLine() 117 | c.Fail() 118 | } 119 | 120 | // Errorf logs an error into the test error output and marks the test as failed. 121 | // The provided arguments are assembled together into a string with fmt.Sprintf. 122 | func (c *C) Errorf(format string, args ...interface{}) { 123 | c.logCaller(1) 124 | c.logString(fmt.Sprintf("Error: "+format, args...)) 125 | c.logNewLine() 126 | c.Fail() 127 | } 128 | 129 | // Fatal logs an error into the test error output, marks the test as failed, and 130 | // stops the test execution. The provided arguments are assembled together into 131 | // a string with fmt.Sprint. 132 | func (c *C) Fatal(args ...interface{}) { 133 | c.logCaller(1) 134 | c.logString(fmt.Sprint("Error: ", fmt.Sprint(args...))) 135 | c.logNewLine() 136 | c.FailNow() 137 | } 138 | 139 | // Fatlaf logs an error into the test error output, marks the test as failed, and 140 | // stops the test execution. The provided arguments are assembled together into 141 | // a string with fmt.Sprintf. 142 | func (c *C) Fatalf(format string, args ...interface{}) { 143 | c.logCaller(1) 144 | c.logString(fmt.Sprint("Error: ", fmt.Sprintf(format, args...))) 145 | c.logNewLine() 146 | c.FailNow() 147 | } 148 | 149 | // ----------------------------------------------------------------------- 150 | // Generic checks and assertions based on checkers. 151 | 152 | // Check verifies if the first value matches the expected value according 153 | // to the provided checker. If they do not match, an error is logged, the 154 | // test is marked as failed, and the test execution continues. 155 | // 156 | // Some checkers may not need the expected argument (e.g. IsNil). 157 | // 158 | // Extra arguments provided to the function are logged next to the reported 159 | // problem when the matching fails. 160 | func (c *C) Check(obtained interface{}, checker Checker, args ...interface{}) bool { 161 | return c.internalCheck("Check", obtained, checker, args...) 162 | } 163 | 164 | // Assert ensures that the first value matches the expected value according 165 | // to the provided checker. If they do not match, an error is logged, the 166 | // test is marked as failed, and the test execution stops. 167 | // 168 | // Some checkers may not need the expected argument (e.g. IsNil). 169 | // 170 | // Extra arguments provided to the function are logged next to the reported 171 | // problem when the matching fails. 172 | func (c *C) Assert(obtained interface{}, checker Checker, args ...interface{}) { 173 | if !c.internalCheck("Assert", obtained, checker, args...) { 174 | c.stopNow() 175 | } 176 | } 177 | 178 | func (c *C) internalCheck(funcName string, obtained interface{}, checker Checker, args ...interface{}) bool { 179 | if checker == nil { 180 | c.logCaller(2) 181 | c.logString(fmt.Sprintf("%s(obtained, nil!?, ...):", funcName)) 182 | c.logString("Oops.. you've provided a nil checker!") 183 | c.logNewLine() 184 | c.Fail() 185 | return false 186 | } 187 | 188 | // If the last argument is a bug info, extract it out. 189 | var comment CommentInterface 190 | if len(args) > 0 { 191 | if c, ok := args[len(args)-1].(CommentInterface); ok { 192 | comment = c 193 | args = args[:len(args)-1] 194 | } 195 | } 196 | 197 | params := append([]interface{}{obtained}, args...) 198 | info := checker.Info() 199 | 200 | if len(params) != len(info.Params) { 201 | names := append([]string{info.Params[0], info.Name}, info.Params[1:]...) 202 | c.logCaller(2) 203 | c.logString(fmt.Sprintf("%s(%s):", funcName, strings.Join(names, ", "))) 204 | c.logString(fmt.Sprintf("Wrong number of parameters for %s: want %d, got %d", info.Name, len(names), len(params)+1)) 205 | c.logNewLine() 206 | c.Fail() 207 | return false 208 | } 209 | 210 | // Copy since it may be mutated by Check. 211 | names := append([]string{}, info.Params...) 212 | 213 | // Do the actual check. 214 | result, error := checker.Check(params, names) 215 | if !result || error != "" { 216 | c.logCaller(2) 217 | for i := 0; i != len(params); i++ { 218 | c.logValue(names[i], params[i]) 219 | } 220 | if comment != nil { 221 | c.logString(comment.CheckCommentString()) 222 | } 223 | if error != "" { 224 | c.logString(error) 225 | } 226 | c.logNewLine() 227 | c.Fail() 228 | return false 229 | } 230 | return true 231 | } 232 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/printer.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import ( 4 | "bytes" 5 | "go/ast" 6 | "go/parser" 7 | "go/printer" 8 | "go/token" 9 | "os" 10 | ) 11 | 12 | func indent(s, with string) (r string) { 13 | eol := true 14 | for i := 0; i != len(s); i++ { 15 | c := s[i] 16 | switch { 17 | case eol && c == '\n' || c == '\r': 18 | case c == '\n' || c == '\r': 19 | eol = true 20 | case eol: 21 | eol = false 22 | s = s[:i] + with + s[i:] 23 | i += len(with) 24 | } 25 | } 26 | return s 27 | } 28 | 29 | func printLine(filename string, line int) (string, error) { 30 | fset := token.NewFileSet() 31 | file, err := os.Open(filename) 32 | if err != nil { 33 | return "", err 34 | } 35 | fnode, err := parser.ParseFile(fset, filename, file, parser.ParseComments) 36 | if err != nil { 37 | return "", err 38 | } 39 | config := &printer.Config{Mode: printer.UseSpaces, Tabwidth: 4} 40 | lp := &linePrinter{fset: fset, fnode: fnode, line: line, config: config} 41 | ast.Walk(lp, fnode) 42 | result := lp.output.Bytes() 43 | // Comments leave \n at the end. 44 | n := len(result) 45 | for n > 0 && result[n-1] == '\n' { 46 | n-- 47 | } 48 | return string(result[:n]), nil 49 | } 50 | 51 | type linePrinter struct { 52 | config *printer.Config 53 | fset *token.FileSet 54 | fnode *ast.File 55 | line int 56 | output bytes.Buffer 57 | stmt ast.Stmt 58 | } 59 | 60 | func (lp *linePrinter) emit() bool { 61 | if lp.stmt != nil { 62 | lp.trim(lp.stmt) 63 | lp.printWithComments(lp.stmt) 64 | lp.stmt = nil 65 | return true 66 | } 67 | return false 68 | } 69 | 70 | func (lp *linePrinter) printWithComments(n ast.Node) { 71 | nfirst := lp.fset.Position(n.Pos()).Line 72 | nlast := lp.fset.Position(n.End()).Line 73 | for _, g := range lp.fnode.Comments { 74 | cfirst := lp.fset.Position(g.Pos()).Line 75 | clast := lp.fset.Position(g.End()).Line 76 | if clast == nfirst-1 && lp.fset.Position(n.Pos()).Column == lp.fset.Position(g.Pos()).Column { 77 | for _, c := range g.List { 78 | lp.output.WriteString(c.Text) 79 | lp.output.WriteByte('\n') 80 | } 81 | } 82 | if cfirst >= nfirst && cfirst <= nlast && n.End() <= g.List[0].Slash { 83 | // The printer will not include the comment if it starts past 84 | // the node itself. Trick it into printing by overlapping the 85 | // slash with the end of the statement. 86 | g.List[0].Slash = n.End() - 1 87 | } 88 | } 89 | node := &printer.CommentedNode{n, lp.fnode.Comments} 90 | lp.config.Fprint(&lp.output, lp.fset, node) 91 | } 92 | 93 | func (lp *linePrinter) Visit(n ast.Node) (w ast.Visitor) { 94 | if n == nil { 95 | if lp.output.Len() == 0 { 96 | lp.emit() 97 | } 98 | return nil 99 | } 100 | first := lp.fset.Position(n.Pos()).Line 101 | last := lp.fset.Position(n.End()).Line 102 | if first <= lp.line && last >= lp.line { 103 | // Print the innermost statement containing the line. 104 | if stmt, ok := n.(ast.Stmt); ok { 105 | if _, ok := n.(*ast.BlockStmt); !ok { 106 | lp.stmt = stmt 107 | } 108 | } 109 | if first == lp.line && lp.emit() { 110 | return nil 111 | } 112 | return lp 113 | } 114 | return nil 115 | } 116 | 117 | func (lp *linePrinter) trim(n ast.Node) bool { 118 | stmt, ok := n.(ast.Stmt) 119 | if !ok { 120 | return true 121 | } 122 | line := lp.fset.Position(n.Pos()).Line 123 | if line != lp.line { 124 | return false 125 | } 126 | switch stmt := stmt.(type) { 127 | case *ast.IfStmt: 128 | stmt.Body = lp.trimBlock(stmt.Body) 129 | case *ast.SwitchStmt: 130 | stmt.Body = lp.trimBlock(stmt.Body) 131 | case *ast.TypeSwitchStmt: 132 | stmt.Body = lp.trimBlock(stmt.Body) 133 | case *ast.CaseClause: 134 | stmt.Body = lp.trimList(stmt.Body) 135 | case *ast.CommClause: 136 | stmt.Body = lp.trimList(stmt.Body) 137 | case *ast.BlockStmt: 138 | stmt.List = lp.trimList(stmt.List) 139 | } 140 | return true 141 | } 142 | 143 | func (lp *linePrinter) trimBlock(stmt *ast.BlockStmt) *ast.BlockStmt { 144 | if !lp.trim(stmt) { 145 | return lp.emptyBlock(stmt) 146 | } 147 | stmt.Rbrace = stmt.Lbrace 148 | return stmt 149 | } 150 | 151 | func (lp *linePrinter) trimList(stmts []ast.Stmt) []ast.Stmt { 152 | for i := 0; i != len(stmts); i++ { 153 | if !lp.trim(stmts[i]) { 154 | stmts[i] = lp.emptyStmt(stmts[i]) 155 | break 156 | } 157 | } 158 | return stmts 159 | } 160 | 161 | func (lp *linePrinter) emptyStmt(n ast.Node) *ast.ExprStmt { 162 | return &ast.ExprStmt{&ast.Ellipsis{n.Pos(), nil}} 163 | } 164 | 165 | func (lp *linePrinter) emptyBlock(n ast.Node) *ast.BlockStmt { 166 | p := n.Pos() 167 | return &ast.BlockStmt{p, []ast.Stmt{lp.emptyStmt(n)}, p} 168 | } 169 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/printer_test.go: -------------------------------------------------------------------------------- 1 | package check_test 2 | 3 | import ( 4 | . "gopkg.in/check.v1" 5 | ) 6 | 7 | var _ = Suite(&PrinterS{}) 8 | 9 | type PrinterS struct{} 10 | 11 | func (s *PrinterS) TestCountSuite(c *C) { 12 | suitesRun += 1 13 | } 14 | 15 | var printTestFuncLine int 16 | 17 | func init() { 18 | printTestFuncLine = getMyLine() + 3 19 | } 20 | 21 | func printTestFunc() { 22 | println(1) // Comment1 23 | if 2 == 2 { // Comment2 24 | println(3) // Comment3 25 | } 26 | switch 5 { 27 | case 6: println(6) // Comment6 28 | println(7) 29 | } 30 | switch interface{}(9).(type) {// Comment9 31 | case int: println(10) 32 | println(11) 33 | } 34 | select { 35 | case <-(chan bool)(nil): println(14) 36 | println(15) 37 | default: println(16) 38 | println(17) 39 | } 40 | println(19, 41 | 20) 42 | _ = func() { println(21) 43 | println(22) 44 | } 45 | println(24, func() { 46 | println(25) 47 | }) 48 | // Leading comment 49 | // with multiple lines. 50 | println(29) // Comment29 51 | } 52 | 53 | var printLineTests = []struct { 54 | line int 55 | output string 56 | }{ 57 | {1, "println(1) // Comment1"}, 58 | {2, "if 2 == 2 { // Comment2\n ...\n}"}, 59 | {3, "println(3) // Comment3"}, 60 | {5, "switch 5 {\n...\n}"}, 61 | {6, "case 6:\n println(6) // Comment6\n ..."}, 62 | {7, "println(7)"}, 63 | {9, "switch interface{}(9).(type) { // Comment9\n...\n}"}, 64 | {10, "case int:\n println(10)\n ..."}, 65 | {14, "case <-(chan bool)(nil):\n println(14)\n ..."}, 66 | {15, "println(15)"}, 67 | {16, "default:\n println(16)\n ..."}, 68 | {17, "println(17)"}, 69 | {19, "println(19,\n 20)"}, 70 | {20, "println(19,\n 20)"}, 71 | {21, "_ = func() {\n println(21)\n println(22)\n}"}, 72 | {22, "println(22)"}, 73 | {24, "println(24, func() {\n println(25)\n})"}, 74 | {25, "println(25)"}, 75 | {26, "println(24, func() {\n println(25)\n})"}, 76 | {29, "// Leading comment\n// with multiple lines.\nprintln(29) // Comment29"}, 77 | } 78 | 79 | func (s *PrinterS) TestPrintLine(c *C) { 80 | for _, test := range printLineTests { 81 | output, err := PrintLine("printer_test.go", printTestFuncLine+test.line) 82 | c.Assert(err, IsNil) 83 | c.Assert(output, Equals, test.output) 84 | } 85 | } 86 | 87 | var indentTests = []struct { 88 | in, out string 89 | }{ 90 | {"", ""}, 91 | {"\n", "\n"}, 92 | {"a", ">>>a"}, 93 | {"a\n", ">>>a\n"}, 94 | {"a\nb", ">>>a\n>>>b"}, 95 | {" ", ">>> "}, 96 | } 97 | 98 | func (s *PrinterS) TestIndent(c *C) { 99 | for _, test := range indentTests { 100 | out := Indent(test.in, ">>>") 101 | c.Assert(out, Equals, test.out) 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/reporter.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "sync" 7 | ) 8 | 9 | // ----------------------------------------------------------------------- 10 | // Output writer manages atomic output writing according to settings. 11 | 12 | type outputWriter struct { 13 | m sync.Mutex 14 | writer io.Writer 15 | wroteCallProblemLast bool 16 | Stream bool 17 | Verbose bool 18 | } 19 | 20 | func newOutputWriter(writer io.Writer, stream, verbose bool) *outputWriter { 21 | return &outputWriter{writer: writer, Stream: stream, Verbose: verbose} 22 | } 23 | 24 | func (ow *outputWriter) Write(content []byte) (n int, err error) { 25 | ow.m.Lock() 26 | n, err = ow.writer.Write(content) 27 | ow.m.Unlock() 28 | return 29 | } 30 | 31 | func (ow *outputWriter) WriteCallStarted(label string, c *C) { 32 | if ow.Stream { 33 | header := renderCallHeader(label, c, "", "\n") 34 | ow.m.Lock() 35 | ow.writer.Write([]byte(header)) 36 | ow.m.Unlock() 37 | } 38 | } 39 | 40 | func (ow *outputWriter) WriteCallProblem(label string, c *C) { 41 | var prefix string 42 | if !ow.Stream { 43 | prefix = "\n-----------------------------------" + 44 | "-----------------------------------\n" 45 | } 46 | header := renderCallHeader(label, c, prefix, "\n\n") 47 | ow.m.Lock() 48 | ow.wroteCallProblemLast = true 49 | ow.writer.Write([]byte(header)) 50 | if !ow.Stream { 51 | c.logb.WriteTo(ow.writer) 52 | } 53 | ow.m.Unlock() 54 | } 55 | 56 | func (ow *outputWriter) WriteCallSuccess(label string, c *C) { 57 | if ow.Stream || (ow.Verbose && c.kind == testKd) { 58 | // TODO Use a buffer here. 59 | var suffix string 60 | if c.reason != "" { 61 | suffix = " (" + c.reason + ")" 62 | } 63 | if c.status() == succeededSt { 64 | suffix += "\t" + c.timerString() 65 | } 66 | suffix += "\n" 67 | if ow.Stream { 68 | suffix += "\n" 69 | } 70 | header := renderCallHeader(label, c, "", suffix) 71 | ow.m.Lock() 72 | // Resist temptation of using line as prefix above due to race. 73 | if !ow.Stream && ow.wroteCallProblemLast { 74 | header = "\n-----------------------------------" + 75 | "-----------------------------------\n" + 76 | header 77 | } 78 | ow.wroteCallProblemLast = false 79 | ow.writer.Write([]byte(header)) 80 | ow.m.Unlock() 81 | } 82 | } 83 | 84 | func renderCallHeader(label string, c *C, prefix, suffix string) string { 85 | pc := c.method.PC() 86 | return fmt.Sprintf("%s%s: %s: %s%s", prefix, label, niceFuncPath(pc), 87 | niceFuncName(pc), suffix) 88 | } 89 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/reporter_test.go: -------------------------------------------------------------------------------- 1 | package check_test 2 | 3 | import ( 4 | "fmt" 5 | "path/filepath" 6 | "runtime" 7 | 8 | . "gopkg.in/check.v1" 9 | ) 10 | 11 | var _ = Suite(&reporterS{}) 12 | 13 | type reporterS struct { 14 | testFile string 15 | } 16 | 17 | func (s *reporterS) SetUpSuite(c *C) { 18 | _, fileName, _, ok := runtime.Caller(0) 19 | c.Assert(ok, Equals, true) 20 | s.testFile = filepath.Base(fileName) 21 | } 22 | 23 | func (s *reporterS) TestWrite(c *C) { 24 | testString := "test string" 25 | output := String{} 26 | 27 | dummyStream := true 28 | dummyVerbose := true 29 | o := NewOutputWriter(&output, dummyStream, dummyVerbose) 30 | 31 | o.Write([]byte(testString)) 32 | c.Assert(output.value, Equals, testString) 33 | } 34 | 35 | func (s *reporterS) TestWriteCallStartedWithStreamFlag(c *C) { 36 | testLabel := "test started label" 37 | stream := true 38 | output := String{} 39 | 40 | dummyVerbose := true 41 | o := NewOutputWriter(&output, stream, dummyVerbose) 42 | 43 | o.WriteCallStarted(testLabel, c) 44 | expected := fmt.Sprintf("%s: %s:\\d+: %s\n", testLabel, s.testFile, c.TestName()) 45 | c.Assert(output.value, Matches, expected) 46 | } 47 | 48 | func (s *reporterS) TestWriteCallStartedWithoutStreamFlag(c *C) { 49 | stream := false 50 | output := String{} 51 | 52 | dummyLabel := "dummy" 53 | dummyVerbose := true 54 | o := NewOutputWriter(&output, stream, dummyVerbose) 55 | 56 | o.WriteCallStarted(dummyLabel, c) 57 | c.Assert(output.value, Equals, "") 58 | } 59 | 60 | func (s *reporterS) TestWriteCallProblemWithStreamFlag(c *C) { 61 | testLabel := "test problem label" 62 | stream := true 63 | output := String{} 64 | 65 | dummyVerbose := true 66 | o := NewOutputWriter(&output, stream, dummyVerbose) 67 | 68 | o.WriteCallProblem(testLabel, c) 69 | expected := fmt.Sprintf("%s: %s:\\d+: %s\n\n", testLabel, s.testFile, c.TestName()) 70 | c.Assert(output.value, Matches, expected) 71 | } 72 | 73 | func (s *reporterS) TestWriteCallProblemWithoutStreamFlag(c *C) { 74 | testLabel := "test problem label" 75 | stream := false 76 | output := String{} 77 | 78 | dummyVerbose := true 79 | o := NewOutputWriter(&output, stream, dummyVerbose) 80 | 81 | o.WriteCallProblem(testLabel, c) 82 | expected := fmt.Sprintf(""+ 83 | "\n"+ 84 | "----------------------------------------------------------------------\n"+ 85 | "%s: %s:\\d+: %s\n\n", testLabel, s.testFile, c.TestName()) 86 | c.Assert(output.value, Matches, expected) 87 | } 88 | 89 | func (s *reporterS) TestWriteCallProblemWithoutStreamFlagWithLog(c *C) { 90 | testLabel := "test problem label" 91 | testLog := "test log" 92 | stream := false 93 | output := String{} 94 | 95 | dummyVerbose := true 96 | o := NewOutputWriter(&output, stream, dummyVerbose) 97 | 98 | c.Log(testLog) 99 | o.WriteCallProblem(testLabel, c) 100 | expected := fmt.Sprintf(""+ 101 | "\n"+ 102 | "----------------------------------------------------------------------\n"+ 103 | "%s: %s:\\d+: %s\n\n%s\n", testLabel, s.testFile, c.TestName(), testLog) 104 | c.Assert(output.value, Matches, expected) 105 | } 106 | 107 | func (s *reporterS) TestWriteCallSuccessWithStreamFlag(c *C) { 108 | testLabel := "test success label" 109 | stream := true 110 | output := String{} 111 | 112 | dummyVerbose := true 113 | o := NewOutputWriter(&output, stream, dummyVerbose) 114 | 115 | o.WriteCallSuccess(testLabel, c) 116 | expected := fmt.Sprintf("%s: %s:\\d+: %s\t\\d\\.\\d+s\n\n", testLabel, s.testFile, c.TestName()) 117 | c.Assert(output.value, Matches, expected) 118 | } 119 | 120 | func (s *reporterS) TestWriteCallSuccessWithStreamFlagAndReason(c *C) { 121 | testLabel := "test success label" 122 | testReason := "test skip reason" 123 | stream := true 124 | output := String{} 125 | 126 | dummyVerbose := true 127 | o := NewOutputWriter(&output, stream, dummyVerbose) 128 | c.FakeSkip(testReason) 129 | 130 | o.WriteCallSuccess(testLabel, c) 131 | expected := fmt.Sprintf("%s: %s:\\d+: %s \\(%s\\)\t\\d\\.\\d+s\n\n", 132 | testLabel, s.testFile, c.TestName(), testReason) 133 | c.Assert(output.value, Matches, expected) 134 | } 135 | 136 | func (s *reporterS) TestWriteCallSuccessWithoutStreamFlagWithVerboseFlag(c *C) { 137 | testLabel := "test success label" 138 | stream := false 139 | verbose := true 140 | output := String{} 141 | 142 | o := NewOutputWriter(&output, stream, verbose) 143 | 144 | o.WriteCallSuccess(testLabel, c) 145 | expected := fmt.Sprintf("%s: %s:\\d+: %s\t\\d\\.\\d+s\n", testLabel, s.testFile, c.TestName()) 146 | c.Assert(output.value, Matches, expected) 147 | } 148 | 149 | func (s *reporterS) TestWriteCallSuccessWithoutStreamFlagWithoutVerboseFlag(c *C) { 150 | testLabel := "test success label" 151 | stream := false 152 | verbose := false 153 | output := String{} 154 | 155 | o := NewOutputWriter(&output, stream, verbose) 156 | 157 | o.WriteCallSuccess(testLabel, c) 158 | c.Assert(output.value, Equals, "") 159 | } 160 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/run.go: -------------------------------------------------------------------------------- 1 | package check 2 | 3 | import ( 4 | "bufio" 5 | "flag" 6 | "fmt" 7 | "os" 8 | "testing" 9 | "time" 10 | ) 11 | 12 | // ----------------------------------------------------------------------- 13 | // Test suite registry. 14 | 15 | var allSuites []interface{} 16 | 17 | // Suite registers the given value as a test suite to be run. Any methods 18 | // starting with the Test prefix in the given value will be considered as 19 | // a test method. 20 | func Suite(suite interface{}) interface{} { 21 | allSuites = append(allSuites, suite) 22 | return suite 23 | } 24 | 25 | // ----------------------------------------------------------------------- 26 | // Public running interface. 27 | 28 | var ( 29 | oldFilterFlag = flag.String("gocheck.f", "", "Regular expression selecting which tests and/or suites to run") 30 | oldVerboseFlag = flag.Bool("gocheck.v", false, "Verbose mode") 31 | oldStreamFlag = flag.Bool("gocheck.vv", false, "Super verbose mode (disables output caching)") 32 | oldBenchFlag = flag.Bool("gocheck.b", false, "Run benchmarks") 33 | oldBenchTime = flag.Duration("gocheck.btime", 1*time.Second, "approximate run time for each benchmark") 34 | oldListFlag = flag.Bool("gocheck.list", false, "List the names of all tests that will be run") 35 | oldWorkFlag = flag.Bool("gocheck.work", false, "Display and do not remove the test working directory") 36 | 37 | newFilterFlag = flag.String("check.f", "", "Regular expression selecting which tests and/or suites to run") 38 | newVerboseFlag = flag.Bool("check.v", false, "Verbose mode") 39 | newStreamFlag = flag.Bool("check.vv", false, "Super verbose mode (disables output caching)") 40 | newBenchFlag = flag.Bool("check.b", false, "Run benchmarks") 41 | newBenchTime = flag.Duration("check.btime", 1*time.Second, "approximate run time for each benchmark") 42 | newBenchMem = flag.Bool("check.bmem", false, "Report memory benchmarks") 43 | newListFlag = flag.Bool("check.list", false, "List the names of all tests that will be run") 44 | newWorkFlag = flag.Bool("check.work", false, "Display and do not remove the test working directory") 45 | ) 46 | 47 | // TestingT runs all test suites registered with the Suite function, 48 | // printing results to stdout, and reporting any failures back to 49 | // the "testing" package. 50 | func TestingT(testingT *testing.T) { 51 | benchTime := *newBenchTime 52 | if benchTime == 1*time.Second { 53 | benchTime = *oldBenchTime 54 | } 55 | conf := &RunConf{ 56 | Filter: *oldFilterFlag + *newFilterFlag, 57 | Verbose: *oldVerboseFlag || *newVerboseFlag, 58 | Stream: *oldStreamFlag || *newStreamFlag, 59 | Benchmark: *oldBenchFlag || *newBenchFlag, 60 | BenchmarkTime: benchTime, 61 | BenchmarkMem: *newBenchMem, 62 | KeepWorkDir: *oldWorkFlag || *newWorkFlag, 63 | } 64 | if *oldListFlag || *newListFlag { 65 | w := bufio.NewWriter(os.Stdout) 66 | for _, name := range ListAll(conf) { 67 | fmt.Fprintln(w, name) 68 | } 69 | w.Flush() 70 | return 71 | } 72 | result := RunAll(conf) 73 | println(result.String()) 74 | if !result.Passed() { 75 | testingT.Fail() 76 | } 77 | } 78 | 79 | // RunAll runs all test suites registered with the Suite function, using the 80 | // provided run configuration. 81 | func RunAll(runConf *RunConf) *Result { 82 | result := Result{} 83 | for _, suite := range allSuites { 84 | result.Add(Run(suite, runConf)) 85 | } 86 | return &result 87 | } 88 | 89 | // Run runs the provided test suite using the provided run configuration. 90 | func Run(suite interface{}, runConf *RunConf) *Result { 91 | runner := newSuiteRunner(suite, runConf) 92 | return runner.run() 93 | } 94 | 95 | // ListAll returns the names of all the test functions registered with the 96 | // Suite function that will be run with the provided run configuration. 97 | func ListAll(runConf *RunConf) []string { 98 | var names []string 99 | for _, suite := range allSuites { 100 | names = append(names, List(suite, runConf)...) 101 | } 102 | return names 103 | } 104 | 105 | // List returns the names of the test functions in the given 106 | // suite that will be run with the provided run configuration. 107 | func List(suite interface{}, runConf *RunConf) []string { 108 | var names []string 109 | runner := newSuiteRunner(suite, runConf) 110 | for _, t := range runner.tests { 111 | names = append(names, t.String()) 112 | } 113 | return names 114 | } 115 | 116 | // ----------------------------------------------------------------------- 117 | // Result methods. 118 | 119 | func (r *Result) Add(other *Result) { 120 | r.Succeeded += other.Succeeded 121 | r.Skipped += other.Skipped 122 | r.Failed += other.Failed 123 | r.Panicked += other.Panicked 124 | r.FixturePanicked += other.FixturePanicked 125 | r.ExpectedFailures += other.ExpectedFailures 126 | r.Missed += other.Missed 127 | if r.WorkDir != "" && other.WorkDir != "" { 128 | r.WorkDir += ":" + other.WorkDir 129 | } else if other.WorkDir != "" { 130 | r.WorkDir = other.WorkDir 131 | } 132 | } 133 | 134 | func (r *Result) Passed() bool { 135 | return (r.Failed == 0 && r.Panicked == 0 && 136 | r.FixturePanicked == 0 && r.Missed == 0 && 137 | r.RunError == nil) 138 | } 139 | 140 | func (r *Result) String() string { 141 | if r.RunError != nil { 142 | return "ERROR: " + r.RunError.Error() 143 | } 144 | 145 | var value string 146 | if r.Failed == 0 && r.Panicked == 0 && r.FixturePanicked == 0 && 147 | r.Missed == 0 { 148 | value = "OK: " 149 | } else { 150 | value = "OOPS: " 151 | } 152 | value += fmt.Sprintf("%d passed", r.Succeeded) 153 | if r.Skipped != 0 { 154 | value += fmt.Sprintf(", %d skipped", r.Skipped) 155 | } 156 | if r.ExpectedFailures != 0 { 157 | value += fmt.Sprintf(", %d expected failures", r.ExpectedFailures) 158 | } 159 | if r.Failed != 0 { 160 | value += fmt.Sprintf(", %d FAILED", r.Failed) 161 | } 162 | if r.Panicked != 0 { 163 | value += fmt.Sprintf(", %d PANICKED", r.Panicked) 164 | } 165 | if r.FixturePanicked != 0 { 166 | value += fmt.Sprintf(", %d FIXTURE-PANICKED", r.FixturePanicked) 167 | } 168 | if r.Missed != 0 { 169 | value += fmt.Sprintf(", %d MISSED", r.Missed) 170 | } 171 | if r.WorkDir != "" { 172 | value += "\nWORK=" + r.WorkDir 173 | } 174 | return value 175 | } 176 | -------------------------------------------------------------------------------- /vendor/gopkg.in/check.v1/run_test.go: -------------------------------------------------------------------------------- 1 | // These tests verify the test running logic. 2 | 3 | package check_test 4 | 5 | import ( 6 | "errors" 7 | . "gopkg.in/check.v1" 8 | "os" 9 | "sync" 10 | ) 11 | 12 | var runnerS = Suite(&RunS{}) 13 | 14 | type RunS struct{} 15 | 16 | func (s *RunS) TestCountSuite(c *C) { 17 | suitesRun += 1 18 | } 19 | 20 | // ----------------------------------------------------------------------- 21 | // Tests ensuring result counting works properly. 22 | 23 | func (s *RunS) TestSuccess(c *C) { 24 | output := String{} 25 | result := Run(&SuccessHelper{}, &RunConf{Output: &output}) 26 | c.Check(result.Succeeded, Equals, 1) 27 | c.Check(result.Failed, Equals, 0) 28 | c.Check(result.Skipped, Equals, 0) 29 | c.Check(result.Panicked, Equals, 0) 30 | c.Check(result.FixturePanicked, Equals, 0) 31 | c.Check(result.Missed, Equals, 0) 32 | c.Check(result.RunError, IsNil) 33 | } 34 | 35 | func (s *RunS) TestFailure(c *C) { 36 | output := String{} 37 | result := Run(&FailHelper{}, &RunConf{Output: &output}) 38 | c.Check(result.Succeeded, Equals, 0) 39 | c.Check(result.Failed, Equals, 1) 40 | c.Check(result.Skipped, Equals, 0) 41 | c.Check(result.Panicked, Equals, 0) 42 | c.Check(result.FixturePanicked, Equals, 0) 43 | c.Check(result.Missed, Equals, 0) 44 | c.Check(result.RunError, IsNil) 45 | } 46 | 47 | func (s *RunS) TestFixture(c *C) { 48 | output := String{} 49 | result := Run(&FixtureHelper{}, &RunConf{Output: &output}) 50 | c.Check(result.Succeeded, Equals, 2) 51 | c.Check(result.Failed, Equals, 0) 52 | c.Check(result.Skipped, Equals, 0) 53 | c.Check(result.Panicked, Equals, 0) 54 | c.Check(result.FixturePanicked, Equals, 0) 55 | c.Check(result.Missed, Equals, 0) 56 | c.Check(result.RunError, IsNil) 57 | } 58 | 59 | func (s *RunS) TestPanicOnTest(c *C) { 60 | output := String{} 61 | helper := &FixtureHelper{panicOn: "Test1"} 62 | result := Run(helper, &RunConf{Output: &output}) 63 | c.Check(result.Succeeded, Equals, 1) 64 | c.Check(result.Failed, Equals, 0) 65 | c.Check(result.Skipped, Equals, 0) 66 | c.Check(result.Panicked, Equals, 1) 67 | c.Check(result.FixturePanicked, Equals, 0) 68 | c.Check(result.Missed, Equals, 0) 69 | c.Check(result.RunError, IsNil) 70 | } 71 | 72 | func (s *RunS) TestPanicOnSetUpTest(c *C) { 73 | output := String{} 74 | helper := &FixtureHelper{panicOn: "SetUpTest"} 75 | result := Run(helper, &RunConf{Output: &output}) 76 | c.Check(result.Succeeded, Equals, 0) 77 | c.Check(result.Failed, Equals, 0) 78 | c.Check(result.Skipped, Equals, 0) 79 | c.Check(result.Panicked, Equals, 0) 80 | c.Check(result.FixturePanicked, Equals, 1) 81 | c.Check(result.Missed, Equals, 2) 82 | c.Check(result.RunError, IsNil) 83 | } 84 | 85 | func (s *RunS) TestPanicOnSetUpSuite(c *C) { 86 | output := String{} 87 | helper := &FixtureHelper{panicOn: "SetUpSuite"} 88 | result := Run(helper, &RunConf{Output: &output}) 89 | c.Check(result.Succeeded, Equals, 0) 90 | c.Check(result.Failed, Equals, 0) 91 | c.Check(result.Skipped, Equals, 0) 92 | c.Check(result.Panicked, Equals, 0) 93 | c.Check(result.FixturePanicked, Equals, 1) 94 | c.Check(result.Missed, Equals, 2) 95 | c.Check(result.RunError, IsNil) 96 | } 97 | 98 | // ----------------------------------------------------------------------- 99 | // Check result aggregation. 100 | 101 | func (s *RunS) TestAdd(c *C) { 102 | result := &Result{ 103 | Succeeded: 1, 104 | Skipped: 2, 105 | Failed: 3, 106 | Panicked: 4, 107 | FixturePanicked: 5, 108 | Missed: 6, 109 | ExpectedFailures: 7, 110 | } 111 | result.Add(&Result{ 112 | Succeeded: 10, 113 | Skipped: 20, 114 | Failed: 30, 115 | Panicked: 40, 116 | FixturePanicked: 50, 117 | Missed: 60, 118 | ExpectedFailures: 70, 119 | }) 120 | c.Check(result.Succeeded, Equals, 11) 121 | c.Check(result.Skipped, Equals, 22) 122 | c.Check(result.Failed, Equals, 33) 123 | c.Check(result.Panicked, Equals, 44) 124 | c.Check(result.FixturePanicked, Equals, 55) 125 | c.Check(result.Missed, Equals, 66) 126 | c.Check(result.ExpectedFailures, Equals, 77) 127 | c.Check(result.RunError, IsNil) 128 | } 129 | 130 | // ----------------------------------------------------------------------- 131 | // Check the Passed() method. 132 | 133 | func (s *RunS) TestPassed(c *C) { 134 | c.Assert((&Result{}).Passed(), Equals, true) 135 | c.Assert((&Result{Succeeded: 1}).Passed(), Equals, true) 136 | c.Assert((&Result{Skipped: 1}).Passed(), Equals, true) 137 | c.Assert((&Result{Failed: 1}).Passed(), Equals, false) 138 | c.Assert((&Result{Panicked: 1}).Passed(), Equals, false) 139 | c.Assert((&Result{FixturePanicked: 1}).Passed(), Equals, false) 140 | c.Assert((&Result{Missed: 1}).Passed(), Equals, false) 141 | c.Assert((&Result{RunError: errors.New("!")}).Passed(), Equals, false) 142 | } 143 | 144 | // ----------------------------------------------------------------------- 145 | // Check that result printing is working correctly. 146 | 147 | func (s *RunS) TestPrintSuccess(c *C) { 148 | result := &Result{Succeeded: 5} 149 | c.Check(result.String(), Equals, "OK: 5 passed") 150 | } 151 | 152 | func (s *RunS) TestPrintFailure(c *C) { 153 | result := &Result{Failed: 5} 154 | c.Check(result.String(), Equals, "OOPS: 0 passed, 5 FAILED") 155 | } 156 | 157 | func (s *RunS) TestPrintSkipped(c *C) { 158 | result := &Result{Skipped: 5} 159 | c.Check(result.String(), Equals, "OK: 0 passed, 5 skipped") 160 | } 161 | 162 | func (s *RunS) TestPrintExpectedFailures(c *C) { 163 | result := &Result{ExpectedFailures: 5} 164 | c.Check(result.String(), Equals, "OK: 0 passed, 5 expected failures") 165 | } 166 | 167 | func (s *RunS) TestPrintPanicked(c *C) { 168 | result := &Result{Panicked: 5} 169 | c.Check(result.String(), Equals, "OOPS: 0 passed, 5 PANICKED") 170 | } 171 | 172 | func (s *RunS) TestPrintFixturePanicked(c *C) { 173 | result := &Result{FixturePanicked: 5} 174 | c.Check(result.String(), Equals, "OOPS: 0 passed, 5 FIXTURE-PANICKED") 175 | } 176 | 177 | func (s *RunS) TestPrintMissed(c *C) { 178 | result := &Result{Missed: 5} 179 | c.Check(result.String(), Equals, "OOPS: 0 passed, 5 MISSED") 180 | } 181 | 182 | func (s *RunS) TestPrintAll(c *C) { 183 | result := &Result{Succeeded: 1, Skipped: 2, ExpectedFailures: 3, 184 | Panicked: 4, FixturePanicked: 5, Missed: 6} 185 | c.Check(result.String(), Equals, 186 | "OOPS: 1 passed, 2 skipped, 3 expected failures, 4 PANICKED, "+ 187 | "5 FIXTURE-PANICKED, 6 MISSED") 188 | } 189 | 190 | func (s *RunS) TestPrintRunError(c *C) { 191 | result := &Result{Succeeded: 1, Failed: 1, 192 | RunError: errors.New("Kaboom!")} 193 | c.Check(result.String(), Equals, "ERROR: Kaboom!") 194 | } 195 | 196 | // ----------------------------------------------------------------------- 197 | // Verify that the method pattern flag works correctly. 198 | 199 | func (s *RunS) TestFilterTestName(c *C) { 200 | helper := FixtureHelper{} 201 | output := String{} 202 | runConf := RunConf{Output: &output, Filter: "Test[91]"} 203 | Run(&helper, &runConf) 204 | c.Check(helper.calls[0], Equals, "SetUpSuite") 205 | c.Check(helper.calls[1], Equals, "SetUpTest") 206 | c.Check(helper.calls[2], Equals, "Test1") 207 | c.Check(helper.calls[3], Equals, "TearDownTest") 208 | c.Check(helper.calls[4], Equals, "TearDownSuite") 209 | c.Check(len(helper.calls), Equals, 5) 210 | } 211 | 212 | func (s *RunS) TestFilterTestNameWithAll(c *C) { 213 | helper := FixtureHelper{} 214 | output := String{} 215 | runConf := RunConf{Output: &output, Filter: ".*"} 216 | Run(&helper, &runConf) 217 | c.Check(helper.calls[0], Equals, "SetUpSuite") 218 | c.Check(helper.calls[1], Equals, "SetUpTest") 219 | c.Check(helper.calls[2], Equals, "Test1") 220 | c.Check(helper.calls[3], Equals, "TearDownTest") 221 | c.Check(helper.calls[4], Equals, "SetUpTest") 222 | c.Check(helper.calls[5], Equals, "Test2") 223 | c.Check(helper.calls[6], Equals, "TearDownTest") 224 | c.Check(helper.calls[7], Equals, "TearDownSuite") 225 | c.Check(len(helper.calls), Equals, 8) 226 | } 227 | 228 | func (s *RunS) TestFilterSuiteName(c *C) { 229 | helper := FixtureHelper{} 230 | output := String{} 231 | runConf := RunConf{Output: &output, Filter: "FixtureHelper"} 232 | Run(&helper, &runConf) 233 | c.Check(helper.calls[0], Equals, "SetUpSuite") 234 | c.Check(helper.calls[1], Equals, "SetUpTest") 235 | c.Check(helper.calls[2], Equals, "Test1") 236 | c.Check(helper.calls[3], Equals, "TearDownTest") 237 | c.Check(helper.calls[4], Equals, "SetUpTest") 238 | c.Check(helper.calls[5], Equals, "Test2") 239 | c.Check(helper.calls[6], Equals, "TearDownTest") 240 | c.Check(helper.calls[7], Equals, "TearDownSuite") 241 | c.Check(len(helper.calls), Equals, 8) 242 | } 243 | 244 | func (s *RunS) TestFilterSuiteNameAndTestName(c *C) { 245 | helper := FixtureHelper{} 246 | output := String{} 247 | runConf := RunConf{Output: &output, Filter: "FixtureHelper\\.Test2"} 248 | Run(&helper, &runConf) 249 | c.Check(helper.calls[0], Equals, "SetUpSuite") 250 | c.Check(helper.calls[1], Equals, "SetUpTest") 251 | c.Check(helper.calls[2], Equals, "Test2") 252 | c.Check(helper.calls[3], Equals, "TearDownTest") 253 | c.Check(helper.calls[4], Equals, "TearDownSuite") 254 | c.Check(len(helper.calls), Equals, 5) 255 | } 256 | 257 | func (s *RunS) TestFilterAllOut(c *C) { 258 | helper := FixtureHelper{} 259 | output := String{} 260 | runConf := RunConf{Output: &output, Filter: "NotFound"} 261 | Run(&helper, &runConf) 262 | c.Check(len(helper.calls), Equals, 0) 263 | } 264 | 265 | func (s *RunS) TestRequirePartialMatch(c *C) { 266 | helper := FixtureHelper{} 267 | output := String{} 268 | runConf := RunConf{Output: &output, Filter: "est"} 269 | Run(&helper, &runConf) 270 | c.Check(len(helper.calls), Equals, 8) 271 | } 272 | 273 | func (s *RunS) TestFilterError(c *C) { 274 | helper := FixtureHelper{} 275 | output := String{} 276 | runConf := RunConf{Output: &output, Filter: "]["} 277 | result := Run(&helper, &runConf) 278 | c.Check(result.String(), Equals, 279 | "ERROR: Bad filter expression: error parsing regexp: missing closing ]: `[`") 280 | c.Check(len(helper.calls), Equals, 0) 281 | } 282 | 283 | // ----------------------------------------------------------------------- 284 | // Verify that List works correctly. 285 | 286 | func (s *RunS) TestListFiltered(c *C) { 287 | names := List(&FixtureHelper{}, &RunConf{Filter: "1"}) 288 | c.Assert(names, DeepEquals, []string{ 289 | "FixtureHelper.Test1", 290 | }) 291 | } 292 | 293 | func (s *RunS) TestList(c *C) { 294 | names := List(&FixtureHelper{}, &RunConf{}) 295 | c.Assert(names, DeepEquals, []string{ 296 | "FixtureHelper.Test1", 297 | "FixtureHelper.Test2", 298 | }) 299 | } 300 | 301 | // ----------------------------------------------------------------------- 302 | // Verify that verbose mode prints tests which pass as well. 303 | 304 | func (s *RunS) TestVerboseMode(c *C) { 305 | helper := FixtureHelper{} 306 | output := String{} 307 | runConf := RunConf{Output: &output, Verbose: true} 308 | Run(&helper, &runConf) 309 | 310 | expected := "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test1\t *[.0-9]+s\n" + 311 | "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t *[.0-9]+s\n" 312 | 313 | c.Assert(output.value, Matches, expected) 314 | } 315 | 316 | func (s *RunS) TestVerboseModeWithFailBeforePass(c *C) { 317 | helper := FixtureHelper{panicOn: "Test1"} 318 | output := String{} 319 | runConf := RunConf{Output: &output, Verbose: true} 320 | Run(&helper, &runConf) 321 | 322 | expected := "(?s).*PANIC.*\n-+\n" + // Should have an extra line. 323 | "PASS: check_test\\.go:[0-9]+: FixtureHelper\\.Test2\t *[.0-9]+s\n" 324 | 325 | c.Assert(output.value, Matches, expected) 326 | } 327 | 328 | // ----------------------------------------------------------------------- 329 | // Verify the stream output mode. In this mode there's no output caching. 330 | 331 | type StreamHelper struct { 332 | l2 sync.Mutex 333 | l3 sync.Mutex 334 | } 335 | 336 | func (s *StreamHelper) SetUpSuite(c *C) { 337 | c.Log("0") 338 | } 339 | 340 | func (s *StreamHelper) Test1(c *C) { 341 | c.Log("1") 342 | s.l2.Lock() 343 | s.l3.Lock() 344 | go func() { 345 | s.l2.Lock() // Wait for "2". 346 | c.Log("3") 347 | s.l3.Unlock() 348 | }() 349 | } 350 | 351 | func (s *StreamHelper) Test2(c *C) { 352 | c.Log("2") 353 | s.l2.Unlock() 354 | s.l3.Lock() // Wait for "3". 355 | c.Fail() 356 | c.Log("4") 357 | } 358 | 359 | func (s *RunS) TestStreamMode(c *C) { 360 | helper := &StreamHelper{} 361 | output := String{} 362 | runConf := RunConf{Output: &output, Stream: true} 363 | Run(helper, &runConf) 364 | 365 | expected := "START: run_test\\.go:[0-9]+: StreamHelper\\.SetUpSuite\n0\n" + 366 | "PASS: run_test\\.go:[0-9]+: StreamHelper\\.SetUpSuite\t *[.0-9]+s\n\n" + 367 | "START: run_test\\.go:[0-9]+: StreamHelper\\.Test1\n1\n" + 368 | "PASS: run_test\\.go:[0-9]+: StreamHelper\\.Test1\t *[.0-9]+s\n\n" + 369 | "START: run_test\\.go:[0-9]+: StreamHelper\\.Test2\n2\n3\n4\n" + 370 | "FAIL: run_test\\.go:[0-9]+: StreamHelper\\.Test2\n\n" 371 | 372 | c.Assert(output.value, Matches, expected) 373 | } 374 | 375 | type StreamMissHelper struct{} 376 | 377 | func (s *StreamMissHelper) SetUpSuite(c *C) { 378 | c.Log("0") 379 | c.Fail() 380 | } 381 | 382 | func (s *StreamMissHelper) Test1(c *C) { 383 | c.Log("1") 384 | } 385 | 386 | func (s *RunS) TestStreamModeWithMiss(c *C) { 387 | helper := &StreamMissHelper{} 388 | output := String{} 389 | runConf := RunConf{Output: &output, Stream: true} 390 | Run(helper, &runConf) 391 | 392 | expected := "START: run_test\\.go:[0-9]+: StreamMissHelper\\.SetUpSuite\n0\n" + 393 | "FAIL: run_test\\.go:[0-9]+: StreamMissHelper\\.SetUpSuite\n\n" + 394 | "START: run_test\\.go:[0-9]+: StreamMissHelper\\.Test1\n" + 395 | "MISS: run_test\\.go:[0-9]+: StreamMissHelper\\.Test1\n\n" 396 | 397 | c.Assert(output.value, Matches, expected) 398 | } 399 | 400 | // ----------------------------------------------------------------------- 401 | // Verify that that the keep work dir request indeed does so. 402 | 403 | type WorkDirSuite struct {} 404 | 405 | func (s *WorkDirSuite) Test(c *C) { 406 | c.MkDir() 407 | } 408 | 409 | func (s *RunS) TestKeepWorkDir(c *C) { 410 | output := String{} 411 | runConf := RunConf{Output: &output, Verbose: true, KeepWorkDir: true} 412 | result := Run(&WorkDirSuite{}, &runConf) 413 | 414 | c.Assert(result.String(), Matches, ".*\nWORK=" + result.WorkDir) 415 | 416 | stat, err := os.Stat(result.WorkDir) 417 | c.Assert(err, IsNil) 418 | c.Assert(stat.IsDir(), Equals, true) 419 | } 420 | -------------------------------------------------------------------------------- /vendor/vgo.list: -------------------------------------------------------------------------------- 1 | MODULE VERSION 2 | github.com/LINBIT/linstor-flexvolume - 3 | github.com/LINBIT/golinstor v0.10.1 4 | github.com/satori/go.uuid v1.2.0 5 | gopkg.in/check.v1 v1.0.0-20161208181325-20d25e280405 6 | --------------------------------------------------------------------------------