commit
						46a0dbbd1a
					
				
							
								
								
									
										3
									
								
								.github/ISSUE_TEMPLATE
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.github/ISSUE_TEMPLATE
									
									
									
									
										vendored
									
									
								
							| @ -1,4 +1,4 @@ | |||||||
| **English Only**. Please use English because other could join the discussion if they got similar issue! | **English Only**. Please use English because others could join the discussion if they got similar issue! | ||||||
| 
 | 
 | ||||||
| Please answer these questions before submitting your issue. Thanks! | Please answer these questions before submitting your issue. Thanks! | ||||||
| 
 | 
 | ||||||
| @ -12,6 +12,7 @@ Please answer these questions before submitting your issue. Thanks! | |||||||
| If possible, provide a recipe for reproducing the error. | If possible, provide a recipe for reproducing the error. | ||||||
| A complete runnable program is good. | A complete runnable program is good. | ||||||
| 
 | 
 | ||||||
|  | If this is ORM issue, please provide the DB schemas. | ||||||
| 
 | 
 | ||||||
| 4. What did you expect to see? | 4. What did you expect to see? | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.github/dependabot.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | # To get started with Dependabot version updates, you'll need to specify which | ||||||
|  | # package ecosystems to update and where the package manifests are located. | ||||||
|  | # Please see the documentation for all configuration options: | ||||||
|  | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates | ||||||
|  | 
 | ||||||
|  | version: 2 | ||||||
|  | updates: | ||||||
|  |   - package-ecosystem: "gomod" | ||||||
|  |     directory: "/" | ||||||
|  |     schedule: | ||||||
|  |       interval: "daily" | ||||||
|  |     open-pull-requests-limit: 10 | ||||||
|  | 
 | ||||||
|  |   - package-ecosystem: "github-actions" | ||||||
|  |     directory: "/" | ||||||
|  |     schedule: | ||||||
|  |       interval: "daily" | ||||||
							
								
								
									
										43
									
								
								.github/linters/.golangci.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								.github/linters/.golangci.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | |||||||
|  | run: | ||||||
|  |   timeout: 5m | ||||||
|  |   skip-files: | ||||||
|  |     - generated.* | ||||||
|  | 
 | ||||||
|  | issues: | ||||||
|  |   new: true | ||||||
|  | 
 | ||||||
|  | linters: | ||||||
|  |   enable: | ||||||
|  |     - asciicheck | ||||||
|  |     - bodyclose | ||||||
|  |     - deadcode | ||||||
|  |     - depguard | ||||||
|  |     - gci | ||||||
|  |     - gocritic | ||||||
|  |     - gofmt | ||||||
|  |     - gofumpt | ||||||
|  |     - goimports | ||||||
|  |     - goprintffuncname | ||||||
|  |     - gosimple | ||||||
|  |     - govet | ||||||
|  |     - ineffassign | ||||||
|  |     - misspell | ||||||
|  |     - nilerr | ||||||
|  |     - rowserrcheck | ||||||
|  |     - staticcheck | ||||||
|  |     - structcheck | ||||||
|  |     - stylecheck | ||||||
|  |     - typecheck | ||||||
|  |     - unconvert | ||||||
|  |     - unused | ||||||
|  |     - unparam | ||||||
|  |     - varcheck | ||||||
|  |     - whitespace | ||||||
|  |   disable: | ||||||
|  |     - errcheck | ||||||
|  | 
 | ||||||
|  | linters-settings: | ||||||
|  |   gci: | ||||||
|  |     local-prefixes: github.com/beego/beego | ||||||
|  |   goimports: | ||||||
|  |     local-prefixes: github.com/beego/beego | ||||||
							
								
								
									
										34
									
								
								.github/workflows/changelog.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								.github/workflows/changelog.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | # This action requires that any PR targeting the master branch should touch at | ||||||
|  | # least one CHANGELOG file. If a CHANGELOG entry is not required, add the "Skip | ||||||
|  | # Changelog" label to disable this action. | ||||||
|  | 
 | ||||||
|  | name: changelog | ||||||
|  | 
 | ||||||
|  | on: | ||||||
|  |   pull_request: | ||||||
|  |     types: [opened, synchronize, reopened, labeled, unlabeled] | ||||||
|  |     branches: | ||||||
|  |       - develop | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   changelog: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     if: "!contains(github.event.pull_request.labels.*.name, 'Skip Changelog')" | ||||||
|  | 
 | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v2 | ||||||
|  | 
 | ||||||
|  |       - name: Check for CHANGELOG changes | ||||||
|  |         run: | | ||||||
|  |           # Only the latest commit of the feature branch is available | ||||||
|  |           # automatically. To diff with the base branch, we need to | ||||||
|  |           # fetch that too (and we only need its latest commit). | ||||||
|  |           git fetch origin ${{ github.base_ref }} --depth=1 | ||||||
|  |           if [[ $(git diff --name-only FETCH_HEAD | grep CHANGELOG) ]] | ||||||
|  |           then | ||||||
|  |             echo "A CHANGELOG was modified. Looks good!" | ||||||
|  |           else | ||||||
|  |             echo "No CHANGELOG was modified." | ||||||
|  |             echo "Please add a CHANGELOG entry, or add the \"Skip Changelog\" label if not required." | ||||||
|  |             false | ||||||
|  |           fi | ||||||
							
								
								
									
										26
									
								
								.github/workflows/golangci-lint.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								.github/workflows/golangci-lint.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | name: golangci-lint | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - master | ||||||
|  |     paths: | ||||||
|  |       - "**/*.go" | ||||||
|  |       - ".github/workflows/golangci-lint.yml" | ||||||
|  |   pull_request: | ||||||
|  |     types: [opened, synchronize, reopened] | ||||||
|  |     paths: | ||||||
|  |       - "**/*.go" | ||||||
|  |       - ".github/workflows/golangci-lint.yml" | ||||||
|  | jobs: | ||||||
|  |   lint: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - name: Checkout codebase | ||||||
|  |         uses: actions/checkout@v2 | ||||||
|  | 
 | ||||||
|  |       - name: golangci-lint | ||||||
|  |         uses: golangci/golangci-lint-action@v2 | ||||||
|  |         with: | ||||||
|  |           version: latest | ||||||
|  |           args: --config=.github/linters/.golangci.yml | ||||||
|  |           only-new-issues: true | ||||||
							
								
								
									
										19
									
								
								.github/workflows/need-feedback.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								.github/workflows/need-feedback.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | name: need-feeback-issues | ||||||
|  | 
 | ||||||
|  | on: | ||||||
|  |   schedule: | ||||||
|  |     - cron: "0 * * * *" # pick a cron here, this is every 1h | ||||||
|  |   workflow_dispatch: | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - uses: luanpotter/changes-requested@master | ||||||
|  |         with: | ||||||
|  |           github-token: ${{ secrets.GITHUB_TOKEN }} | ||||||
|  |           # these are optional, if you want to configure: | ||||||
|  |           days-until-close: 5 | ||||||
|  |           trigger-label: status/need-feedback | ||||||
|  |           closing-comment: This issue was closed by the need-feedback bot due to without feebacks. | ||||||
|  |           dry-run: false | ||||||
							
								
								
									
										19
									
								
								.github/workflows/need-translation.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								.github/workflows/need-translation.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | |||||||
|  | name: need-translation-issues | ||||||
|  | 
 | ||||||
|  | on: | ||||||
|  |   schedule: | ||||||
|  |     - cron: "0 * * * *" # pick a cron here, this is every 1h | ||||||
|  |   workflow_dispatch: | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - uses: luanpotter/changes-requested@master | ||||||
|  |         with: | ||||||
|  |           github-token: ${{ secrets.GITHUB_TOKEN }} | ||||||
|  |           # these are optional, if you want to configure: | ||||||
|  |           days-until-close: 5 | ||||||
|  |           trigger-label: status/need-translation | ||||||
|  |           closing-comment: This issue was closed by the need-translation bot. Please transalate your issue to English so it could help others. | ||||||
|  |           dry-run: false | ||||||
							
								
								
									
										2
									
								
								.github/workflows/stale.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/stale.yml
									
									
									
									
										vendored
									
									
								
							| @ -10,7 +10,7 @@ jobs: | |||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
| 
 | 
 | ||||||
|     steps: |     steps: | ||||||
|       - uses: actions/stale@v1 |       - uses: actions/stale@v4 | ||||||
|         with: |         with: | ||||||
|           repo-token: ${{ secrets.GITHUB_TOKEN }} |           repo-token: ${{ secrets.GITHUB_TOKEN }} | ||||||
|           stale-issue-message: 'This issue is inactive for a long time.' |           stale-issue-message: 'This issue is inactive for a long time.' | ||||||
|  | |||||||
							
								
								
									
										124
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								.github/workflows/test.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,124 @@ | |||||||
|  | name: Test | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - master | ||||||
|  |       - develop | ||||||
|  |     paths: | ||||||
|  |       - "**/*.go" | ||||||
|  |       - "go.mod" | ||||||
|  |       - "go.sum" | ||||||
|  |       - ".github/workflows/test.yml" | ||||||
|  |   pull_request: | ||||||
|  |     types: [opened, synchronize, reopened] | ||||||
|  |     branches: | ||||||
|  |       - master | ||||||
|  |       - develop | ||||||
|  |     paths: | ||||||
|  |       - "**/*.go" | ||||||
|  |       - "go.mod" | ||||||
|  |       - "go.sum" | ||||||
|  |       - ".github/workflows/test.yml" | ||||||
|  | 
 | ||||||
|  | jobs: | ||||||
|  |   test: | ||||||
|  |     strategy: | ||||||
|  |       fail-fast: false | ||||||
|  |       matrix: | ||||||
|  |         go-version: [1.14, 1.15, 1.16] | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     services: | ||||||
|  |       redis: | ||||||
|  |         image: redis:latest | ||||||
|  |         ports: | ||||||
|  |           - 6379:6379 | ||||||
|  |       memcached: | ||||||
|  |         image: memcached:latest | ||||||
|  |         ports: | ||||||
|  |           - 11211:11211 | ||||||
|  |       ssdb: | ||||||
|  |         image: wendal/ssdb:latest | ||||||
|  |         ports: | ||||||
|  |           - 8888:8888 | ||||||
|  |       postgres: | ||||||
|  |         image: postgres:latest | ||||||
|  |         env: | ||||||
|  |           POSTGRES_USER: postgres | ||||||
|  |           POSTGRES_PASSWORD: postgres | ||||||
|  |           POSTGRES_DB: orm_test | ||||||
|  |         ports: | ||||||
|  |           - 5432/tcp | ||||||
|  |         options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 | ||||||
|  | 
 | ||||||
|  |     steps: | ||||||
|  |       - name: Set up Go | ||||||
|  |         uses: actions/setup-go@v2 | ||||||
|  |         with: | ||||||
|  |           go-version: ${{ matrix.go-version }} | ||||||
|  | 
 | ||||||
|  |       - name: Checkout codebase | ||||||
|  |         uses: actions/checkout@v2 | ||||||
|  |         with: | ||||||
|  |           fetch-depth: 0 | ||||||
|  | 
 | ||||||
|  |       - name: Run etcd | ||||||
|  |         env: | ||||||
|  |           ETCD_VERSION: v3.4.16 | ||||||
|  |         run: | | ||||||
|  |           rm -rf /tmp/etcd-data.tmp | ||||||
|  |           mkdir -p /tmp/etcd-data.tmp | ||||||
|  |           docker rmi gcr.io/etcd-development/etcd:${ETCD_VERSION} || true && \ | ||||||
|  |           docker run -d \ | ||||||
|  |             -p 2379:2379 \ | ||||||
|  |             -p 2380:2380 \ | ||||||
|  |             --mount type=bind,source=/tmp/etcd-data.tmp,destination=/etcd-data \ | ||||||
|  |             --name etcd-gcr-${ETCD_VERSION} \ | ||||||
|  |             gcr.io/etcd-development/etcd:${ETCD_VERSION} \ | ||||||
|  |             /usr/local/bin/etcd \ | ||||||
|  |             --name s1 \ | ||||||
|  |             --data-dir /etcd-data \ | ||||||
|  |             --listen-client-urls http://0.0.0.0:2379 \ | ||||||
|  |             --advertise-client-urls http://0.0.0.0:2379 \ | ||||||
|  |             --listen-peer-urls http://0.0.0.0:2380 \ | ||||||
|  |             --initial-advertise-peer-urls http://0.0.0.0:2380 \ | ||||||
|  |             --initial-cluster s1=http://0.0.0.0:2380 \ | ||||||
|  |             --initial-cluster-token tkn \ | ||||||
|  |             --initial-cluster-state new | ||||||
|  |           docker exec etcd-gcr-${ETCD_VERSION} /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.float 1.23" | ||||||
|  |           docker exec etcd-gcr-${ETCD_VERSION} /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.bool true" | ||||||
|  |           docker exec etcd-gcr-${ETCD_VERSION} /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.int 11" | ||||||
|  |           docker exec etcd-gcr-${ETCD_VERSION} /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.string hello" | ||||||
|  |           docker exec etcd-gcr-${ETCD_VERSION} /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.serialize.name test" | ||||||
|  |           docker exec etcd-gcr-${ETCD_VERSION} /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put sub.sub.key1 sub.sub.key" | ||||||
|  | 
 | ||||||
|  |       - name: Run ORM tests on sqlite3 | ||||||
|  |         env: | ||||||
|  |           GOPATH: /home/runner/go | ||||||
|  |           ORM_DRIVER: sqlite3 | ||||||
|  |           ORM_SOURCE: /tmp/sqlite3/orm_test.db | ||||||
|  |         run: | | ||||||
|  |           mkdir -p /tmp/sqlite3 && touch /tmp/sqlite3/orm_test.db | ||||||
|  |           go test -coverprofile=coverage_sqlite3.txt -covermode=atomic $(go list ./... | grep client/orm) | ||||||
|  | 
 | ||||||
|  |       - name: Run ORM tests on postgres | ||||||
|  |         env: | ||||||
|  |           GOPATH: /home/runner/go | ||||||
|  |           ORM_DRIVER: postgres | ||||||
|  |           ORM_SOURCE: host=localhost port=${{ job.services.postgres.ports[5432] }} user=postgres password=postgres dbname=orm_test sslmode=disable | ||||||
|  |         run: | | ||||||
|  |           go test -coverprofile=coverage_postgres.txt -covermode=atomic $(go list ./... | grep client/orm) | ||||||
|  | 
 | ||||||
|  |       - name: Run tests on mysql | ||||||
|  |         env: | ||||||
|  |           GOPATH: /home/runner/go | ||||||
|  |           ORM_DRIVER: mysql | ||||||
|  |           ORM_SOURCE: root:root@/orm_test?charset=utf8 | ||||||
|  |         run: | | ||||||
|  |           sudo systemctl start mysql | ||||||
|  |           mysql -u root -proot -e 'create database orm_test;' | ||||||
|  |           go test -coverprofile=coverage.txt -covermode=atomic ./... | ||||||
|  | 
 | ||||||
|  |       - name: Upload codecov | ||||||
|  |         env: | ||||||
|  |           CODECOV_TOKEN: 4f4bc484-32a8-43b7-9f48-20966bd48ceb | ||||||
|  |         run: bash <(curl -s https://codecov.io/bash) | ||||||
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -10,3 +10,8 @@ _beeTmp2/ | |||||||
| pkg/_beeTmp/ | pkg/_beeTmp/ | ||||||
| pkg/_beeTmp2/ | pkg/_beeTmp2/ | ||||||
| test/tmp/ | test/tmp/ | ||||||
|  | core/config/env/pkg/ | ||||||
|  | 
 | ||||||
|  | my save path/ | ||||||
|  | 
 | ||||||
|  | profile.out | ||||||
|  | |||||||
							
								
								
									
										105
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										105
									
								
								.travis.yml
									
									
									
									
									
								
							| @ -1,105 +0,0 @@ | |||||||
| language: go |  | ||||||
| 
 |  | ||||||
| go: |  | ||||||
|   - "1.14.x" |  | ||||||
| services: |  | ||||||
|   - redis-server |  | ||||||
|   - mysql |  | ||||||
|   - postgresql |  | ||||||
|   - memcached |  | ||||||
|   - docker |  | ||||||
| env: |  | ||||||
|   global: |  | ||||||
|     - GO_REPO_FULLNAME="github.com/beego/beego/v2" |  | ||||||
|   matrix: |  | ||||||
|     - ORM_DRIVER=sqlite3   ORM_SOURCE=$TRAVIS_BUILD_DIR/orm_test.db |  | ||||||
|     - ORM_DRIVER=postgres ORM_SOURCE="user=postgres dbname=orm_test sslmode=disable" |  | ||||||
|     - ORM_DRIVER=mysql export ORM_SOURCE="root:@/orm_test?charset=utf8" |  | ||||||
| before_install: |  | ||||||
|   # link the local repo with ${GOPATH}/src/<namespace>/<repo> |  | ||||||
|   - GO_REPO_NAMESPACE=${GO_REPO_FULLNAME%/*} |  | ||||||
|   # relies on GOPATH to contain only one directory... |  | ||||||
|   - mkdir -p ${GOPATH}/src/${GO_REPO_NAMESPACE} |  | ||||||
|   - ln -sv ${TRAVIS_BUILD_DIR} ${GOPATH}/src/${GO_REPO_FULLNAME} |  | ||||||
|   - cd ${GOPATH}/src/${GO_REPO_FULLNAME} |  | ||||||
|   # get and build ssdb |  | ||||||
|   - git clone git://github.com/ideawu/ssdb.git |  | ||||||
|   - cd ssdb |  | ||||||
|   - make |  | ||||||
|   - cd .. |  | ||||||
|   #  - prepare etcd |  | ||||||
|   #  - prepare for etcd unit tests |  | ||||||
|   - rm -rf /tmp/etcd-data.tmp |  | ||||||
|   - mkdir -p /tmp/etcd-data.tmp |  | ||||||
|   - docker rmi gcr.io/etcd-development/etcd:v3.3.25 || true && |  | ||||||
|     docker run -d |  | ||||||
|     -p 2379:2379 |  | ||||||
|     -p 2380:2380 |  | ||||||
|     --mount type=bind,source=/tmp/etcd-data.tmp,destination=/etcd-data |  | ||||||
|     --name etcd-gcr-v3.3.25 |  | ||||||
|     gcr.io/etcd-development/etcd:v3.3.25 |  | ||||||
|     /usr/local/bin/etcd |  | ||||||
|     --name s1 |  | ||||||
|     --data-dir /etcd-data |  | ||||||
|     --listen-client-urls http://0.0.0.0:2379 |  | ||||||
|     --advertise-client-urls http://0.0.0.0:2379 |  | ||||||
|     --listen-peer-urls http://0.0.0.0:2380 |  | ||||||
|     --initial-advertise-peer-urls http://0.0.0.0:2380 |  | ||||||
|     --initial-cluster s1=http://0.0.0.0:2380 |  | ||||||
|     --initial-cluster-token tkn |  | ||||||
|     --initial-cluster-state new |  | ||||||
|   - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.float 1.23" |  | ||||||
|   - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.bool true" |  | ||||||
|   - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.int 11" |  | ||||||
|   - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.string hello" |  | ||||||
|   - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put current.serialize.name test" |  | ||||||
|   - docker exec etcd-gcr-v3.3.25 /bin/sh -c "ETCDCTL_API=3 /usr/local/bin/etcdctl put sub.sub.key1 sub.sub.key" |  | ||||||
| install: |  | ||||||
|   - go get github.com/lib/pq |  | ||||||
|   - go get github.com/go-sql-driver/mysql |  | ||||||
|   - go get github.com/mattn/go-sqlite3 |  | ||||||
|   - go get github.com/bradfitz/gomemcache/memcache |  | ||||||
|   - go get github.com/gomodule/redigo/redis |  | ||||||
|   - go get github.com/beego/x2j |  | ||||||
|   - go get github.com/couchbase/go-couchbase |  | ||||||
|   - go get github.com/beego/goyaml2 |  | ||||||
|   - go get gopkg.in/yaml.v2 |  | ||||||
|   - go get github.com/belogik/goes |  | ||||||
|   - go get github.com/ledisdb/ledisdb |  | ||||||
|   - go get github.com/ssdb/gossdb/ssdb |  | ||||||
|   - go get github.com/cloudflare/golz4 |  | ||||||
|   - go get github.com/gogo/protobuf/proto |  | ||||||
|   - go get github.com/Knetic/govaluate |  | ||||||
|   - go get github.com/casbin/casbin |  | ||||||
|   - go get github.com/elazarl/go-bindata-assetfs |  | ||||||
|   - go get github.com/OwnLocal/goes |  | ||||||
|   - go get github.com/shiena/ansicolor |  | ||||||
|   - go get -u honnef.co/go/tools/cmd/staticcheck |  | ||||||
|   - go get -u github.com/mdempsky/unconvert |  | ||||||
|   - go get -u github.com/gordonklaus/ineffassign |  | ||||||
|   - go get -u golang.org/x/lint/golint |  | ||||||
|   - go get -u github.com/go-redis/redis |  | ||||||
| before_script: |  | ||||||
| 
 |  | ||||||
|   #  - |  | ||||||
|   - psql --version |  | ||||||
|   #  - prepare for orm unit tests |  | ||||||
|   - sh -c "if [ '$ORM_DRIVER' = 'postgres' ]; then psql -c 'create database orm_test;' -U postgres; fi" |  | ||||||
|   - sh -c "if [ '$ORM_DRIVER' = 'mysql' ]; then mysql -u root -e 'create database orm_test;'; fi" |  | ||||||
|   - sh -c "if [ '$ORM_DRIVER' = 'sqlite' ]; then touch $TRAVIS_BUILD_DIR/orm_test.db; fi" |  | ||||||
|   - sh -c "go get github.com/golang/lint/golint; golint ./...;" |  | ||||||
|   - sh -c "go list ./... | grep -v vendor | xargs go vet -v" |  | ||||||
|   - mkdir -p res/var |  | ||||||
|   - ./ssdb/ssdb-server ./ssdb/ssdb.conf -d |  | ||||||
| after_script: |  | ||||||
|   - killall -w ssdb-server |  | ||||||
|   - rm -rf ./res/var/* |  | ||||||
| script: |  | ||||||
|   - go test ./... |  | ||||||
|   - staticcheck -show-ignored -checks "-ST1017,-U1000,-ST1005,-S1034,-S1012,-SA4006,-SA6005,-SA1019,-SA1024" ./ |  | ||||||
|   - unconvert $(go list ./... | grep -v /vendor/) |  | ||||||
|   - ineffassign . |  | ||||||
|   - find . ! \( -path './vendor' -prune \) -type f -name '*.go' -print0 | xargs -0 gofmt -l -s |  | ||||||
|   - golint ./... |  | ||||||
| addons: |  | ||||||
|   postgresql: "9.6" |  | ||||||
							
								
								
									
										83
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @ -1,4 +1,28 @@ | |||||||
| # developing | # developing | ||||||
|  | 
 | ||||||
|  | - Add a custom option for whether to escape HTML special characters when processing http request parameters. [4701](https://github.com/beego/beego/pull/4701) | ||||||
|  | - Always set the response status in the CustomAbort function. [4686](https://github.com/beego/beego/pull/4686) | ||||||
|  | - Add template functions eq,lt to support uint and int compare. [4607](https://github.com/beego/beego/pull/4607) | ||||||
|  | - Migrate tests to GitHub Actions. [4663](https://github.com/beego/beego/issues/4663) | ||||||
|  | - Add http client and option func. [4455](https://github.com/beego/beego/issues/4455) | ||||||
|  | - Add: Convenient way to generate mock object [4620](https://github.com/beego/beego/issues/4620) | ||||||
|  | - Infra: use dependabot to update dependencies. [4623](https://github.com/beego/beego/pull/4623) | ||||||
|  | - Lint: use golangci-lint. [4619](https://github.com/beego/beego/pull/4619) | ||||||
|  | - Chore: format code. [4615](https://github.com/beego/beego/pull/4615) | ||||||
|  | - Test on Go v1.15.x & v1.16.x. [4614](https://github.com/beego/beego/pull/4614) | ||||||
|  | - Env: non-empty GOBIN & GOPATH. [4613](https://github.com/beego/beego/pull/4613) | ||||||
|  | - Chore: update dependencies. [4611](https://github.com/beego/beego/pull/4611) | ||||||
|  | - Update orm_test.go/TestInsertOrUpdate with table-driven. [4609](https://github.com/beego/beego/pull/4609) | ||||||
|  | - Add: Resp() method for web.Controller. [4588](https://github.com/beego/beego/pull/4588) | ||||||
|  | - Web mock and test support. [4565](https://github.com/beego/beego/pull/4565) [4574](https://github.com/beego/beego/pull/4574) | ||||||
|  | - Error codes definition of cache module. [4493](https://github.com/beego/beego/pull/4493) | ||||||
|  | - Remove generateCommentRoute http hook. Using `bee generate routers` commands instead.[4486](https://github.com/beego/beego/pull/4486) [bee PR 762](https://github.com/beego/bee/pull/762) | ||||||
|  | - Fix: /abc.html/aaa match /abc/aaa. [4459](https://github.com/beego/beego/pull/4459) | ||||||
|  | - ORM mock. [4407](https://github.com/beego/beego/pull/4407) | ||||||
|  | - Add sonar check and ignore test. [4432](https://github.com/beego/beego/pull/4432) [4433](https://github.com/beego/beego/pull/4433) | ||||||
|  | - Update changlog.yml to check every PR to develop branch.[4427](https://github.com/beego/beego/pull/4427) | ||||||
|  | - Fix 4396: Add context.param module into adapter. [4398](https://github.com/beego/beego/pull/4398) | ||||||
|  | - Support `RollbackUnlessCommit` API. [4542](https://github.com/beego/beego/pull/4542) | ||||||
| - Fix 4503 and 4504: Add `when` to `Write([]byte)` method and add `prefix` to `writeMsg`. [4507](https://github.com/beego/beego/pull/4507) | - Fix 4503 and 4504: Add `when` to `Write([]byte)` method and add `prefix` to `writeMsg`. [4507](https://github.com/beego/beego/pull/4507) | ||||||
| - Fix 4480: log format incorrect. [4482](https://github.com/beego/beego/pull/4482) | - Fix 4480: log format incorrect. [4482](https://github.com/beego/beego/pull/4482) | ||||||
| - Remove `duration` from prometheus labels. [4391](https://github.com/beego/beego/pull/4391) | - Remove `duration` from prometheus labels. [4391](https://github.com/beego/beego/pull/4391) | ||||||
| @ -7,6 +31,65 @@ | |||||||
| - Fix 4727: CSS when request URI is invalid. [4729](https://github.com/beego/beego/pull/4729) | - Fix 4727: CSS when request URI is invalid. [4729](https://github.com/beego/beego/pull/4729) | ||||||
| - Using fixed name `commentRouter.go` as generated file name. [4385](https://github.com/beego/beego/pull/4385) | - Using fixed name `commentRouter.go` as generated file name. [4385](https://github.com/beego/beego/pull/4385) | ||||||
| - Fix 4383: ORM Adapter produces panic when using orm.RegisterModelWithPrefix. [4386](https://github.com/beego/beego/pull/4386) | - Fix 4383: ORM Adapter produces panic when using orm.RegisterModelWithPrefix. [4386](https://github.com/beego/beego/pull/4386) | ||||||
|  | - Support 4144: Add new api for order by for supporting multiple way to query [4294](https://github.com/beego/beego/pull/4294) | ||||||
|  | - Support session Filter chain. [4404](https://github.com/beego/beego/pull/4404) | ||||||
|  | - Feature issue #4402 finish router get example. [4416](https://github.com/beego/beego/pull/4416) | ||||||
|  | - Implement context.Context support and deprecate `QueryM2MWithCtx` and `QueryTableWithCtx` [4424](https://github.com/beego/beego/pull/4424) | ||||||
|  | - Finish timeout option for tasks #4441 [4441](https://github.com/beego/beego/pull/4441) | ||||||
|  | - Error Module brief design & using httplib module to validate this design. [4453](https://github.com/beego/beego/pull/4453) | ||||||
| - Fix 4444: panic when 404 not found. [4446](https://github.com/beego/beego/pull/4446) | - Fix 4444: panic when 404 not found. [4446](https://github.com/beego/beego/pull/4446) | ||||||
| - Fix 4435: fix panic when controller dir not found. [4452](https://github.com/beego/beego/pull/4452) | - Fix 4435: fix panic when controller dir not found. [4452](https://github.com/beego/beego/pull/4452) | ||||||
| - Hotfix:reflect.ValueOf(nil) in getFlatParams [4716](https://github.com/beego/beego/issues/4716) | - Hotfix:reflect.ValueOf(nil) in getFlatParams [4716](https://github.com/beego/beego/issues/4716) | ||||||
|  | - Fix 4456: Fix router method expression [4456](https://github.com/beego/beego/pull/4456) | ||||||
|  | - Remove some `go get` lines in `.travis.yml` file [4469](https://github.com/beego/beego/pull/4469) | ||||||
|  | - Fix 4451: support QueryExecutor interface. [4461](https://github.com/beego/beego/pull/4461) | ||||||
|  | - Add some testing scripts [4461](https://github.com/beego/beego/pull/4461) | ||||||
|  | - Refactor httplib: Move debug code to a filter [4440](https://github.com/beego/beego/issues/4440) | ||||||
|  | - fix: code quality issues [4513](https://github.com/beego/beego/pull/4513) | ||||||
|  | - Optimize maligned structs to reduce memory foot-print [4525](https://github.com/beego/beego/pull/4525) | ||||||
|  | - Feat: add token bucket ratelimit filter [4508](https://github.com/beego/beego/pull/4508) | ||||||
|  | - Improve: Avoid ignoring mistakes that need attention [4548](https://github.com/beego/beego/pull/4548) | ||||||
|  | - Integration: DeepSource [4560](https://github.com/beego/beego/pull/4560) | ||||||
|  | - Integration: Remove unnecessary function call [4577](https://github.com/beego/beego/pull/4577) | ||||||
|  | - Feature issue #4402 finish router get example. [4416](https://github.com/beego/beego/pull/4416) | ||||||
|  | - Proposal: Add Bind() method for `web.Controller` [4491](https://github.com/beego/beego/issues/4579) | ||||||
|  | - Optimize AddAutoPrefix: only register one router in case-insensitive mode. [4582](https://github.com/beego/beego/pull/4582) | ||||||
|  | - Init exceptMethod by using reflection. [4583](https://github.com/beego/beego/pull/4583) | ||||||
|  | - Deprecated BeeMap and replace all usage with `sync.map` [4616](https://github.com/beego/beego/pull/4616) | ||||||
|  | - TaskManager support graceful shutdown [4635](https://github.com/beego/beego/pull/4635) | ||||||
|  | - Add comments to `web.Config`, rename `RouterXXX` to `CtrlXXX`, define `HandleFunc` [4714](https://github.com/beego/beego/pull/4714) | ||||||
|  | - Refactor: Move `BindXXX` and `XXXResp` methods to `context.Context`. [4718](https://github.com/beego/beego/pull/4718) | ||||||
|  | - Fix 4728: Print wrong file name. [4737](https://github.com/beego/beego/pull/4737) | ||||||
|  | - fix bug:reflect.ValueOf(nil) in getFlatParams [4715](https://github.com/beego/beego/pull/4715) | ||||||
|  | - Fix 4736: set a fixed value "/" to the "Path" of "_xsrf" cookie. [4736](https://github.com/beego/beego/issues/4735) [4739](https://github.com/beego/beego/issues/4739) | ||||||
|  | - Fix 4734: do not reset id in Delete function. [4738](https://github.com/beego/beego/pull/4738) [4742](https://github.com/beego/beego/pull/4742) | ||||||
|  | - Fix 4699: Remove Remove goyaml2 dependency. [4755](https://github.com/beego/beego/pull/4755) | ||||||
|  | - Fix 4698: Prompt error when config format is incorrect. [4757](https://github.com/beego/beego/pull/4757) | ||||||
|  | - Fix 4674: Tx Orm missing debug log [4756](https://github.com/beego/beego/pull/4756) | ||||||
|  | - Fix 4759: fix numeric notation of permissions [4759](https://github.com/beego/beego/pull/4759) | ||||||
|  | ## Fix Sonar | ||||||
|  | 
 | ||||||
|  | - [4677](https://github.com/beego/beego/pull/4677) | ||||||
|  | - [4624](https://github.com/beego/beego/pull/4624) | ||||||
|  | - [4608](https://github.com/beego/beego/pull/4608) | ||||||
|  | - [4473](https://github.com/beego/beego/pull/4473) | ||||||
|  | - [4474](https://github.com/beego/beego/pull/4474) | ||||||
|  | - [4479](https://github.com/beego/beego/pull/4479) | ||||||
|  | - [4639](https://github.com/beego/beego/pull/4639) | ||||||
|  | - [4668](https://github.com/beego/beego/pull/4668) | ||||||
|  | 
 | ||||||
|  | ## Fix lint and format code | ||||||
|  | 
 | ||||||
|  | - [4644](https://github.com/beego/beego/pull/4644) | ||||||
|  | - [4645](https://github.com/beego/beego/pull/4645) | ||||||
|  | - [4646](https://github.com/beego/beego/pull/4646) | ||||||
|  | - [4647](https://github.com/beego/beego/pull/4647) | ||||||
|  | - [4648](https://github.com/beego/beego/pull/4648) | ||||||
|  | - [4649](https://github.com/beego/beego/pull/4649) | ||||||
|  | - [4651](https://github.com/beego/beego/pull/4651) | ||||||
|  | - [4652](https://github.com/beego/beego/pull/4652) | ||||||
|  | - [4653](https://github.com/beego/beego/pull/4653) | ||||||
|  | - [4654](https://github.com/beego/beego/pull/4654) | ||||||
|  | - [4655](https://github.com/beego/beego/pull/4655) | ||||||
|  | - [4656](https://github.com/beego/beego/pull/4656) | ||||||
|  | - [4660](https://github.com/beego/beego/pull/4660) | ||||||
|  | |||||||
| @ -36,7 +36,7 @@ We provide docker compose file to start all middlewares. | |||||||
| You can run: | You can run: | ||||||
| 
 | 
 | ||||||
| ```shell script | ```shell script | ||||||
| docker-compose -f scripts/test_docker_compose.yml up -d | docker-compose -f scripts/test_docker_compose.yaml up -d | ||||||
| ``` | ``` | ||||||
| 
 | 
 | ||||||
| Unit tests read addresses from environment, here is an example: | Unit tests read addresses from environment, here is an example: | ||||||
| @ -53,7 +53,7 @@ export SSDB_ADDR="192.168.0.105:8888" | |||||||
| 
 | 
 | ||||||
| ### Pull requests | ### Pull requests | ||||||
| 
 | 
 | ||||||
| First of all. beego follow the gitflow. So please send you pull request to **develop-2** branch. We will close the pull | First of all. beego follow the gitflow. So please send you pull request to **develop** branch. We will close the pull | ||||||
| request to master branch. | request to master branch. | ||||||
| 
 | 
 | ||||||
| We are always happy to receive pull requests, and do our best to review them as fast as possible. Not sure if that typo | We are always happy to receive pull requests, and do our best to review them as fast as possible. Not sure if that typo | ||||||
|  | |||||||
							
								
								
									
										5
									
								
								ERROR_SPECIFICATION.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								ERROR_SPECIFICATION.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,5 @@ | |||||||
|  | # Error Module | ||||||
|  | 
 | ||||||
|  | ## Module code | ||||||
|  | - httplib 1 | ||||||
|  | - cache 2 | ||||||
							
								
								
									
										19
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								README.md
									
									
									
									
									
								
							| @ -1,14 +1,12 @@ | |||||||
| # Beego [](https://travis-ci.org/astaxie/beego) [](http://godoc.org/github.com/beego/beego/v2) [](http://golangfoundation.org) [](https://goreportcard.com/report/github.com/beego/beego/v2) | # Beego [](https://github.com/beego/beego/actions/workflows/test.yml) [](https://goreportcard.com/report/github.com/beego/beego) [](https://pkg.go.dev/github.com/beego/beego/v2) | ||||||
| 
 | 
 | ||||||
| Beego is used for rapid development of enterprise application in Go, including RESTful APIs, web apps and backend | Beego is used for rapid development of enterprise application in Go, including RESTful APIs, web apps and backend services. | ||||||
| services. |  | ||||||
| 
 | 
 | ||||||
| It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific features such as interfaces and struct | It is inspired by Tornado, Sinatra and Flask. beego has some Go-specific features such as interfaces and struct embedding. | ||||||
| embedding. |  | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
| 
 | 
 | ||||||
| Beego is compos of four parts: | Beego is composed of four parts: | ||||||
| 
 | 
 | ||||||
| 1. Base modules: including log module, config module, governor module; | 1. Base modules: including log module, config module, governor module; | ||||||
| 2. Task: is used for running timed tasks or periodic tasks; | 2. Task: is used for running timed tasks or periodic tasks; | ||||||
| @ -19,7 +17,7 @@ Beego is compos of four parts: | |||||||
| 
 | 
 | ||||||
| ## Quick Start | ## Quick Start | ||||||
| 
 | 
 | ||||||
| [Officail website](http://beego.me) | [Official website](http://beego.me) | ||||||
| 
 | 
 | ||||||
| [Example](https://github.com/beego/beego-example) | [Example](https://github.com/beego/beego-example) | ||||||
| 
 | 
 | ||||||
| @ -40,7 +38,7 @@ Beego is compos of four parts: | |||||||
| 
 | 
 | ||||||
| #### Download and install | #### Download and install | ||||||
| 
 | 
 | ||||||
|     go get github.com/beego/beego/v2@v2.0.0 |     go get github.com/beego/beego/v2@latest | ||||||
| 
 | 
 | ||||||
| #### Create file `hello.go` | #### Create file `hello.go` | ||||||
| 
 | 
 | ||||||
| @ -90,12 +88,11 @@ Congratulations! You've just built your first **beego** app. | |||||||
| ## Community | ## Community | ||||||
| 
 | 
 | ||||||
| * [http://beego.me/community](http://beego.me/community) | * [http://beego.me/community](http://beego.me/community) | ||||||
| * Welcome to join us in Slack: [https://beego.slack.com](https://beego.slack.com), you can get invited | * Welcome to join us in Slack: [https://beego.slack.com invite](https://join.slack.com/t/beego/shared_invite/zt-fqlfjaxs-_CRmiITCSbEqQG9NeBqXKA), | ||||||
|   from [here](https://github.com/beego/beedoc/issues/232) |  | ||||||
| * QQ Group Group ID:523992905 | * QQ Group Group ID:523992905 | ||||||
| * [Contribution Guide](https://github.com/beego/beedoc/blob/master/en-US/intro/contributing.md). | * [Contribution Guide](https://github.com/beego/beedoc/blob/master/en-US/intro/contributing.md). | ||||||
| 
 | 
 | ||||||
| ## License | ## License | ||||||
| 
 | 
 | ||||||
| beego source code is licensed under the Apache Licence, Version 2.0 | beego source code is licensed under the Apache Licence, Version 2.0 | ||||||
| (http://www.apache.org/licenses/LICENSE-2.0.html). | ([https://www.apache.org/licenses/LICENSE-2.0.html](https://www.apache.org/licenses/LICENSE-2.0.html)). | ||||||
|  | |||||||
| @ -22,10 +22,8 @@ import ( | |||||||
| 	"github.com/beego/beego/v2/server/web/context" | 	"github.com/beego/beego/v2/server/web/context" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( |  | ||||||
| // BeeApp is an application instance | // BeeApp is an application instance | ||||||
| 	BeeApp *App | var BeeApp *App | ||||||
| ) |  | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
| 	// create beego application | 	// create beego application | ||||||
| @ -139,7 +137,7 @@ func RESTRouter(rootpath string, c ControllerInterface) *App { | |||||||
| 
 | 
 | ||||||
| // AutoRouter adds defined controller handler to BeeApp. | // AutoRouter adds defined controller handler to BeeApp. | ||||||
| // it's same to HttpServer.AutoRouter. | // it's same to HttpServer.AutoRouter. | ||||||
| // if beego.AddAuto(&MainContorlller{}) and MainController has methods List and Page, | // if beego.AddAuto(&MainController{}) and MainController has methods List and Page, | ||||||
| // visit the url /main/list to exec List function or /main/page to exec Page function. | // visit the url /main/list to exec List function or /main/page to exec Page function. | ||||||
| func AutoRouter(c ControllerInterface) *App { | func AutoRouter(c ControllerInterface) *App { | ||||||
| 	return (*App)(web.AutoRouter(c)) | 	return (*App)(web.AutoRouter(c)) | ||||||
| @ -147,7 +145,7 @@ func AutoRouter(c ControllerInterface) *App { | |||||||
| 
 | 
 | ||||||
| // AutoPrefix adds controller handler to BeeApp with prefix. | // AutoPrefix adds controller handler to BeeApp with prefix. | ||||||
| // it's same to HttpServer.AutoRouterWithPrefix. | // it's same to HttpServer.AutoRouterWithPrefix. | ||||||
| // if beego.AutoPrefix("/admin",&MainContorlller{}) and MainController has methods List and Page, | // if beego.AutoPrefix("/admin",&MainController{}) and MainController has methods List and Page, | ||||||
| // visit the url /admin/main/list to exec List function or /admin/main/page to exec Page function. | // visit the url /admin/main/list to exec List function or /admin/main/page to exec Page function. | ||||||
| func AutoPrefix(prefix string, c ControllerInterface) *App { | func AutoPrefix(prefix string, c ControllerInterface) *App { | ||||||
| 	return (*App)(web.AutoPrefix(prefix, c)) | 	return (*App)(web.AutoPrefix(prefix, c)) | ||||||
|  | |||||||
| @ -36,10 +36,6 @@ type M web.M | |||||||
| // Hook function to run | // Hook function to run | ||||||
| type hookfunc func() error | type hookfunc func() error | ||||||
| 
 | 
 | ||||||
| var ( |  | ||||||
| 	hooks = make([]hookfunc, 0) // hook function slice to store the hookfunc |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // AddAPPStartHook is used to register the hookfunc | // AddAPPStartHook is used to register the hookfunc | ||||||
| // The hookfuncs will run in beego.Run() | // The hookfuncs will run in beego.Run() | ||||||
| // such as initiating session , starting middleware , building template, starting admin control and so on. | // such as initiating session , starting middleware , building template, starting admin control and so on. | ||||||
|  | |||||||
							
								
								
									
										2
									
								
								adapter/cache/cache.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								adapter/cache/cache.go
									
									
									
									
										vendored
									
									
								
							| @ -16,7 +16,7 @@ | |||||||
| // Usage: | // Usage: | ||||||
| // | // | ||||||
| // import( | // import( | ||||||
| //   "github.com/beego/beego/v2/cache" | //   "github.com/beego/beego/v2/client/cache" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| // bm, err := cache.NewCache("memory", `{"interval":60}`) | // bm, err := cache.NewCache("memory", `{"interval":60}`) | ||||||
|  | |||||||
							
								
								
									
										187
									
								
								adapter/cache/cache_test.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										187
									
								
								adapter/cache/cache_test.go
									
									
									
									
										vendored
									
									
								
							| @ -19,12 +19,16 @@ import ( | |||||||
| 	"sync" | 	"sync" | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | const initError = "init err" | ||||||
|  | 
 | ||||||
| func TestCacheIncr(t *testing.T) { | func TestCacheIncr(t *testing.T) { | ||||||
| 	bm, err := NewCache("memory", `{"interval":20}`) | 	bm, err := NewCache("memory", `{"interval":20}`) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Error("init err") | 		t.Error(initError) | ||||||
| 	} | 	} | ||||||
| 	// timeoutDuration := 10 * time.Second | 	// timeoutDuration := 10 * time.Second | ||||||
| 
 | 
 | ||||||
| @ -45,147 +49,94 @@ func TestCacheIncr(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| func TestCache(t *testing.T) { | func TestCache(t *testing.T) { | ||||||
| 	bm, err := NewCache("memory", `{"interval":20}`) | 	bm, err := NewCache("memory", `{"interval":20}`) | ||||||
| 	if err != nil { |  | ||||||
| 		t.Error("init err") |  | ||||||
| 	} |  | ||||||
| 	timeoutDuration := 10 * time.Second |  | ||||||
| 	if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { |  | ||||||
| 		t.Error("set Error", err) |  | ||||||
| 	} |  | ||||||
| 	if !bm.IsExist("astaxie") { |  | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v := bm.Get("astaxie"); v.(int) != 1 { | 	assert.Nil(t, err) | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	time.Sleep(30 * time.Second) | 	timeoutDuration := 5 * time.Second | ||||||
|  | 	err = bm.Put("astaxie", 1, timeoutDuration) | ||||||
|  | 	assert.Nil(t, err) | ||||||
| 
 | 
 | ||||||
| 	if bm.IsExist("astaxie") { | 	assert.True(t, bm.IsExist("astaxie")) | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { | 	assert.Equal(t, 1, bm.Get("astaxie")) | ||||||
| 		t.Error("set Error", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if err = bm.Incr("astaxie"); err != nil { | 	time.Sleep(10 * time.Second) | ||||||
| 		t.Error("Incr Error", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v := bm.Get("astaxie"); v.(int) != 2 { | 	assert.False(t, bm.IsExist("astaxie")) | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if err = bm.Decr("astaxie"); err != nil { | 	err = bm.Put("astaxie", 1, timeoutDuration) | ||||||
| 		t.Error("Decr Error", err) | 	assert.Nil(t, err) | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v := bm.Get("astaxie"); v.(int) != 1 { | 	err = bm.Incr("astaxie") | ||||||
| 		t.Error("get err") | 	assert.Nil(t, err) | ||||||
| 	} |  | ||||||
| 	bm.Delete("astaxie") |  | ||||||
| 	if bm.IsExist("astaxie") { |  | ||||||
| 		t.Error("delete err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test GetMulti | 	assert.Equal(t, 2, bm.Get("astaxie")) | ||||||
| 	if err = bm.Put("astaxie", "author", timeoutDuration); err != nil { |  | ||||||
| 		t.Error("set Error", err) |  | ||||||
| 	} |  | ||||||
| 	if !bm.IsExist("astaxie") { |  | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 	if v := bm.Get("astaxie"); v.(string) != "author" { |  | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil { | 	assert.Nil(t, bm.Decr("astaxie")) | ||||||
| 		t.Error("set Error", err) | 
 | ||||||
| 	} | 	assert.Equal(t, 1, bm.Get("astaxie")) | ||||||
| 	if !bm.IsExist("astaxie1") { | 
 | ||||||
| 		t.Error("check err") | 	assert.Nil(t, bm.Delete("astaxie")) | ||||||
| 	} | 
 | ||||||
|  | 	assert.False(t, bm.IsExist("astaxie")) | ||||||
|  | 
 | ||||||
|  | 	assert.Nil(t, bm.Put("astaxie", "author", timeoutDuration)) | ||||||
|  | 
 | ||||||
|  | 	assert.True(t, bm.IsExist("astaxie")) | ||||||
|  | 
 | ||||||
|  | 	assert.Equal(t, "author", bm.Get("astaxie")) | ||||||
|  | 
 | ||||||
|  | 	assert.Nil(t, bm.Put("astaxie1", "author1", timeoutDuration)) | ||||||
|  | 
 | ||||||
|  | 	assert.True(t, bm.IsExist("astaxie1")) | ||||||
| 
 | 
 | ||||||
| 	vv := bm.GetMulti([]string{"astaxie", "astaxie1"}) | 	vv := bm.GetMulti([]string{"astaxie", "astaxie1"}) | ||||||
| 	if len(vv) != 2 { | 
 | ||||||
| 		t.Error("GetMulti ERROR") | 	assert.Equal(t, 2, len(vv)) | ||||||
| 	} | 
 | ||||||
| 	if vv[0].(string) != "author" { | 	assert.Equal(t, "author", vv[0]) | ||||||
| 		t.Error("GetMulti ERROR") | 
 | ||||||
| 	} | 	assert.Equal(t, "author1", vv[1]) | ||||||
| 	if vv[1].(string) != "author1" { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestFileCache(t *testing.T) { | func TestFileCache(t *testing.T) { | ||||||
| 	bm, err := NewCache("file", `{"CachePath":"cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"}`) | 	bm, err := NewCache("file", `{"CachePath":"cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"}`) | ||||||
| 	if err != nil { |  | ||||||
| 		t.Error("init err") |  | ||||||
| 	} |  | ||||||
| 	timeoutDuration := 10 * time.Second |  | ||||||
| 	if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { |  | ||||||
| 		t.Error("set Error", err) |  | ||||||
| 	} |  | ||||||
| 	if !bm.IsExist("astaxie") { |  | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v := bm.Get("astaxie"); v.(int) != 1 { | 	assert.Nil(t, err) | ||||||
| 		t.Error("get err") | 	timeoutDuration := 5 * time.Second | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if err = bm.Incr("astaxie"); err != nil { | 	assert.Nil(t, bm.Put("astaxie", 1, timeoutDuration)) | ||||||
| 		t.Error("Incr Error", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v := bm.Get("astaxie"); v.(int) != 2 { | 	assert.True(t, bm.IsExist("astaxie")) | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if err = bm.Decr("astaxie"); err != nil { | 	assert.Equal(t, 1, bm.Get("astaxie")) | ||||||
| 		t.Error("Decr Error", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v := bm.Get("astaxie"); v.(int) != 1 { | 	assert.Nil(t, bm.Incr("astaxie")) | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 	bm.Delete("astaxie") |  | ||||||
| 	if bm.IsExist("astaxie") { |  | ||||||
| 		t.Error("delete err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test string | 	assert.Equal(t, 2, bm.Get("astaxie")) | ||||||
| 	if err = bm.Put("astaxie", "author", timeoutDuration); err != nil { |  | ||||||
| 		t.Error("set Error", err) |  | ||||||
| 	} |  | ||||||
| 	if !bm.IsExist("astaxie") { |  | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 	if v := bm.Get("astaxie"); v.(string) != "author" { |  | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test GetMulti | 	assert.Nil(t, bm.Decr("astaxie")) | ||||||
| 	if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil { | 
 | ||||||
| 		t.Error("set Error", err) | 	assert.Equal(t, 1, bm.Get("astaxie")) | ||||||
| 	} | 	assert.Nil(t, bm.Delete("astaxie")) | ||||||
| 	if !bm.IsExist("astaxie1") { | 
 | ||||||
| 		t.Error("check err") | 	assert.False(t, bm.IsExist("astaxie")) | ||||||
| 	} | 
 | ||||||
|  | 	assert.Nil(t, bm.Put("astaxie", "author", timeoutDuration)) | ||||||
|  | 
 | ||||||
|  | 	assert.True(t, bm.IsExist("astaxie")) | ||||||
|  | 
 | ||||||
|  | 	assert.Equal(t, "author", bm.Get("astaxie")) | ||||||
|  | 
 | ||||||
|  | 	assert.Nil(t, bm.Put("astaxie1", "author1", timeoutDuration)) | ||||||
|  | 
 | ||||||
|  | 	assert.True(t, bm.IsExist("astaxie1")) | ||||||
| 
 | 
 | ||||||
| 	vv := bm.GetMulti([]string{"astaxie", "astaxie1"}) | 	vv := bm.GetMulti([]string{"astaxie", "astaxie1"}) | ||||||
| 	if len(vv) != 2 { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 	if vv[0].(string) != "author" { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 	if vv[1].(string) != "author1" { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	os.RemoveAll("cache") | 	assert.Equal(t, 2, len(vv)) | ||||||
|  | 
 | ||||||
|  | 	assert.Equal(t, "author", vv[0]) | ||||||
|  | 	assert.Equal(t, "author1", vv[1]) | ||||||
|  | 	assert.Nil(t, os.RemoveAll("cache")) | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										28
									
								
								adapter/cache/conv_test.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										28
									
								
								adapter/cache/conv_test.go
									
									
									
									
										vendored
									
									
								
							| @ -19,15 +19,15 @@ import ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestGetString(t *testing.T) { | func TestGetString(t *testing.T) { | ||||||
| 	var t1 = "test1" | 	t1 := "test1" | ||||||
| 	if "test1" != GetString(t1) { | 	if "test1" != GetString(t1) { | ||||||
| 		t.Error("get string from string error") | 		t.Error("get string from string error") | ||||||
| 	} | 	} | ||||||
| 	var t2 = []byte("test2") | 	t2 := []byte("test2") | ||||||
| 	if "test2" != GetString(t2) { | 	if "test2" != GetString(t2) { | ||||||
| 		t.Error("get string from byte array error") | 		t.Error("get string from byte array error") | ||||||
| 	} | 	} | ||||||
| 	var t3 = 1 | 	t3 := 1 | ||||||
| 	if "1" != GetString(t3) { | 	if "1" != GetString(t3) { | ||||||
| 		t.Error("get string from int error") | 		t.Error("get string from int error") | ||||||
| 	} | 	} | ||||||
| @ -35,7 +35,7 @@ func TestGetString(t *testing.T) { | |||||||
| 	if "1" != GetString(t4) { | 	if "1" != GetString(t4) { | ||||||
| 		t.Error("get string from int64 error") | 		t.Error("get string from int64 error") | ||||||
| 	} | 	} | ||||||
| 	var t5 = 1.1 | 	t5 := 1.1 | ||||||
| 	if "1.1" != GetString(t5) { | 	if "1.1" != GetString(t5) { | ||||||
| 		t.Error("get string from float64 error") | 		t.Error("get string from float64 error") | ||||||
| 	} | 	} | ||||||
| @ -46,7 +46,7 @@ func TestGetString(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestGetInt(t *testing.T) { | func TestGetInt(t *testing.T) { | ||||||
| 	var t1 = 1 | 	t1 := 1 | ||||||
| 	if 1 != GetInt(t1) { | 	if 1 != GetInt(t1) { | ||||||
| 		t.Error("get int from int error") | 		t.Error("get int from int error") | ||||||
| 	} | 	} | ||||||
| @ -58,7 +58,7 @@ func TestGetInt(t *testing.T) { | |||||||
| 	if 64 != GetInt(t3) { | 	if 64 != GetInt(t3) { | ||||||
| 		t.Error("get int from int64 error") | 		t.Error("get int from int64 error") | ||||||
| 	} | 	} | ||||||
| 	var t4 = "128" | 	t4 := "128" | ||||||
| 	if 128 != GetInt(t4) { | 	if 128 != GetInt(t4) { | ||||||
| 		t.Error("get int from num string error") | 		t.Error("get int from num string error") | ||||||
| 	} | 	} | ||||||
| @ -69,7 +69,7 @@ func TestGetInt(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| func TestGetInt64(t *testing.T) { | func TestGetInt64(t *testing.T) { | ||||||
| 	var i int64 = 1 | 	var i int64 = 1 | ||||||
| 	var t1 = 1 | 	t1 := 1 | ||||||
| 	if i != GetInt64(t1) { | 	if i != GetInt64(t1) { | ||||||
| 		t.Error("get int64 from int error") | 		t.Error("get int64 from int error") | ||||||
| 	} | 	} | ||||||
| @ -81,7 +81,7 @@ func TestGetInt64(t *testing.T) { | |||||||
| 	if i != GetInt64(t3) { | 	if i != GetInt64(t3) { | ||||||
| 		t.Error("get int64 from int64 error") | 		t.Error("get int64 from int64 error") | ||||||
| 	} | 	} | ||||||
| 	var t4 = "1" | 	t4 := "1" | ||||||
| 	if i != GetInt64(t4) { | 	if i != GetInt64(t4) { | ||||||
| 		t.Error("get int64 from num string error") | 		t.Error("get int64 from num string error") | ||||||
| 	} | 	} | ||||||
| @ -91,22 +91,22 @@ func TestGetInt64(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestGetFloat64(t *testing.T) { | func TestGetFloat64(t *testing.T) { | ||||||
| 	var f = 1.11 | 	f := 1.11 | ||||||
| 	var t1 float32 = 1.11 | 	var t1 float32 = 1.11 | ||||||
| 	if f != GetFloat64(t1) { | 	if f != GetFloat64(t1) { | ||||||
| 		t.Error("get float64 from float32 error") | 		t.Error("get float64 from float32 error") | ||||||
| 	} | 	} | ||||||
| 	var t2 = 1.11 | 	t2 := 1.11 | ||||||
| 	if f != GetFloat64(t2) { | 	if f != GetFloat64(t2) { | ||||||
| 		t.Error("get float64 from float64 error") | 		t.Error("get float64 from float64 error") | ||||||
| 	} | 	} | ||||||
| 	var t3 = "1.11" | 	t3 := "1.11" | ||||||
| 	if f != GetFloat64(t3) { | 	if f != GetFloat64(t3) { | ||||||
| 		t.Error("get float64 from string error") | 		t.Error("get float64 from string error") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var f2 float64 = 1 | 	var f2 float64 = 1 | ||||||
| 	var t4 = 1 | 	t4 := 1 | ||||||
| 	if f2 != GetFloat64(t4) { | 	if f2 != GetFloat64(t4) { | ||||||
| 		t.Error("get float64 from int error") | 		t.Error("get float64 from int error") | ||||||
| 	} | 	} | ||||||
| @ -117,11 +117,11 @@ func TestGetFloat64(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestGetBool(t *testing.T) { | func TestGetBool(t *testing.T) { | ||||||
| 	var t1 = true | 	t1 := true | ||||||
| 	if !GetBool(t1) { | 	if !GetBool(t1) { | ||||||
| 		t.Error("get bool from bool error") | 		t.Error("get bool from bool error") | ||||||
| 	} | 	} | ||||||
| 	var t2 = "true" | 	t2 := "true" | ||||||
| 	if !GetBool(t2) { | 	if !GetBool(t2) { | ||||||
| 		t.Error("get bool from string error") | 		t.Error("get bool from string error") | ||||||
| 	} | 	} | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								adapter/cache/memcache/memcache.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								adapter/cache/memcache/memcache.go
									
									
									
									
										vendored
									
									
								
							| @ -20,8 +20,8 @@ | |||||||
| // | // | ||||||
| // Usage: | // Usage: | ||||||
| // import( | // import( | ||||||
| //   _ "github.com/beego/beego/v2/cache/memcache" | //   _ "github.com/beego/beego/v2/client/cache/memcache" | ||||||
| //   "github.com/beego/beego/v2/cache" | //   "github.com/beego/beego/v2/client/cache" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| //  bm, err := cache.NewCache("memcache", `{"conn":"127.0.0.1:11211"}`) | //  bm, err := cache.NewCache("memcache", `{"conn":"127.0.0.1:11211"}`) | ||||||
|  | |||||||
							
								
								
									
										102
									
								
								adapter/cache/memcache/memcache_test.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										102
									
								
								adapter/cache/memcache/memcache_test.go
									
									
									
									
										vendored
									
									
								
							| @ -21,94 +21,64 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | 
 | ||||||
| 	"github.com/beego/beego/v2/adapter/cache" | 	"github.com/beego/beego/v2/adapter/cache" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestMemcacheCache(t *testing.T) { | func TestMemcacheCache(t *testing.T) { | ||||||
| 
 |  | ||||||
| 	addr := os.Getenv("MEMCACHE_ADDR") | 	addr := os.Getenv("MEMCACHE_ADDR") | ||||||
| 	if addr == "" { | 	if addr == "" { | ||||||
| 		addr = "127.0.0.1:11211" | 		addr = "127.0.0.1:11211" | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	bm, err := cache.NewCache("memcache", fmt.Sprintf(`{"conn": "%s"}`, addr)) | 	bm, err := cache.NewCache("memcache", fmt.Sprintf(`{"conn": "%s"}`, addr)) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Error("init err") | 	timeoutDuration := 5 * time.Second | ||||||
| 	} | 
 | ||||||
| 	timeoutDuration := 10 * time.Second | 	assert.Nil(t, bm.Put("astaxie", "1", timeoutDuration)) | ||||||
| 	if err = bm.Put("astaxie", "1", timeoutDuration); err != nil { | 
 | ||||||
| 		t.Error("set Error", err) | 	assert.True(t, bm.IsExist("astaxie")) | ||||||
| 	} |  | ||||||
| 	if !bm.IsExist("astaxie") { |  | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	time.Sleep(11 * time.Second) | 	time.Sleep(11 * time.Second) | ||||||
| 
 | 
 | ||||||
| 	if bm.IsExist("astaxie") { | 	assert.False(t, bm.IsExist("astaxie")) | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 	if err = bm.Put("astaxie", "1", timeoutDuration); err != nil { |  | ||||||
| 		t.Error("set Error", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v, err := strconv.Atoi(string(bm.Get("astaxie").([]byte))); err != nil || v != 1 { | 	assert.Nil(t, bm.Put("astaxie", "1", timeoutDuration)) | ||||||
| 		t.Error("get err") | 	v, err := strconv.Atoi(string(bm.Get("astaxie").([]byte))) | ||||||
| 	} | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, 1, v) | ||||||
| 
 | 
 | ||||||
| 	if err = bm.Incr("astaxie"); err != nil { | 	assert.Nil(t, bm.Incr("astaxie")) | ||||||
| 		t.Error("Incr Error", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v, err := strconv.Atoi(string(bm.Get("astaxie").([]byte))); err != nil || v != 2 { | 	v, err = strconv.Atoi(string(bm.Get("astaxie").([]byte))) | ||||||
| 		t.Error("get err") | 	assert.Nil(t, err) | ||||||
| 	} | 	assert.Equal(t, 2, v) | ||||||
| 
 | 
 | ||||||
| 	if err = bm.Decr("astaxie"); err != nil { | 	assert.Nil(t, bm.Decr("astaxie")) | ||||||
| 		t.Error("Decr Error", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v, err := strconv.Atoi(string(bm.Get("astaxie").([]byte))); err != nil || v != 1 { | 	v, err = strconv.Atoi(string(bm.Get("astaxie").([]byte))) | ||||||
| 		t.Error("get err") | 	assert.Nil(t, err) | ||||||
| 	} | 	assert.Equal(t, 1, v) | ||||||
| 	bm.Delete("astaxie") |  | ||||||
| 	if bm.IsExist("astaxie") { |  | ||||||
| 		t.Error("delete err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test string | 	assert.Nil(t, bm.Delete("astaxie")) | ||||||
| 	if err = bm.Put("astaxie", "author", timeoutDuration); err != nil { |  | ||||||
| 		t.Error("set Error", err) |  | ||||||
| 	} |  | ||||||
| 	if !bm.IsExist("astaxie") { |  | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v := bm.Get("astaxie").([]byte); string(v) != "author" { | 	assert.False(t, bm.IsExist("astaxie")) | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test GetMulti | 	assert.Nil(t, bm.Put("astaxie", "author", timeoutDuration)) | ||||||
| 	if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil { | 
 | ||||||
| 		t.Error("set Error", err) | 	assert.True(t, bm.IsExist("astaxie")) | ||||||
| 	} | 
 | ||||||
| 	if !bm.IsExist("astaxie1") { | 	assert.Equal(t, []byte("author"), bm.Get("astaxie")) | ||||||
| 		t.Error("check err") | 
 | ||||||
| 	} | 	assert.Nil(t, bm.Put("astaxie1", "author1", timeoutDuration)) | ||||||
|  | 
 | ||||||
|  | 	assert.True(t, bm.IsExist("astaxie1")) | ||||||
| 
 | 
 | ||||||
| 	vv := bm.GetMulti([]string{"astaxie", "astaxie1"}) | 	vv := bm.GetMulti([]string{"astaxie", "astaxie1"}) | ||||||
| 	if len(vv) != 2 { | 	assert.Equal(t, 2, len(vv)) | ||||||
| 		t.Error("GetMulti ERROR") | 	assert.Equal(t, []byte("author"), vv[0]) | ||||||
| 	} | 	assert.Equal(t, []byte("author1"), vv[1]) | ||||||
| 	if string(vv[0].([]byte)) != "author" && string(vv[0].([]byte)) != "author1" { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 	if string(vv[1].([]byte)) != "author1" && string(vv[1].([]byte)) != "author" { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test clear all | 	assert.Nil(t, bm.ClearAll()) | ||||||
| 	if err = bm.ClearAll(); err != nil { |  | ||||||
| 		t.Error("clear all err") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										8
									
								
								adapter/cache/redis/redis.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								adapter/cache/redis/redis.go
									
									
									
									
										vendored
									
									
								
							| @ -20,8 +20,8 @@ | |||||||
| // | // | ||||||
| // Usage: | // Usage: | ||||||
| // import( | // import( | ||||||
| //   _ "github.com/beego/beego/v2/cache/redis" | //   _ "github.com/beego/beego/v2/client/cache/redis" | ||||||
| //   "github.com/beego/beego/v2/cache" | //   "github.com/beego/beego/v2/client/cache" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| //  bm, err := cache.NewCache("redis", `{"conn":"127.0.0.1:11211"}`) | //  bm, err := cache.NewCache("redis", `{"conn":"127.0.0.1:11211"}`) | ||||||
| @ -34,10 +34,8 @@ import ( | |||||||
| 	redis2 "github.com/beego/beego/v2/client/cache/redis" | 	redis2 "github.com/beego/beego/v2/client/cache/redis" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( |  | ||||||
| // DefaultKey the collection name of redis for cache adapter. | // DefaultKey the collection name of redis for cache adapter. | ||||||
| 	DefaultKey = "beecacheRedis" | var DefaultKey = "beecacheRedis" | ||||||
| ) |  | ||||||
| 
 | 
 | ||||||
| // NewRedisCache create new redis cache with default collection name. | // NewRedisCache create new redis cache with default collection name. | ||||||
| func NewRedisCache() cache.Cache { | func NewRedisCache() cache.Cache { | ||||||
|  | |||||||
							
								
								
									
										124
									
								
								adapter/cache/redis/redis_test.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										124
									
								
								adapter/cache/redis/redis_test.go
									
									
									
									
										vendored
									
									
								
							| @ -21,10 +21,16 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/gomodule/redigo/redis" | 	"github.com/gomodule/redigo/redis" | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
| 
 | 
 | ||||||
| 	"github.com/beego/beego/v2/adapter/cache" | 	"github.com/beego/beego/v2/adapter/cache" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | const ( | ||||||
|  | 	initError = "init err" | ||||||
|  | 	setError  = "set Error" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| func TestRedisCache(t *testing.T) { | func TestRedisCache(t *testing.T) { | ||||||
| 	redisAddr := os.Getenv("REDIS_ADDR") | 	redisAddr := os.Getenv("REDIS_ADDR") | ||||||
| 	if redisAddr == "" { | 	if redisAddr == "" { | ||||||
| @ -32,98 +38,79 @@ func TestRedisCache(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	bm, err := cache.NewCache("redis", fmt.Sprintf(`{"conn": "%s"}`, redisAddr)) | 	bm, err := cache.NewCache("redis", fmt.Sprintf(`{"conn": "%s"}`, redisAddr)) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Error("init err") | 	timeoutDuration := 5 * time.Second | ||||||
| 	} |  | ||||||
| 	timeoutDuration := 10 * time.Second |  | ||||||
| 	if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { |  | ||||||
| 		t.Error("set Error", err) |  | ||||||
| 	} |  | ||||||
| 	if !bm.IsExist("astaxie") { |  | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	time.Sleep(11 * time.Second) | 	assert.Nil(t, bm.Put("astaxie", 1, timeoutDuration)) | ||||||
| 
 | 
 | ||||||
| 	if bm.IsExist("astaxie") { | 	assert.True(t, bm.IsExist("astaxie")) | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 	if err = bm.Put("astaxie", 1, timeoutDuration); err != nil { |  | ||||||
| 		t.Error("set Error", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v, _ := redis.Int(bm.Get("astaxie"), err); v != 1 { | 	time.Sleep(7 * time.Second) | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if err = bm.Incr("astaxie"); err != nil { | 	assert.False(t, bm.IsExist("astaxie")) | ||||||
| 		t.Error("Incr Error", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v, _ := redis.Int(bm.Get("astaxie"), err); v != 2 { | 	assert.Nil(t, bm.Put("astaxie", 1, timeoutDuration)) | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if err = bm.Decr("astaxie"); err != nil { | 	v, err := redis.Int(bm.Get("astaxie"), err) | ||||||
| 		t.Error("Decr Error", err) | 	assert.Nil(t, err) | ||||||
| 	} | 	assert.Equal(t, 1, v) | ||||||
| 
 | 
 | ||||||
| 	if v, _ := redis.Int(bm.Get("astaxie"), err); v != 1 { | 	assert.Nil(t, bm.Incr("astaxie")) | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 	bm.Delete("astaxie") |  | ||||||
| 	if bm.IsExist("astaxie") { |  | ||||||
| 		t.Error("delete err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test string | 	v, err = redis.Int(bm.Get("astaxie"), err) | ||||||
| 	if err = bm.Put("astaxie", "author", timeoutDuration); err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Error("set Error", err) | 	assert.Equal(t, 2, v) | ||||||
| 	} |  | ||||||
| 	if !bm.IsExist("astaxie") { |  | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v, _ := redis.String(bm.Get("astaxie"), err); v != "author" { | 	assert.Nil(t, bm.Decr("astaxie")) | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test GetMulti | 	v, err = redis.Int(bm.Get("astaxie"), err) | ||||||
| 	if err = bm.Put("astaxie1", "author1", timeoutDuration); err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Error("set Error", err) | 	assert.Equal(t, 1, v) | ||||||
| 	} | 
 | ||||||
| 	if !bm.IsExist("astaxie1") { | 	assert.Nil(t, bm.Delete("astaxie")) | ||||||
| 		t.Error("check err") | 
 | ||||||
| 	} | 	assert.False(t, bm.IsExist("astaxie")) | ||||||
|  | 
 | ||||||
|  | 	assert.Nil(t, bm.Put("astaxie", "author", timeoutDuration)) | ||||||
|  | 	assert.True(t, bm.IsExist("astaxie")) | ||||||
|  | 
 | ||||||
|  | 	vs, err := redis.String(bm.Get("astaxie"), err) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, "author", vs) | ||||||
|  | 
 | ||||||
|  | 	assert.Nil(t, bm.Put("astaxie1", "author1", timeoutDuration)) | ||||||
|  | 
 | ||||||
|  | 	assert.True(t, bm.IsExist("astaxie1")) | ||||||
| 
 | 
 | ||||||
| 	vv := bm.GetMulti([]string{"astaxie", "astaxie1"}) | 	vv := bm.GetMulti([]string{"astaxie", "astaxie1"}) | ||||||
| 	if len(vv) != 2 { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 	if v, _ := redis.String(vv[0], nil); v != "author" { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 	if v, _ := redis.String(vv[1], nil); v != "author1" { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  | 	assert.Equal(t, 2, len(vv)) | ||||||
|  | 
 | ||||||
|  | 	vs, err = redis.String(vv[0], nil) | ||||||
|  | 
 | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, "author", vs) | ||||||
|  | 
 | ||||||
|  | 	vs, err = redis.String(vv[1], nil) | ||||||
|  | 
 | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, "author1", vs) | ||||||
|  | 
 | ||||||
|  | 	assert.Nil(t, bm.ClearAll()) | ||||||
| 	// test clear all | 	// test clear all | ||||||
| 	if err = bm.ClearAll(); err != nil { |  | ||||||
| 		t.Error("clear all err") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestCache_Scan(t *testing.T) { | func TestCacheScan(t *testing.T) { | ||||||
| 	timeoutDuration := 10 * time.Second | 	timeoutDuration := 10 * time.Second | ||||||
| 	// init | 	// init | ||||||
| 	bm, err := cache.NewCache("redis", `{"conn": "127.0.0.1:6379"}`) | 	bm, err := cache.NewCache("redis", `{"conn": "127.0.0.1:6379"}`) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Error("init err") | 		t.Error(initError) | ||||||
| 	} | 	} | ||||||
| 	// insert all | 	// insert all | ||||||
| 	for i := 0; i < 10000; i++ { | 	for i := 0; i < 10000; i++ { | ||||||
| 		if err = bm.Put(fmt.Sprintf("astaxie%d", i), fmt.Sprintf("author%d", i), timeoutDuration); err != nil { | 		if err = bm.Put(fmt.Sprintf("astaxie%d", i), fmt.Sprintf("author%d", i), timeoutDuration); err != nil { | ||||||
| 			t.Error("set Error", err) | 			t.Error(setError, err) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -131,5 +118,4 @@ func TestCache_Scan(t *testing.T) { | |||||||
| 	if err = bm.ClearAll(); err != nil { | 	if err = bm.ClearAll(); err != nil { | ||||||
| 		t.Error("clear all err") | 		t.Error("clear all err") | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										114
									
								
								adapter/cache/ssdb/ssdb_test.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										114
									
								
								adapter/cache/ssdb/ssdb_test.go
									
									
									
									
										vendored
									
									
								
							| @ -7,6 +7,8 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | 
 | ||||||
| 	"github.com/beego/beego/v2/adapter/cache" | 	"github.com/beego/beego/v2/adapter/cache" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @ -17,95 +19,59 @@ func TestSsdbcacheCache(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	ssdb, err := cache.NewCache("ssdb", fmt.Sprintf(`{"conn": "%s"}`, ssdbAddr)) | 	ssdb, err := cache.NewCache("ssdb", fmt.Sprintf(`{"conn": "%s"}`, ssdbAddr)) | ||||||
| 	if err != nil { |  | ||||||
| 		t.Error("init err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 
 | ||||||
|  | 	assert.False(t, ssdb.IsExist("ssdb")) | ||||||
| 	// test put and exist | 	// test put and exist | ||||||
| 	if ssdb.IsExist("ssdb") { | 	timeoutDuration := 3 * time.Second | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 	timeoutDuration := 10 * time.Second |  | ||||||
| 	// timeoutDuration := -10*time.Second   if timeoutDuration is negtive,it means permanent | 	// timeoutDuration := -10*time.Second   if timeoutDuration is negtive,it means permanent | ||||||
| 	if err = ssdb.Put("ssdb", "ssdb", timeoutDuration); err != nil { | 	assert.Nil(t, ssdb.Put("ssdb", "ssdb", timeoutDuration)) | ||||||
| 		t.Error("set Error", err) | 	assert.True(t, ssdb.IsExist("ssdb")) | ||||||
| 	} |  | ||||||
| 	if !ssdb.IsExist("ssdb") { |  | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// Get test done | 	assert.Nil(t, ssdb.Put("ssdb", "ssdb", timeoutDuration)) | ||||||
| 	if err = ssdb.Put("ssdb", "ssdb", timeoutDuration); err != nil { |  | ||||||
| 		t.Error("set Error", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v := ssdb.Get("ssdb"); v != "ssdb" { | 	assert.Equal(t, "ssdb", ssdb.Get("ssdb")) | ||||||
| 		t.Error("get Error") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// inc/dec test done | 	// inc/dec test done | ||||||
| 	if err = ssdb.Put("ssdb", "2", timeoutDuration); err != nil { | 	assert.Nil(t, ssdb.Put("ssdb", "2", timeoutDuration)) | ||||||
| 		t.Error("set Error", err) |  | ||||||
| 	} |  | ||||||
| 	if err = ssdb.Incr("ssdb"); err != nil { |  | ||||||
| 		t.Error("incr Error", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v, err := strconv.Atoi(ssdb.Get("ssdb").(string)); err != nil || v != 3 { | 	assert.Nil(t, ssdb.Incr("ssdb")) | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if err = ssdb.Decr("ssdb"); err != nil { | 	v, err := strconv.Atoi(ssdb.Get("ssdb").(string)) | ||||||
| 		t.Error("decr error") | 	assert.Nil(t, err) | ||||||
| 	} | 	assert.Equal(t, 3, v) | ||||||
|  | 
 | ||||||
|  | 	assert.Nil(t, ssdb.Decr("ssdb")) | ||||||
|  | 
 | ||||||
|  | 	assert.Nil(t, ssdb.Put("ssdb", "3", timeoutDuration)) | ||||||
| 
 | 
 | ||||||
| 	// test del | 	// test del | ||||||
| 	if err = ssdb.Put("ssdb", "3", timeoutDuration); err != nil { | 	v, err = strconv.Atoi(ssdb.Get("ssdb").(string)) | ||||||
| 		t.Error("set Error", err) | 	assert.Nil(t, err) | ||||||
| 	} | 	assert.Equal(t, 3, v) | ||||||
| 	if v, err := strconv.Atoi(ssdb.Get("ssdb").(string)); err != nil || v != 3 { | 
 | ||||||
| 		t.Error("get err") | 	assert.Nil(t, ssdb.Delete("ssdb")) | ||||||
| 	} | 	assert.False(t, ssdb.IsExist("ssdb")) | ||||||
| 	if err := ssdb.Delete("ssdb"); err == nil { |  | ||||||
| 		if ssdb.IsExist("ssdb") { |  | ||||||
| 			t.Error("delete err") |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test string | 	// test string | ||||||
| 	if err = ssdb.Put("ssdb", "ssdb", -10*time.Second); err != nil { | 	assert.Nil(t, ssdb.Put("ssdb", "ssdb", -10*time.Second)) | ||||||
| 		t.Error("set Error", err) | 
 | ||||||
| 	} | 	assert.True(t, ssdb.IsExist("ssdb")) | ||||||
| 	if !ssdb.IsExist("ssdb") { | 	assert.Equal(t, "ssdb", ssdb.Get("ssdb")) | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 	if v := ssdb.Get("ssdb").(string); v != "ssdb" { |  | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test GetMulti done | 	// test GetMulti done | ||||||
| 	if err = ssdb.Put("ssdb1", "ssdb1", -10*time.Second); err != nil { | 	assert.Nil(t, ssdb.Put("ssdb1", "ssdb1", -10*time.Second)) | ||||||
| 		t.Error("set Error", err) | 	assert.True(t, ssdb.IsExist("ssdb1")) | ||||||
| 	} |  | ||||||
| 	if !ssdb.IsExist("ssdb1") { |  | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 	vv := ssdb.GetMulti([]string{"ssdb", "ssdb1"}) |  | ||||||
| 	if len(vv) != 2 { |  | ||||||
| 		t.Error("getmulti error") |  | ||||||
| 	} |  | ||||||
| 	if vv[0].(string) != "ssdb" { |  | ||||||
| 		t.Error("getmulti error") |  | ||||||
| 	} |  | ||||||
| 	if vv[1].(string) != "ssdb1" { |  | ||||||
| 		t.Error("getmulti error") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  | 	vv := ssdb.GetMulti([]string{"ssdb", "ssdb1"}) | ||||||
|  | 	assert.Equal(t, 2, len(vv)) | ||||||
|  | 
 | ||||||
|  | 	assert.Equal(t, "ssdb", vv[0]) | ||||||
|  | 	assert.Equal(t, "ssdb1", vv[1]) | ||||||
|  | 
 | ||||||
|  | 	assert.Nil(t, ssdb.ClearAll()) | ||||||
|  | 	assert.False(t, ssdb.IsExist("ssdb")) | ||||||
|  | 	assert.False(t, ssdb.IsExist("ssdb1")) | ||||||
| 	// test clear all done | 	// test clear all done | ||||||
| 	if err = ssdb.ClearAll(); err != nil { |  | ||||||
| 		t.Error("clear all err") |  | ||||||
| 	} |  | ||||||
| 	if ssdb.IsExist("ssdb") || ssdb.IsExist("ssdb1") { |  | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -14,7 +14,7 @@ | |||||||
| 
 | 
 | ||||||
| // Package config is used to parse config. | // Package config is used to parse config. | ||||||
| // Usage: | // Usage: | ||||||
| //  import "github.com/beego/beego/v2/config" | //  import "github.com/beego/beego/v2/core/config" | ||||||
| // Examples. | // Examples. | ||||||
| // | // | ||||||
| //  cnf, err := config.NewConfig("ini", "config.conf") | //  cnf, err := config.NewConfig("ini", "config.conf") | ||||||
|  | |||||||
| @ -20,7 +20,6 @@ import ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestExpandValueEnv(t *testing.T) { | func TestExpandValueEnv(t *testing.T) { | ||||||
| 
 |  | ||||||
| 	testCases := []struct { | 	testCases := []struct { | ||||||
| 		item string | 		item string | ||||||
| 		want string | 		want string | ||||||
| @ -51,5 +50,4 @@ func TestExpandValueEnv(t *testing.T) { | |||||||
| 			t.Errorf("expand value error, item %q want %q, got %q", c.item, c.want, got) | 			t.Errorf("expand value error, item %q want %q, got %q", c.item, c.want, got) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -20,6 +20,6 @@ import ( | |||||||
| 
 | 
 | ||||||
| // NewFakeConfig return a fake Configer | // NewFakeConfig return a fake Configer | ||||||
| func NewFakeConfig() Configer { | func NewFakeConfig() Configer { | ||||||
| 	new := config.NewFakeConfig() | 	config := config.NewFakeConfig() | ||||||
| 	return &newToOldConfigerAdapter{delegate: new} | 	return &newToOldConfigerAdapter{delegate: config} | ||||||
| } | } | ||||||
|  | |||||||
| @ -23,7 +23,6 @@ import ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestIni(t *testing.T) { | func TestIni(t *testing.T) { | ||||||
| 
 |  | ||||||
| 	var ( | 	var ( | ||||||
| 		inicontext = ` | 		inicontext = ` | ||||||
| ;comment one | ;comment one | ||||||
| @ -81,7 +80,8 @@ password = ${GOPATH} | |||||||
| 		} | 		} | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 	f, err := os.Create("testini.conf") | 	cfgFile := "testini.conf" | ||||||
|  | 	f, err := os.Create(cfgFile) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| @ -91,8 +91,8 @@ password = ${GOPATH} | |||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 	f.Close() | 	f.Close() | ||||||
| 	defer os.Remove("testini.conf") | 	defer os.Remove(cfgFile) | ||||||
| 	iniconf, err := NewConfig("ini", "testini.conf") | 	iniconf, err := NewConfig("ini", cfgFile) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| @ -128,11 +128,9 @@ password = ${GOPATH} | |||||||
| 	if iniconf.String("name") != "astaxie" { | 	if iniconf.String("name") != "astaxie" { | ||||||
| 		t.Fatal("get name error") | 		t.Fatal("get name error") | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestIniSave(t *testing.T) { | func TestIniSave(t *testing.T) { | ||||||
| 
 |  | ||||||
| 	const ( | 	const ( | ||||||
| 		inicontext = ` | 		inicontext = ` | ||||||
| app = app | app = app | ||||||
|  | |||||||
| @ -18,10 +18,11 @@ import ( | |||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"os" | 	"os" | ||||||
| 	"testing" | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestJsonStartsWithArray(t *testing.T) { | func TestJsonStartsWithArray(t *testing.T) { | ||||||
| 
 |  | ||||||
| 	const jsoncontextwitharray = `[ | 	const jsoncontextwitharray = `[ | ||||||
| 	{ | 	{ | ||||||
| 		"url": "user", | 		"url": "user", | ||||||
| @ -32,7 +33,8 @@ func TestJsonStartsWithArray(t *testing.T) { | |||||||
| 		"serviceAPI": "http://www.test.com/employee" | 		"serviceAPI": "http://www.test.com/employee" | ||||||
| 	} | 	} | ||||||
| ]` | ]` | ||||||
| 	f, err := os.Create("testjsonWithArray.conf") | 	cfgFileName := "testjsonWithArray.conf" | ||||||
|  | 	f, err := os.Create(cfgFileName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| @ -42,8 +44,8 @@ func TestJsonStartsWithArray(t *testing.T) { | |||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 	f.Close() | 	f.Close() | ||||||
| 	defer os.Remove("testjsonWithArray.conf") | 	defer os.Remove(cfgFileName) | ||||||
| 	jsonconf, err := NewConfig("json", "testjsonWithArray.conf") | 	jsonconf, err := NewConfig("json", cfgFileName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| @ -68,7 +70,6 @@ func TestJsonStartsWithArray(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestJson(t *testing.T) { | func TestJson(t *testing.T) { | ||||||
| 
 |  | ||||||
| 	var ( | 	var ( | ||||||
| 		jsoncontext = `{ | 		jsoncontext = `{ | ||||||
| "appname": "beeapi", | "appname": "beeapi", | ||||||
| @ -132,7 +133,8 @@ func TestJson(t *testing.T) { | |||||||
| 		} | 		} | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 	f, err := os.Create("testjson.conf") | 	cfgFileName := "testjson.conf" | ||||||
|  | 	f, err := os.Create(cfgFileName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| @ -142,8 +144,8 @@ func TestJson(t *testing.T) { | |||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 	f.Close() | 	f.Close() | ||||||
| 	defer os.Remove("testjson.conf") | 	defer os.Remove(cfgFileName) | ||||||
| 	jsonconf, err := NewConfig("json", "testjson.conf") | 	jsonconf, err := NewConfig("json", cfgFileName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| @ -167,56 +169,39 @@ func TestJson(t *testing.T) { | |||||||
| 		default: | 		default: | ||||||
| 			value, err = jsonconf.DIY(k) | 			value, err = jsonconf.DIY(k) | ||||||
| 		} | 		} | ||||||
| 		if err != nil { | 
 | ||||||
| 			t.Fatalf("get key %q value fatal,%v err %s", k, v, err) | 		assert.Nil(t, err) | ||||||
| 		} else if fmt.Sprintf("%v", v) != fmt.Sprintf("%v", value) { | 		assert.Equal(t, fmt.Sprintf("%v", v), fmt.Sprintf("%v", value)) | ||||||
| 			t.Fatalf("get key %q value, want %v got %v .", k, v, value) |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	} | 	assert.Nil(t, jsonconf.Set("name", "astaxie")) | ||||||
| 	if err = jsonconf.Set("name", "astaxie"); err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if jsonconf.String("name") != "astaxie" { |  | ||||||
| 		t.Fatal("get name error") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if db, err := jsonconf.DIY("database"); err != nil { | 	assert.Equal(t, "astaxie", jsonconf.String("name")) | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} else if m, ok := db.(map[string]interface{}); !ok { |  | ||||||
| 		t.Log(db) |  | ||||||
| 		t.Fatal("db not map[string]interface{}") |  | ||||||
| 	} else { |  | ||||||
| 		if m["host"].(string) != "host" { |  | ||||||
| 			t.Fatal("get host err") |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if _, err := jsonconf.Int("unknown"); err == nil { | 	db, err := jsonconf.DIY("database") | ||||||
| 		t.Error("unknown keys should return an error when expecting an Int") | 	assert.Nil(t, err) | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if _, err := jsonconf.Int64("unknown"); err == nil { | 	m, ok := db.(map[string]interface{}) | ||||||
| 		t.Error("unknown keys should return an error when expecting an Int64") | 	assert.True(t, ok) | ||||||
| 	} | 	assert.Equal(t, "host", m["host"]) | ||||||
| 
 | 
 | ||||||
| 	if _, err := jsonconf.Float("unknown"); err == nil { | 	_, err = jsonconf.Int("unknown") | ||||||
| 		t.Error("unknown keys should return an error when expecting a Float") | 	assert.NotNil(t, err) | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if _, err := jsonconf.DIY("unknown"); err == nil { | 	_, err = jsonconf.Int64("unknown") | ||||||
| 		t.Error("unknown keys should return an error when expecting an interface{}") | 	assert.NotNil(t, err) | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if val := jsonconf.String("unknown"); val != "" { | 	_, err = jsonconf.Float("unknown") | ||||||
| 		t.Error("unknown keys should return an empty string when expecting a String") | 	assert.NotNil(t, err) | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if _, err := jsonconf.Bool("unknown"); err == nil { | 	_, err = jsonconf.DIY("unknown") | ||||||
| 		t.Error("unknown keys should return an error when expecting a Bool") | 	assert.NotNil(t, err) | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if !jsonconf.DefaultBool("unknown", true) { | 	val := jsonconf.String("unknown") | ||||||
| 		t.Error("unknown keys with default value wrong") | 	assert.Equal(t, "", val) | ||||||
| 	} | 
 | ||||||
|  | 	_, err = jsonconf.Bool("unknown") | ||||||
|  | 	assert.NotNil(t, err) | ||||||
|  | 
 | ||||||
|  | 	assert.True(t, jsonconf.DefaultBool("unknown", true)) | ||||||
| } | } | ||||||
|  | |||||||
| @ -20,8 +20,8 @@ | |||||||
| // | // | ||||||
| // Usage: | // Usage: | ||||||
| //  import( | //  import( | ||||||
| //    _ "github.com/beego/beego/v2/config/xml" | //    _ "github.com/beego/beego/v2/core/config/xml" | ||||||
| //      "github.com/beego/beego/v2/config" | //      "github.com/beego/beego/v2/core/config" | ||||||
| //  ) | //  ) | ||||||
| // | // | ||||||
| //  cnf, err := config.NewConfig("xml", "config.xml") | //  cnf, err := config.NewConfig("xml", "config.xml") | ||||||
|  | |||||||
| @ -23,7 +23,6 @@ import ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestXML(t *testing.T) { | func TestXML(t *testing.T) { | ||||||
| 
 |  | ||||||
| 	var ( | 	var ( | ||||||
| 		// xml parse should incluce in <config></config> tags | 		// xml parse should incluce in <config></config> tags | ||||||
| 		xmlcontext = `<?xml version="1.0" encoding="UTF-8"?> | 		xmlcontext = `<?xml version="1.0" encoding="UTF-8"?> | ||||||
| @ -58,7 +57,8 @@ func TestXML(t *testing.T) { | |||||||
| 		} | 		} | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| 	f, err := os.Create("testxml.conf") | 	cfgFileName := "testxml.conf" | ||||||
|  | 	f, err := os.Create(cfgFileName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| @ -68,9 +68,9 @@ func TestXML(t *testing.T) { | |||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 	f.Close() | 	f.Close() | ||||||
| 	defer os.Remove("testxml.conf") | 	defer os.Remove(cfgFileName) | ||||||
| 
 | 
 | ||||||
| 	xmlconf, err := config.NewConfig("xml", "testxml.conf") | 	xmlconf, err := config.NewConfig("xml", cfgFileName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -20,8 +20,8 @@ | |||||||
| // | // | ||||||
| // Usage: | // Usage: | ||||||
| //  import( | //  import( | ||||||
| //   _ "github.com/beego/beego/v2/config/yaml" | //   _ "github.com/beego/beego/v2/core/config/yaml" | ||||||
| //     "github.com/beego/beego/v2/config" | //     "github.com/beego/beego/v2/core/config" | ||||||
| //  ) | //  ) | ||||||
| // | // | ||||||
| //  cnf, err := config.NewConfig("yaml", "config.yaml") | //  cnf, err := config.NewConfig("yaml", "config.yaml") | ||||||
|  | |||||||
| @ -23,7 +23,6 @@ import ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestYaml(t *testing.T) { | func TestYaml(t *testing.T) { | ||||||
| 
 |  | ||||||
| 	var ( | 	var ( | ||||||
| 		yamlcontext = ` | 		yamlcontext = ` | ||||||
| "appname": beeapi | "appname": beeapi | ||||||
| @ -54,7 +53,8 @@ func TestYaml(t *testing.T) { | |||||||
| 			"emptystrings":    []string{}, | 			"emptystrings":    []string{}, | ||||||
| 		} | 		} | ||||||
| 	) | 	) | ||||||
| 	f, err := os.Create("testyaml.conf") | 	cfgFileName := "testyaml.conf" | ||||||
|  | 	f, err := os.Create(cfgFileName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| @ -64,8 +64,8 @@ func TestYaml(t *testing.T) { | |||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 	f.Close() | 	f.Close() | ||||||
| 	defer os.Remove("testyaml.conf") | 	defer os.Remove(cfgFileName) | ||||||
| 	yamlconf, err := config.NewConfig("yaml", "testyaml.conf") | 	yamlconf, err := config.NewConfig("yaml", cfgFileName) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| @ -111,5 +111,4 @@ func TestYaml(t *testing.T) { | |||||||
| 	if yamlconf.String("name") != "astaxie" { | 	if yamlconf.String("name") != "astaxie" { | ||||||
| 		t.Fatal("get name error") | 		t.Fatal("get name error") | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ | |||||||
| // Package context provide the context utils | // Package context provide the context utils | ||||||
| // Usage: | // Usage: | ||||||
| // | // | ||||||
| //	import "github.com/beego/beego/v2/context" | //	import "github.com/beego/beego/v2/server/web/context" | ||||||
| // | // | ||||||
| //	ctx := context.Context{Request:req,ResponseWriter:rw} | //	ctx := context.Context{Request:req,ResponseWriter:rw} | ||||||
| // | // | ||||||
|  | |||||||
							
								
								
									
										18
									
								
								adapter/context/param/conv.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								adapter/context/param/conv.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | |||||||
|  | package param | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"reflect" | ||||||
|  | 
 | ||||||
|  | 	beecontext "github.com/beego/beego/v2/adapter/context" | ||||||
|  | 	"github.com/beego/beego/v2/server/web/context" | ||||||
|  | 	"github.com/beego/beego/v2/server/web/context/param" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // ConvertParams converts http method params to values that will be passed to the method controller as arguments | ||||||
|  | func ConvertParams(methodParams []*MethodParam, methodType reflect.Type, ctx *beecontext.Context) (result []reflect.Value) { | ||||||
|  | 	nps := make([]*param.MethodParam, 0, len(methodParams)) | ||||||
|  | 	for _, mp := range methodParams { | ||||||
|  | 		nps = append(nps, (*param.MethodParam)(mp)) | ||||||
|  | 	} | ||||||
|  | 	return param.ConvertParams(nps, methodType, (*context.Context)(ctx)) | ||||||
|  | } | ||||||
							
								
								
									
										39
									
								
								adapter/context/param/conv_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								adapter/context/param/conv_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,39 @@ | |||||||
|  | // Copyright 2020 beego | ||||||
|  | // | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | // you may not use this file except in compliance with the License. | ||||||
|  | // You may obtain a copy of the License at | ||||||
|  | // | ||||||
|  | // http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | // | ||||||
|  | // Unless required by applicable law or agreed to in writing, software | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | // See the License for the specific language governing permissions and | ||||||
|  | // limitations under the License. | ||||||
|  | 
 | ||||||
|  | package param | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"reflect" | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | 
 | ||||||
|  | 	"github.com/beego/beego/v2/adapter/context" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Demo is used to test, it's empty | ||||||
|  | func Demo(i int) { | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestConvertParams(t *testing.T) { | ||||||
|  | 	res := ConvertParams(nil, reflect.TypeOf(Demo), context.NewContext()) | ||||||
|  | 	assert.Equal(t, 0, len(res)) | ||||||
|  | 	ctx := context.NewContext() | ||||||
|  | 	ctx.Input.RequestBody = []byte("11") | ||||||
|  | 	res = ConvertParams([]*MethodParam{ | ||||||
|  | 		New("A", InBody), | ||||||
|  | 	}, reflect.TypeOf(Demo), ctx) | ||||||
|  | 	assert.Equal(t, int64(11), res[0].Int()) | ||||||
|  | } | ||||||
							
								
								
									
										29
									
								
								adapter/context/param/methodparams.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								adapter/context/param/methodparams.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | |||||||
|  | package param | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"github.com/beego/beego/v2/server/web/context/param" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // MethodParam keeps param information to be auto passed to controller methods | ||||||
|  | type MethodParam param.MethodParam | ||||||
|  | 
 | ||||||
|  | // New creates a new MethodParam with name and specific options | ||||||
|  | func New(name string, opts ...MethodParamOption) *MethodParam { | ||||||
|  | 	newOps := make([]param.MethodParamOption, 0, len(opts)) | ||||||
|  | 	for _, o := range opts { | ||||||
|  | 		newOps = append(newOps, oldMpoToNew(o)) | ||||||
|  | 	} | ||||||
|  | 	return (*MethodParam)(param.New(name, newOps...)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Make creates an array of MethodParmas or an empty array | ||||||
|  | func Make(list ...*MethodParam) []*MethodParam { | ||||||
|  | 	if len(list) > 0 { | ||||||
|  | 		return list | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (mp *MethodParam) String() string { | ||||||
|  | 	return (*param.MethodParam)(mp).String() | ||||||
|  | } | ||||||
							
								
								
									
										34
									
								
								adapter/context/param/methodparams_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								adapter/context/param/methodparams_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | |||||||
|  | // Copyright 2020 beego | ||||||
|  | // | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | // you may not use this file except in compliance with the License. | ||||||
|  | // You may obtain a copy of the License at | ||||||
|  | // | ||||||
|  | // http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | // | ||||||
|  | // Unless required by applicable law or agreed to in writing, software | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | // See the License for the specific language governing permissions and | ||||||
|  | // limitations under the License. | ||||||
|  | 
 | ||||||
|  | package param | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestMethodParamString(t *testing.T) { | ||||||
|  | 	method := New("myName", IsRequired, InHeader, Default("abc")) | ||||||
|  | 	s := method.String() | ||||||
|  | 	assert.Equal(t, `param.New("myName", param.IsRequired, param.InHeader, param.Default("abc"))`, s) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestMake(t *testing.T) { | ||||||
|  | 	res := Make() | ||||||
|  | 	assert.Equal(t, 0, len(res)) | ||||||
|  | 	res = Make(New("myName", InBody)) | ||||||
|  | 	assert.Equal(t, 1, len(res)) | ||||||
|  | } | ||||||
							
								
								
									
										45
									
								
								adapter/context/param/options.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								adapter/context/param/options.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | package param | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"github.com/beego/beego/v2/server/web/context/param" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // MethodParamOption defines a func which apply options on a MethodParam | ||||||
|  | type MethodParamOption func(*MethodParam) | ||||||
|  | 
 | ||||||
|  | // IsRequired indicates that this param is required and can not be omitted from the http request | ||||||
|  | var IsRequired MethodParamOption = func(p *MethodParam) { | ||||||
|  | 	param.IsRequired((*param.MethodParam)(p)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // InHeader indicates that this param is passed via an http header | ||||||
|  | var InHeader MethodParamOption = func(p *MethodParam) { | ||||||
|  | 	param.InHeader((*param.MethodParam)(p)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // InPath indicates that this param is part of the URL path | ||||||
|  | var InPath MethodParamOption = func(p *MethodParam) { | ||||||
|  | 	param.InPath((*param.MethodParam)(p)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // InBody indicates that this param is passed as an http request body | ||||||
|  | var InBody MethodParamOption = func(p *MethodParam) { | ||||||
|  | 	param.InBody((*param.MethodParam)(p)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // Default provides a default value for the http param | ||||||
|  | func Default(defaultValue interface{}) MethodParamOption { | ||||||
|  | 	return newMpoToOld(param.Default(defaultValue)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func newMpoToOld(n param.MethodParamOption) MethodParamOption { | ||||||
|  | 	return func(methodParam *MethodParam) { | ||||||
|  | 		n((*param.MethodParam)(methodParam)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func oldMpoToNew(old MethodParamOption) param.MethodParamOption { | ||||||
|  | 	return func(methodParam *param.MethodParam) { | ||||||
|  | 		old((*MethodParam)(methodParam)) | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -19,9 +19,8 @@ import ( | |||||||
| 	"net/url" | 	"net/url" | ||||||
| 
 | 
 | ||||||
| 	"github.com/beego/beego/v2/adapter/session" | 	"github.com/beego/beego/v2/adapter/session" | ||||||
| 	webContext "github.com/beego/beego/v2/server/web/context" |  | ||||||
| 
 |  | ||||||
| 	"github.com/beego/beego/v2/server/web" | 	"github.com/beego/beego/v2/server/web" | ||||||
|  | 	webContext "github.com/beego/beego/v2/server/web/context" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
| @ -49,9 +48,11 @@ type ControllerCommentsSlice web.ControllerCommentsSlice | |||||||
| func (p ControllerCommentsSlice) Len() int { | func (p ControllerCommentsSlice) Len() int { | ||||||
| 	return (web.ControllerCommentsSlice)(p).Len() | 	return (web.ControllerCommentsSlice)(p).Len() | ||||||
| } | } | ||||||
|  | 
 | ||||||
| func (p ControllerCommentsSlice) Less(i, j int) bool { | func (p ControllerCommentsSlice) Less(i, j int) bool { | ||||||
| 	return (web.ControllerCommentsSlice)(p).Less(i, j) | 	return (web.ControllerCommentsSlice)(p).Less(i, j) | ||||||
| } | } | ||||||
|  | 
 | ||||||
| func (p ControllerCommentsSlice) Swap(i, j int) { | func (p ControllerCommentsSlice) Swap(i, j int) { | ||||||
| 	(web.ControllerCommentsSlice)(p).Swap(i, j) | 	(web.ControllerCommentsSlice)(p).Swap(i, j) | ||||||
| } | } | ||||||
|  | |||||||
| @ -18,9 +18,8 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 
 | 
 | ||||||
| 	"github.com/beego/beego/v2/adapter/context" | 	"github.com/beego/beego/v2/adapter/context" | ||||||
| 	beecontext "github.com/beego/beego/v2/server/web/context" |  | ||||||
| 
 |  | ||||||
| 	"github.com/beego/beego/v2/server/web" | 	"github.com/beego/beego/v2/server/web" | ||||||
|  | 	beecontext "github.com/beego/beego/v2/server/web/context" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
|  | |||||||
| @ -22,7 +22,7 @@ | |||||||
| //	 "net/http" | //	 "net/http" | ||||||
| //	 "os" | //	 "os" | ||||||
| // | // | ||||||
| //   "github.com/beego/beego/v2/grace" | //   "github.com/beego/beego/v2/server/web/grace" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| //  func handler(w http.ResponseWriter, r *http.Request) { | //  func handler(w http.ResponseWriter, r *http.Request) { | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ | |||||||
| // Package httplib is used as http.Client | // Package httplib is used as http.Client | ||||||
| // Usage: | // Usage: | ||||||
| // | // | ||||||
| // import "github.com/beego/beego/v2/httplib" | // import "github.com/beego/beego/v2/client/httplib" | ||||||
| // | // | ||||||
| //	b := httplib.Post("http://beego.me/") | //	b := httplib.Post("http://beego.me/") | ||||||
| //	b.Param("username","astaxie") | //	b.Param("username","astaxie") | ||||||
| @ -115,12 +115,6 @@ func (b *BeegoHTTPRequest) SetUserAgent(useragent string) *BeegoHTTPRequest { | |||||||
| 	return b | 	return b | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Debug sets show debug or not when executing request. |  | ||||||
| func (b *BeegoHTTPRequest) Debug(isdebug bool) *BeegoHTTPRequest { |  | ||||||
| 	b.delegate.Debug(isdebug) |  | ||||||
| 	return b |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // Retries sets Retries times. | // Retries sets Retries times. | ||||||
| // default is 0 means no retried. | // default is 0 means no retried. | ||||||
| // -1 means retried forever. | // -1 means retried forever. | ||||||
| @ -135,17 +129,6 @@ func (b *BeegoHTTPRequest) RetryDelay(delay time.Duration) *BeegoHTTPRequest { | |||||||
| 	return b | 	return b | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // DumpBody setting whether need to Dump the Body. |  | ||||||
| func (b *BeegoHTTPRequest) DumpBody(isdump bool) *BeegoHTTPRequest { |  | ||||||
| 	b.delegate.DumpBody(isdump) |  | ||||||
| 	return b |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // DumpRequest return the DumpRequest |  | ||||||
| func (b *BeegoHTTPRequest) DumpRequest() []byte { |  | ||||||
| 	return b.delegate.DumpRequest() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // SetTimeout sets connect time out and read-write time out for BeegoRequest. | // SetTimeout sets connect time out and read-write time out for BeegoRequest. | ||||||
| func (b *BeegoHTTPRequest) SetTimeout(connectTimeout, readWriteTimeout time.Duration) *BeegoHTTPRequest { | func (b *BeegoHTTPRequest) SetTimeout(connectTimeout, readWriteTimeout time.Duration) *BeegoHTTPRequest { | ||||||
| 	b.delegate.SetTimeout(connectTimeout, readWriteTimeout) | 	b.delegate.SetTimeout(connectTimeout, readWriteTimeout) | ||||||
|  | |||||||
| @ -15,6 +15,7 @@ | |||||||
| package httplib | package httplib | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"bytes" | ||||||
| 	"errors" | 	"errors" | ||||||
| 	"io/ioutil" | 	"io/ioutil" | ||||||
| 	"net" | 	"net" | ||||||
| @ -25,8 +26,13 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | const ( | ||||||
|  | 	getURL = "http://httpbin.org/get" | ||||||
|  | 	ipURL  = "http://httpbin.org/ip" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| func TestResponse(t *testing.T) { | func TestResponse(t *testing.T) { | ||||||
| 	req := Get("http://httpbin.org/get") | 	req := Get(getURL) | ||||||
| 	resp, err := req.Response() | 	resp, err := req.Response() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| @ -59,11 +65,10 @@ func TestDoRequest(t *testing.T) { | |||||||
| 	if elapsedTime < delayedTime { | 	if elapsedTime < delayedTime { | ||||||
| 		t.Errorf("Not enough retries. Took %dms. Delay was meant to take %dms", elapsedTime, delayedTime) | 		t.Errorf("Not enough retries. Took %dms. Delay was meant to take %dms", elapsedTime, delayedTime) | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestGet(t *testing.T) { | func TestGet(t *testing.T) { | ||||||
| 	req := Get("http://httpbin.org/get") | 	req := Get(getURL) | ||||||
| 	b, err := req.Bytes() | 	b, err := req.Bytes() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| @ -205,7 +210,7 @@ func TestWithSetting(t *testing.T) { | |||||||
| 	setting.ReadWriteTimeout = 5 * time.Second | 	setting.ReadWriteTimeout = 5 * time.Second | ||||||
| 	SetDefaultSetting(setting) | 	SetDefaultSetting(setting) | ||||||
| 
 | 
 | ||||||
| 	str, err := Get("http://httpbin.org/get").String() | 	str, err := Get(getURL).String() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| @ -218,7 +223,7 @@ func TestWithSetting(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestToJson(t *testing.T) { | func TestToJson(t *testing.T) { | ||||||
| 	req := Get("http://httpbin.org/ip") | 	req := Get(ipURL) | ||||||
| 	resp, err := req.Response() | 	resp, err := req.Response() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| @ -244,33 +249,32 @@ func TestToJson(t *testing.T) { | |||||||
| 			t.Fatal("response is not valid ip") | 			t.Fatal("response is not valid ip") | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestToFile(t *testing.T) { | func TestToFile(t *testing.T) { | ||||||
| 	f := "beego_testfile" | 	f := "beego_testfile" | ||||||
| 	req := Get("http://httpbin.org/ip") | 	req := Get(ipURL) | ||||||
| 	err := req.ToFile(f) | 	err := req.ToFile(f) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 	defer os.Remove(f) | 	defer os.Remove(f) | ||||||
| 	b, err := ioutil.ReadFile(f) | 	b, err := ioutil.ReadFile(f) | ||||||
| 	if n := strings.Index(string(b), "origin"); n == -1 { | 	if n := bytes.Index(b, []byte("origin")); n == -1 { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestToFileDir(t *testing.T) { | func TestToFileDir(t *testing.T) { | ||||||
| 	f := "./files/beego_testfile" | 	f := "./files/beego_testfile" | ||||||
| 	req := Get("http://httpbin.org/ip") | 	req := Get(ipURL) | ||||||
| 	err := req.ToFile(f) | 	err := req.ToFile(f) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| 	defer os.RemoveAll("./files") | 	defer os.RemoveAll("./files") | ||||||
| 	b, err := ioutil.ReadFile(f) | 	b, err := ioutil.ReadFile(f) | ||||||
| 	if n := strings.Index(string(b), "origin"); n == -1 { | 	if n := bytes.Index(b, []byte("origin")); n == -1 { | ||||||
| 		t.Fatal(err) | 		t.Fatal(err) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -18,108 +18,106 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/beego/beego/v2/core/logs" | 	"github.com/beego/beego/v2/core/logs" | ||||||
| 
 |  | ||||||
| 	webLog "github.com/beego/beego/v2/core/logs" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Log levels to control the logging output. | // Log levels to control the logging output. | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| const ( | const ( | ||||||
| 	LevelEmergency     = webLog.LevelEmergency | 	LevelEmergency     = logs.LevelEmergency | ||||||
| 	LevelAlert         = webLog.LevelAlert | 	LevelAlert         = logs.LevelAlert | ||||||
| 	LevelCritical      = webLog.LevelCritical | 	LevelCritical      = logs.LevelCritical | ||||||
| 	LevelError         = webLog.LevelError | 	LevelError         = logs.LevelError | ||||||
| 	LevelWarning       = webLog.LevelWarning | 	LevelWarning       = logs.LevelWarning | ||||||
| 	LevelNotice        = webLog.LevelNotice | 	LevelNotice        = logs.LevelNotice | ||||||
| 	LevelInformational = webLog.LevelInformational | 	LevelInformational = logs.LevelInformational | ||||||
| 	LevelDebug         = webLog.LevelDebug | 	LevelDebug         = logs.LevelDebug | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // BeeLogger references the used application logger. | // BeeLogger references the used application logger. | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| var BeeLogger = logs.GetBeeLogger() | var BeeLogger = logs.GetBeeLogger() | ||||||
| 
 | 
 | ||||||
| // SetLevel sets the global log level used by the simple logger. | // SetLevel sets the global log level used by the simple logger. | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| func SetLevel(l int) { | func SetLevel(l int) { | ||||||
| 	logs.SetLevel(l) | 	logs.SetLevel(l) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SetLogFuncCall set the CallDepth, default is 3 | // SetLogFuncCall set the CallDepth, default is 3 | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| func SetLogFuncCall(b bool) { | func SetLogFuncCall(b bool) { | ||||||
| 	logs.SetLogFuncCall(b) | 	logs.SetLogFuncCall(b) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SetLogger sets a new logger. | // SetLogger sets a new logger. | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| func SetLogger(adaptername string, config string) error { | func SetLogger(adaptername string, config string) error { | ||||||
| 	return logs.SetLogger(adaptername, config) | 	return logs.SetLogger(adaptername, config) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Emergency logs a message at emergency level. | // Emergency logs a message at emergency level. | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| func Emergency(v ...interface{}) { | func Emergency(v ...interface{}) { | ||||||
| 	logs.Emergency(generateFmtStr(len(v)), v...) | 	logs.Emergency(generateFmtStr(len(v)), v...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Alert logs a message at alert level. | // Alert logs a message at alert level. | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| func Alert(v ...interface{}) { | func Alert(v ...interface{}) { | ||||||
| 	logs.Alert(generateFmtStr(len(v)), v...) | 	logs.Alert(generateFmtStr(len(v)), v...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Critical logs a message at critical level. | // Critical logs a message at critical level. | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| func Critical(v ...interface{}) { | func Critical(v ...interface{}) { | ||||||
| 	logs.Critical(generateFmtStr(len(v)), v...) | 	logs.Critical(generateFmtStr(len(v)), v...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Error logs a message at error level. | // Error logs a message at error level. | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| func Error(v ...interface{}) { | func Error(v ...interface{}) { | ||||||
| 	logs.Error(generateFmtStr(len(v)), v...) | 	logs.Error(generateFmtStr(len(v)), v...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Warning logs a message at warning level. | // Warning logs a message at warning level. | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| func Warning(v ...interface{}) { | func Warning(v ...interface{}) { | ||||||
| 	logs.Warning(generateFmtStr(len(v)), v...) | 	logs.Warning(generateFmtStr(len(v)), v...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Warn compatibility alias for Warning() | // Warn compatibility alias for Warning() | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| func Warn(v ...interface{}) { | func Warn(v ...interface{}) { | ||||||
| 	logs.Warn(generateFmtStr(len(v)), v...) | 	logs.Warn(generateFmtStr(len(v)), v...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Notice logs a message at notice level. | // Notice logs a message at notice level. | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| func Notice(v ...interface{}) { | func Notice(v ...interface{}) { | ||||||
| 	logs.Notice(generateFmtStr(len(v)), v...) | 	logs.Notice(generateFmtStr(len(v)), v...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Informational logs a message at info level. | // Informational logs a message at info level. | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| func Informational(v ...interface{}) { | func Informational(v ...interface{}) { | ||||||
| 	logs.Informational(generateFmtStr(len(v)), v...) | 	logs.Informational(generateFmtStr(len(v)), v...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Info compatibility alias for Warning() | // Info compatibility alias for Warning() | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| func Info(v ...interface{}) { | func Info(v ...interface{}) { | ||||||
| 	logs.Info(generateFmtStr(len(v)), v...) | 	logs.Info(generateFmtStr(len(v)), v...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Debug logs a message at debug level. | // Debug logs a message at debug level. | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| func Debug(v ...interface{}) { | func Debug(v ...interface{}) { | ||||||
| 	logs.Debug(generateFmtStr(len(v)), v...) | 	logs.Debug(generateFmtStr(len(v)), v...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Trace logs a message at trace level. | // Trace logs a message at trace level. | ||||||
| // compatibility alias for Warning() | // compatibility alias for Warning() | ||||||
| // Deprecated: use github.com/beego/beego/v2/logs instead. | // Deprecated: use github.com/beego/beego/v2/core/logs instead. | ||||||
| func Trace(v ...interface{}) { | func Trace(v ...interface{}) { | ||||||
| 	logs.Trace(generateFmtStr(len(v)), v...) | 	logs.Trace(generateFmtStr(len(v)), v...) | ||||||
| } | } | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ | |||||||
| // Package logs provide a general log interface | // Package logs provide a general log interface | ||||||
| // Usage: | // Usage: | ||||||
| // | // | ||||||
| // import "github.com/beego/beego/v2/logs" | // import "github.com/beego/beego/v2/core/logs" | ||||||
| // | // | ||||||
| //	log := NewLogger(10000) | //	log := NewLogger(10000) | ||||||
| //	log.SetLogger("console", "") | //	log.SetLogger("console", "") | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestBeeLogger_Info(t *testing.T) { | func TestBeeLoggerInfo(t *testing.T) { | ||||||
| 	log := NewLogger(1000) | 	log := NewLogger(1000) | ||||||
| 	log.SetLogger("file", `{"net":"tcp","addr":":7020"}`) | 	log.SetLogger("file", `{"net":"tcp","addr":":7020"}`) | ||||||
| } | } | ||||||
|  | |||||||
| @ -15,6 +15,7 @@ | |||||||
| package metric | package metric | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
|  | 	"fmt" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"testing" | 	"testing" | ||||||
| @ -26,7 +27,9 @@ import ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestPrometheusMiddleWare(t *testing.T) { | func TestPrometheusMiddleWare(t *testing.T) { | ||||||
| 	middleware := PrometheusMiddleWare(http.HandlerFunc(func(http.ResponseWriter, *http.Request) {})) | 	middleware := PrometheusMiddleWare(http.HandlerFunc(func(http.ResponseWriter, *http.Request) { | ||||||
|  | 		fmt.Print("you are coming") | ||||||
|  | 	})) | ||||||
| 	writer := &context.Response{} | 	writer := &context.Response{} | ||||||
| 	request := &http.Request{ | 	request := &http.Request{ | ||||||
| 		URL: &url.URL{ | 		URL: &url.URL{ | ||||||
|  | |||||||
| @ -18,9 +18,8 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 
 | 
 | ||||||
| 	adtContext "github.com/beego/beego/v2/adapter/context" | 	adtContext "github.com/beego/beego/v2/adapter/context" | ||||||
| 	"github.com/beego/beego/v2/server/web/context" |  | ||||||
| 
 |  | ||||||
| 	"github.com/beego/beego/v2/server/web" | 	"github.com/beego/beego/v2/server/web" | ||||||
|  | 	"github.com/beego/beego/v2/server/web/context" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type namespaceCond func(*adtContext.Context) bool | type namespaceCond func(*adtContext.Context) bool | ||||||
| @ -240,141 +239,158 @@ func AddNamespace(nl ...*Namespace) { | |||||||
| 
 | 
 | ||||||
| // NSCond is Namespace Condition | // NSCond is Namespace Condition | ||||||
| func NSCond(cond namespaceCond) LinkNamespace { | func NSCond(cond namespaceCond) LinkNamespace { | ||||||
| 	return func(namespace *Namespace) { | 	wc := web.NSCond(func(b *context.Context) bool { | ||||||
| 		web.NSCond(func(b *context.Context) bool { |  | ||||||
| 		return cond((*adtContext.Context)(b)) | 		return cond((*adtContext.Context)(b)) | ||||||
| 	}) | 	}) | ||||||
|  | 	return func(namespace *Namespace) { | ||||||
|  | 		wc((*web.Namespace)(namespace)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSBefore Namespace BeforeRouter filter | // NSBefore Namespace BeforeRouter filter | ||||||
| func NSBefore(filterList ...FilterFunc) LinkNamespace { | func NSBefore(filterList ...FilterFunc) LinkNamespace { | ||||||
| 	return func(namespace *Namespace) { |  | ||||||
| 	nfs := oldToNewFilter(filterList) | 	nfs := oldToNewFilter(filterList) | ||||||
| 		web.NSBefore(nfs...) | 	wf := web.NSBefore(nfs...) | ||||||
|  | 	return func(namespace *Namespace) { | ||||||
|  | 		wf((*web.Namespace)(namespace)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSAfter add Namespace FinishRouter filter | // NSAfter add Namespace FinishRouter filter | ||||||
| func NSAfter(filterList ...FilterFunc) LinkNamespace { | func NSAfter(filterList ...FilterFunc) LinkNamespace { | ||||||
| 	return func(namespace *Namespace) { |  | ||||||
| 	nfs := oldToNewFilter(filterList) | 	nfs := oldToNewFilter(filterList) | ||||||
| 		web.NSAfter(nfs...) | 	wf := web.NSAfter(nfs...) | ||||||
|  | 	return func(namespace *Namespace) { | ||||||
|  | 		wf((*web.Namespace)(namespace)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSInclude Namespace Include ControllerInterface | // NSInclude Namespace Include ControllerInterface | ||||||
| func NSInclude(cList ...ControllerInterface) LinkNamespace { | func NSInclude(cList ...ControllerInterface) LinkNamespace { | ||||||
| 	return func(namespace *Namespace) { |  | ||||||
| 	nfs := oldToNewCtrlIntfs(cList) | 	nfs := oldToNewCtrlIntfs(cList) | ||||||
| 		web.NSInclude(nfs...) | 	wi := web.NSInclude(nfs...) | ||||||
|  | 	return func(namespace *Namespace) { | ||||||
|  | 		wi((*web.Namespace)(namespace)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSRouter call Namespace Router | // NSRouter call Namespace Router | ||||||
| func NSRouter(rootpath string, c ControllerInterface, mappingMethods ...string) LinkNamespace { | func NSRouter(rootpath string, c ControllerInterface, mappingMethods ...string) LinkNamespace { | ||||||
|  | 	wn := web.NSRouter(rootpath, c, mappingMethods...) | ||||||
| 	return func(namespace *Namespace) { | 	return func(namespace *Namespace) { | ||||||
| 		web.Router(rootpath, c, mappingMethods...) | 		wn((*web.Namespace)(namespace)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSGet call Namespace Get | // NSGet call Namespace Get | ||||||
| func NSGet(rootpath string, f FilterFunc) LinkNamespace { | func NSGet(rootpath string, f FilterFunc) LinkNamespace { | ||||||
| 	return func(ns *Namespace) { | 	ln := web.NSGet(rootpath, func(ctx *context.Context) { | ||||||
| 		web.NSGet(rootpath, func(ctx *context.Context) { |  | ||||||
| 		f((*adtContext.Context)(ctx)) | 		f((*adtContext.Context)(ctx)) | ||||||
| 	}) | 	}) | ||||||
|  | 	return func(ns *Namespace) { | ||||||
|  | 		ln((*web.Namespace)(ns)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSPost call Namespace Post | // NSPost call Namespace Post | ||||||
| func NSPost(rootpath string, f FilterFunc) LinkNamespace { | func NSPost(rootpath string, f FilterFunc) LinkNamespace { | ||||||
| 	return func(ns *Namespace) { | 	wp := web.NSPost(rootpath, func(ctx *context.Context) { | ||||||
| 		web.Post(rootpath, func(ctx *context.Context) { |  | ||||||
| 		f((*adtContext.Context)(ctx)) | 		f((*adtContext.Context)(ctx)) | ||||||
| 	}) | 	}) | ||||||
|  | 	return func(ns *Namespace) { | ||||||
|  | 		wp((*web.Namespace)(ns)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSHead call Namespace Head | // NSHead call Namespace Head | ||||||
| func NSHead(rootpath string, f FilterFunc) LinkNamespace { | func NSHead(rootpath string, f FilterFunc) LinkNamespace { | ||||||
| 	return func(ns *Namespace) { | 	wb := web.NSHead(rootpath, func(ctx *context.Context) { | ||||||
| 		web.NSHead(rootpath, func(ctx *context.Context) { |  | ||||||
| 		f((*adtContext.Context)(ctx)) | 		f((*adtContext.Context)(ctx)) | ||||||
| 	}) | 	}) | ||||||
|  | 	return func(ns *Namespace) { | ||||||
|  | 		wb((*web.Namespace)(ns)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSPut call Namespace Put | // NSPut call Namespace Put | ||||||
| func NSPut(rootpath string, f FilterFunc) LinkNamespace { | func NSPut(rootpath string, f FilterFunc) LinkNamespace { | ||||||
| 	return func(ns *Namespace) { | 	wn := web.NSPut(rootpath, func(ctx *context.Context) { | ||||||
| 		web.NSPut(rootpath, func(ctx *context.Context) { |  | ||||||
| 		f((*adtContext.Context)(ctx)) | 		f((*adtContext.Context)(ctx)) | ||||||
| 	}) | 	}) | ||||||
|  | 	return func(ns *Namespace) { | ||||||
|  | 		wn((*web.Namespace)(ns)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSDelete call Namespace Delete | // NSDelete call Namespace Delete | ||||||
| func NSDelete(rootpath string, f FilterFunc) LinkNamespace { | func NSDelete(rootpath string, f FilterFunc) LinkNamespace { | ||||||
| 	return func(ns *Namespace) { | 	wn := web.NSDelete(rootpath, func(ctx *context.Context) { | ||||||
| 		web.NSDelete(rootpath, func(ctx *context.Context) { |  | ||||||
| 		f((*adtContext.Context)(ctx)) | 		f((*adtContext.Context)(ctx)) | ||||||
| 	}) | 	}) | ||||||
|  | 	return func(ns *Namespace) { | ||||||
|  | 		wn((*web.Namespace)(ns)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSAny call Namespace Any | // NSAny call Namespace Any | ||||||
| func NSAny(rootpath string, f FilterFunc) LinkNamespace { | func NSAny(rootpath string, f FilterFunc) LinkNamespace { | ||||||
| 	return func(ns *Namespace) { | 	wn := web.NSAny(rootpath, func(ctx *context.Context) { | ||||||
| 		web.NSAny(rootpath, func(ctx *context.Context) { |  | ||||||
| 		f((*adtContext.Context)(ctx)) | 		f((*adtContext.Context)(ctx)) | ||||||
| 	}) | 	}) | ||||||
|  | 	return func(ns *Namespace) { | ||||||
|  | 		wn((*web.Namespace)(ns)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSOptions call Namespace Options | // NSOptions call Namespace Options | ||||||
| func NSOptions(rootpath string, f FilterFunc) LinkNamespace { | func NSOptions(rootpath string, f FilterFunc) LinkNamespace { | ||||||
| 	return func(ns *Namespace) { | 	wo := web.NSOptions(rootpath, func(ctx *context.Context) { | ||||||
| 		web.NSOptions(rootpath, func(ctx *context.Context) { |  | ||||||
| 		f((*adtContext.Context)(ctx)) | 		f((*adtContext.Context)(ctx)) | ||||||
| 	}) | 	}) | ||||||
|  | 	return func(ns *Namespace) { | ||||||
|  | 		wo((*web.Namespace)(ns)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSPatch call Namespace Patch | // NSPatch call Namespace Patch | ||||||
| func NSPatch(rootpath string, f FilterFunc) LinkNamespace { | func NSPatch(rootpath string, f FilterFunc) LinkNamespace { | ||||||
| 	return func(ns *Namespace) { | 	wn := web.NSPatch(rootpath, func(ctx *context.Context) { | ||||||
| 		web.NSPatch(rootpath, func(ctx *context.Context) { |  | ||||||
| 		f((*adtContext.Context)(ctx)) | 		f((*adtContext.Context)(ctx)) | ||||||
| 	}) | 	}) | ||||||
|  | 	return func(ns *Namespace) { | ||||||
|  | 		wn((*web.Namespace)(ns)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSAutoRouter call Namespace AutoRouter | // NSAutoRouter call Namespace AutoRouter | ||||||
| func NSAutoRouter(c ControllerInterface) LinkNamespace { | func NSAutoRouter(c ControllerInterface) LinkNamespace { | ||||||
|  | 	wn := web.NSAutoRouter(c) | ||||||
| 	return func(ns *Namespace) { | 	return func(ns *Namespace) { | ||||||
| 		web.NSAutoRouter(c) | 		wn((*web.Namespace)(ns)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSAutoPrefix call Namespace AutoPrefix | // NSAutoPrefix call Namespace AutoPrefix | ||||||
| func NSAutoPrefix(prefix string, c ControllerInterface) LinkNamespace { | func NSAutoPrefix(prefix string, c ControllerInterface) LinkNamespace { | ||||||
|  | 	wn := web.NSAutoPrefix(prefix, c) | ||||||
| 	return func(ns *Namespace) { | 	return func(ns *Namespace) { | ||||||
| 		web.NSAutoPrefix(prefix, c) | 		wn((*web.Namespace)(ns)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSNamespace add sub Namespace | // NSNamespace add sub Namespace | ||||||
| func NSNamespace(prefix string, params ...LinkNamespace) LinkNamespace { | func NSNamespace(prefix string, params ...LinkNamespace) LinkNamespace { | ||||||
| 	return func(ns *Namespace) { |  | ||||||
| 	nps := oldToNewLinkNs(params) | 	nps := oldToNewLinkNs(params) | ||||||
| 		web.NSNamespace(prefix, nps...) | 	wn := web.NSNamespace(prefix, nps...) | ||||||
|  | 	return func(ns *Namespace) { | ||||||
|  | 		wn((*web.Namespace)(ns)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // NSHandler add handler | // NSHandler add handler | ||||||
| func NSHandler(rootpath string, h http.Handler) LinkNamespace { | func NSHandler(rootpath string, h http.Handler) LinkNamespace { | ||||||
|  | 	wn := web.NSHandler(rootpath, h) | ||||||
| 	return func(ns *Namespace) { | 	return func(ns *Namespace) { | ||||||
| 		web.NSHandler(rootpath, h) | 		wn((*web.Namespace)(ns)) | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -18,7 +18,5 @@ import ( | |||||||
| 	"github.com/beego/beego/v2/client/orm" | 	"github.com/beego/beego/v2/client/orm" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( |  | ||||||
| // ErrMissPK missing pk error | // ErrMissPK missing pk error | ||||||
| 	ErrMissPK = orm.ErrMissPK | var ErrMissPK = orm.ErrMissPK | ||||||
| ) |  | ||||||
|  | |||||||
| @ -25,7 +25,7 @@ func RegisterModel(models ...interface{}) { | |||||||
| 
 | 
 | ||||||
| // RegisterModelWithPrefix register models with a prefix | // RegisterModelWithPrefix register models with a prefix | ||||||
| func RegisterModelWithPrefix(prefix string, models ...interface{}) { | func RegisterModelWithPrefix(prefix string, models ...interface{}) { | ||||||
| 	orm.RegisterModelWithPrefix(prefix, models) | 	orm.RegisterModelWithPrefix(prefix, models...) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // RegisterModelWithSuffix register models with a suffix | // RegisterModelWithSuffix register models with a suffix | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| // Copyright 2020 | // Copyright 2020 beego | ||||||
| // | // | ||||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | // Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
| // you may not use this file except in compliance with the License. | // you may not use this file except in compliance with the License. | ||||||
| @ -15,20 +15,17 @@ | |||||||
| package orm | package orm | ||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"github.com/beego/beego/v2/client/orm" | 	"testing" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type baseQuerySetter struct { | type User struct { | ||||||
|  | 	Id int | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (b *baseQuerySetter) ForceIndex(indexes ...string) orm.QuerySeter { | type Seller struct { | ||||||
| 	panic("you should not invoke this method.") | 	Id int | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (b *baseQuerySetter) UseIndex(indexes ...string) orm.QuerySeter { | func TestRegisterModelWithPrefix(t *testing.T) { | ||||||
| 	panic("you should not invoke this method.") | 	RegisterModelWithPrefix("test", &User{}, &Seller{}) | ||||||
| } |  | ||||||
| 
 |  | ||||||
| func (b *baseQuerySetter) IgnoreIndex(indexes ...string) orm.QuerySeter { |  | ||||||
| 	panic("you should not invoke this method.") |  | ||||||
| } | } | ||||||
| @ -21,7 +21,7 @@ | |||||||
| // | // | ||||||
| //	import ( | //	import ( | ||||||
| //		"fmt" | //		"fmt" | ||||||
| //		"github.com/beego/beego/v2/orm" | //		"github.com/beego/beego/v2/client/orm" | ||||||
| //		_ "github.com/go-sql-driver/mysql" // import your used driver | //		_ "github.com/go-sql-driver/mysql" // import your used driver | ||||||
| //	) | //	) | ||||||
| // | // | ||||||
|  | |||||||
| @ -195,7 +195,7 @@ func snakeStringWithAcronym(s string) string { | |||||||
| 		} | 		} | ||||||
| 		data = append(data, d) | 		data = append(data, d) | ||||||
| 	} | 	} | ||||||
| 	return strings.ToLower(string(data[:])) | 	return strings.ToLower(string(data)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // snake string, XxYy to xx_yy , XxYY to xx_y_y | // snake string, XxYy to xx_yy , XxYY to xx_y_y | ||||||
| @ -213,7 +213,7 @@ func snakeString(s string) string { | |||||||
| 		} | 		} | ||||||
| 		data = append(data, d) | 		data = append(data, d) | ||||||
| 	} | 	} | ||||||
| 	return strings.ToLower(string(data[:])) | 	return strings.ToLower(string(data)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // SetNameStrategy set different name strategy | // SetNameStrategy set different name strategy | ||||||
| @ -241,7 +241,7 @@ func camelString(s string) string { | |||||||
| 		} | 		} | ||||||
| 		data = append(data, d) | 		data = append(data, d) | ||||||
| 	} | 	} | ||||||
| 	return string(data[:]) | 	return string(data) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type argString []string | type argString []string | ||||||
|  | |||||||
| @ -16,6 +16,8 @@ package orm | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestCamelString(t *testing.T) { | func TestCamelString(t *testing.T) { | ||||||
| @ -29,9 +31,7 @@ func TestCamelString(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	for _, v := range snake { | 	for _, v := range snake { | ||||||
| 		res := camelString(v) | 		res := camelString(v) | ||||||
| 		if res != answer[v] { | 		assert.Equal(t, answer[v], res) | ||||||
| 			t.Error("Unit Test Fail:", v, res, answer[v]) |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -46,9 +46,7 @@ func TestSnakeString(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	for _, v := range camel { | 	for _, v := range camel { | ||||||
| 		res := snakeString(v) | 		res := snakeString(v) | ||||||
| 		if res != answer[v] { | 		assert.Equal(t, answer[v], res) | ||||||
| 			t.Error("Unit Test Fail:", v, res, answer[v]) |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @ -63,8 +61,6 @@ func TestSnakeStringWithAcronym(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	for _, v := range camel { | 	for _, v := range camel { | ||||||
| 		res := snakeStringWithAcronym(v) | 		res := snakeStringWithAcronym(v) | ||||||
| 		if res != answer[v] { | 		assert.Equal(t, answer[v], res) | ||||||
| 			t.Error("Unit Test Fail:", v, res, answer[v]) |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -17,7 +17,7 @@ | |||||||
| // Simple Usage: | // Simple Usage: | ||||||
| //	import( | //	import( | ||||||
| //		"github.com/beego/beego/v2" | //		"github.com/beego/beego/v2" | ||||||
| //		"github.com/beego/beego/v2/plugins/apiauth" | //		"github.com/beego/beego/v2/server/web/filter/apiauth" | ||||||
| //	) | //	) | ||||||
| // | // | ||||||
| //	func main(){ | //	func main(){ | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ | |||||||
| // Simple Usage: | // Simple Usage: | ||||||
| //	import( | //	import( | ||||||
| //		"github.com/beego/beego/v2" | //		"github.com/beego/beego/v2" | ||||||
| //		"github.com/beego/beego/v2/plugins/auth" | //		"github.com/beego/beego/v2/server/web/filter/auth" | ||||||
| //	) | //	) | ||||||
| // | // | ||||||
| //	func main(){ | //	func main(){ | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ | |||||||
| // Simple Usage: | // Simple Usage: | ||||||
| //	import( | //	import( | ||||||
| //		"github.com/beego/beego/v2" | //		"github.com/beego/beego/v2" | ||||||
| //		"github.com/beego/beego/v2/plugins/authz" | //		"github.com/beego/beego/v2/server/web/filter/authz" | ||||||
| //		"github.com/casbin/casbin" | //		"github.com/casbin/casbin" | ||||||
| //	) | //	) | ||||||
| // | // | ||||||
|  | |||||||
| @ -26,6 +26,11 @@ import ( | |||||||
| 	"github.com/beego/beego/v2/adapter/plugins/auth" | 	"github.com/beego/beego/v2/adapter/plugins/auth" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | const ( | ||||||
|  | 	authCfg = "authz_model.conf" | ||||||
|  | 	authCsv = "authz_policy.csv" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| func testRequest(t *testing.T, handler *beego.ControllerRegister, user string, path string, method string, code int) { | func testRequest(t *testing.T, handler *beego.ControllerRegister, user string, path string, method string, code int) { | ||||||
| 	r, _ := http.NewRequest(method, path, nil) | 	r, _ := http.NewRequest(method, path, nil) | ||||||
| 	r.SetBasicAuth(user, "123") | 	r.SetBasicAuth(user, "123") | ||||||
| @ -40,70 +45,79 @@ func testRequest(t *testing.T, handler *beego.ControllerRegister, user string, p | |||||||
| func TestBasic(t *testing.T) { | func TestBasic(t *testing.T) { | ||||||
| 	handler := beego.NewControllerRegister() | 	handler := beego.NewControllerRegister() | ||||||
| 
 | 
 | ||||||
| 	handler.InsertFilter("*", beego.BeforeRouter, auth.Basic("alice", "123")) | 	_ = handler.InsertFilter("*", beego.BeforeRouter, auth.Basic("alice", "123")) | ||||||
| 	handler.InsertFilter("*", beego.BeforeRouter, NewAuthorizer(casbin.NewEnforcer("authz_model.conf", "authz_policy.csv"))) | 
 | ||||||
|  | 	_ = handler.InsertFilter("*", beego.BeforeRouter, NewAuthorizer(casbin.NewEnforcer(authCfg, authCsv))) | ||||||
| 
 | 
 | ||||||
| 	handler.Any("*", func(ctx *context.Context) { | 	handler.Any("*", func(ctx *context.Context) { | ||||||
| 		ctx.Output.SetStatus(200) | 		ctx.Output.SetStatus(200) | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	testRequest(t, handler, "alice", "/dataset1/resource1", "GET", 200) | 	const d1r1 = "/dataset1/resource1" | ||||||
| 	testRequest(t, handler, "alice", "/dataset1/resource1", "POST", 200) | 	testRequest(t, handler, "alice", d1r1, "GET", 200) | ||||||
| 	testRequest(t, handler, "alice", "/dataset1/resource2", "GET", 200) | 	testRequest(t, handler, "alice", d1r1, "POST", 200) | ||||||
| 	testRequest(t, handler, "alice", "/dataset1/resource2", "POST", 403) | 	const d1r2 = "/dataset1/resource2" | ||||||
|  | 	testRequest(t, handler, "alice", d1r2, "GET", 200) | ||||||
|  | 	testRequest(t, handler, "alice", d1r2, "POST", 403) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestPathWildcard(t *testing.T) { | func TestPathWildcard(t *testing.T) { | ||||||
| 	handler := beego.NewControllerRegister() | 	handler := beego.NewControllerRegister() | ||||||
| 
 | 
 | ||||||
| 	handler.InsertFilter("*", beego.BeforeRouter, auth.Basic("bob", "123")) | 	_ = handler.InsertFilter("*", beego.BeforeRouter, auth.Basic("bob", "123")) | ||||||
| 	handler.InsertFilter("*", beego.BeforeRouter, NewAuthorizer(casbin.NewEnforcer("authz_model.conf", "authz_policy.csv"))) | 	_ = handler.InsertFilter("*", beego.BeforeRouter, NewAuthorizer(casbin.NewEnforcer(authCfg, authCsv))) | ||||||
| 
 | 
 | ||||||
| 	handler.Any("*", func(ctx *context.Context) { | 	handler.Any("*", func(ctx *context.Context) { | ||||||
| 		ctx.Output.SetStatus(200) | 		ctx.Output.SetStatus(200) | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	testRequest(t, handler, "bob", "/dataset2/resource1", "GET", 200) | 	const d2r1 = "/dataset2/resource1" | ||||||
| 	testRequest(t, handler, "bob", "/dataset2/resource1", "POST", 200) | 	testRequest(t, handler, "bob", d2r1, "GET", 200) | ||||||
| 	testRequest(t, handler, "bob", "/dataset2/resource1", "DELETE", 200) | 	testRequest(t, handler, "bob", d2r1, "POST", 200) | ||||||
| 	testRequest(t, handler, "bob", "/dataset2/resource2", "GET", 200) | 	testRequest(t, handler, "bob", d2r1, "DELETE", 200) | ||||||
| 	testRequest(t, handler, "bob", "/dataset2/resource2", "POST", 403) | 	const d2r2 = "/dataset2/resource2" | ||||||
| 	testRequest(t, handler, "bob", "/dataset2/resource2", "DELETE", 403) | 	testRequest(t, handler, "bob", d2r2, "GET", 200) | ||||||
|  | 	testRequest(t, handler, "bob", d2r2, "POST", 403) | ||||||
|  | 	testRequest(t, handler, "bob", d2r2, "DELETE", 403) | ||||||
| 
 | 
 | ||||||
| 	testRequest(t, handler, "bob", "/dataset2/folder1/item1", "GET", 403) | 	const item1 = "/dataset2/folder1/item1" | ||||||
| 	testRequest(t, handler, "bob", "/dataset2/folder1/item1", "POST", 200) | 	testRequest(t, handler, "bob", item1, "GET", 403) | ||||||
| 	testRequest(t, handler, "bob", "/dataset2/folder1/item1", "DELETE", 403) | 	testRequest(t, handler, "bob", item1, "POST", 200) | ||||||
| 	testRequest(t, handler, "bob", "/dataset2/folder1/item2", "GET", 403) | 	testRequest(t, handler, "bob", item1, "DELETE", 403) | ||||||
| 	testRequest(t, handler, "bob", "/dataset2/folder1/item2", "POST", 200) | 	const item2 = "/dataset2/folder1/item2" | ||||||
| 	testRequest(t, handler, "bob", "/dataset2/folder1/item2", "DELETE", 403) | 	testRequest(t, handler, "bob", item2, "GET", 403) | ||||||
|  | 	testRequest(t, handler, "bob", item2, "POST", 200) | ||||||
|  | 	testRequest(t, handler, "bob", item2, "DELETE", 403) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestRBAC(t *testing.T) { | func TestRBAC(t *testing.T) { | ||||||
| 	handler := beego.NewControllerRegister() | 	handler := beego.NewControllerRegister() | ||||||
| 
 | 
 | ||||||
| 	handler.InsertFilter("*", beego.BeforeRouter, auth.Basic("cathy", "123")) | 	_ = handler.InsertFilter("*", beego.BeforeRouter, auth.Basic("cathy", "123")) | ||||||
| 	e := casbin.NewEnforcer("authz_model.conf", "authz_policy.csv") | 	e := casbin.NewEnforcer(authCfg, authCsv) | ||||||
| 	handler.InsertFilter("*", beego.BeforeRouter, NewAuthorizer(e)) | 	_ = handler.InsertFilter("*", beego.BeforeRouter, NewAuthorizer(e)) | ||||||
| 
 | 
 | ||||||
| 	handler.Any("*", func(ctx *context.Context) { | 	handler.Any("*", func(ctx *context.Context) { | ||||||
| 		ctx.Output.SetStatus(200) | 		ctx.Output.SetStatus(200) | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	// cathy can access all /dataset1/* resources via all methods because it has the dataset1_admin role. | 	// cathy can access all /dataset1/* resources via all methods because it has the dataset1_admin role. | ||||||
| 	testRequest(t, handler, "cathy", "/dataset1/item", "GET", 200) | 	const dataSet1 = "/dataset1/item" | ||||||
| 	testRequest(t, handler, "cathy", "/dataset1/item", "POST", 200) | 	testRequest(t, handler, "cathy", dataSet1, "GET", 200) | ||||||
| 	testRequest(t, handler, "cathy", "/dataset1/item", "DELETE", 200) | 	testRequest(t, handler, "cathy", dataSet1, "POST", 200) | ||||||
| 	testRequest(t, handler, "cathy", "/dataset2/item", "GET", 403) | 	testRequest(t, handler, "cathy", dataSet1, "DELETE", 200) | ||||||
| 	testRequest(t, handler, "cathy", "/dataset2/item", "POST", 403) | 	const dataSet2 = "/dataset2/item" | ||||||
| 	testRequest(t, handler, "cathy", "/dataset2/item", "DELETE", 403) | 	testRequest(t, handler, "cathy", dataSet2, "GET", 403) | ||||||
|  | 	testRequest(t, handler, "cathy", dataSet2, "POST", 403) | ||||||
|  | 	testRequest(t, handler, "cathy", dataSet2, "DELETE", 403) | ||||||
| 
 | 
 | ||||||
| 	// delete all roles on user cathy, so cathy cannot access any resources now. | 	// delete all roles on user cathy, so cathy cannot access any resources now. | ||||||
| 	e.DeleteRolesForUser("cathy") | 	e.DeleteRolesForUser("cathy") | ||||||
| 
 | 
 | ||||||
| 	testRequest(t, handler, "cathy", "/dataset1/item", "GET", 403) | 	testRequest(t, handler, "cathy", dataSet1, "GET", 403) | ||||||
| 	testRequest(t, handler, "cathy", "/dataset1/item", "POST", 403) | 	testRequest(t, handler, "cathy", dataSet1, "POST", 403) | ||||||
| 	testRequest(t, handler, "cathy", "/dataset1/item", "DELETE", 403) | 	testRequest(t, handler, "cathy", dataSet1, "DELETE", 403) | ||||||
| 	testRequest(t, handler, "cathy", "/dataset2/item", "GET", 403) | 	testRequest(t, handler, "cathy", dataSet2, "GET", 403) | ||||||
| 	testRequest(t, handler, "cathy", "/dataset2/item", "POST", 403) | 	testRequest(t, handler, "cathy", dataSet2, "POST", 403) | ||||||
| 	testRequest(t, handler, "cathy", "/dataset2/item", "DELETE", 403) | 	testRequest(t, handler, "cathy", dataSet2, "DELETE", 403) | ||||||
| } | } | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ | |||||||
| // Usage | // Usage | ||||||
| //	import ( | //	import ( | ||||||
| // 		"github.com/beego/beego/v2" | // 		"github.com/beego/beego/v2" | ||||||
| //		"github.com/beego/beego/v2/plugins/cors" | //		"github.com/beego/beego/v2/server/web/filter/cors" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| //	func main() { | //	func main() { | ||||||
| @ -37,10 +37,9 @@ package cors | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	beego "github.com/beego/beego/v2/adapter" | 	beego "github.com/beego/beego/v2/adapter" | ||||||
|  | 	"github.com/beego/beego/v2/adapter/context" | ||||||
| 	beecontext "github.com/beego/beego/v2/server/web/context" | 	beecontext "github.com/beego/beego/v2/server/web/context" | ||||||
| 	"github.com/beego/beego/v2/server/web/filter/cors" | 	"github.com/beego/beego/v2/server/web/filter/cors" | ||||||
| 
 |  | ||||||
| 	"github.com/beego/beego/v2/adapter/context" |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Options represents Access Control options. | // Options represents Access Control options. | ||||||
|  | |||||||
| @ -19,9 +19,8 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	beecontext "github.com/beego/beego/v2/adapter/context" | 	beecontext "github.com/beego/beego/v2/adapter/context" | ||||||
| 	"github.com/beego/beego/v2/server/web/context" |  | ||||||
| 
 |  | ||||||
| 	"github.com/beego/beego/v2/server/web" | 	"github.com/beego/beego/v2/server/web" | ||||||
|  | 	"github.com/beego/beego/v2/server/web/context" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // default filter execution points | // default filter execution points | ||||||
| @ -87,7 +86,7 @@ func NewControllerRegister() *ControllerRegister { | |||||||
| //	Add("/api",&RestController{},"get,post:ApiFunc" | //	Add("/api",&RestController{},"get,post:ApiFunc" | ||||||
| //	Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc") | //	Add("/simple",&SimpleController{},"get:GetFunc;post:PostFunc") | ||||||
| func (p *ControllerRegister) Add(pattern string, c ControllerInterface, mappingMethods ...string) { | func (p *ControllerRegister) Add(pattern string, c ControllerInterface, mappingMethods ...string) { | ||||||
| 	(*web.ControllerRegister)(p).Add(pattern, c, mappingMethods...) | 	(*web.ControllerRegister)(p).Add(pattern, c, web.WithRouterMethods(c, mappingMethods...)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Include only when the Runmode is dev will generate router file in the router/auto.go from the controller | // Include only when the Runmode is dev will generate router file in the router/auto.go from the controller | ||||||
| @ -217,7 +216,7 @@ func (p *ControllerRegister) Handler(pattern string, h http.Handler, options ... | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // AddAuto router to ControllerRegister. | // AddAuto router to ControllerRegister. | ||||||
| // example beego.AddAuto(&MainContorlller{}), | // example beego.AddAuto(&MainController{}), | ||||||
| // MainController has method List and Page. | // MainController has method List and Page. | ||||||
| // visit the url /main/list to execute List function | // visit the url /main/list to execute List function | ||||||
| // /main/page to execute Page function. | // /main/page to execute Page function. | ||||||
| @ -226,7 +225,7 @@ func (p *ControllerRegister) AddAuto(c ControllerInterface) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // AddAutoPrefix Add auto router to ControllerRegister with prefix. | // AddAutoPrefix Add auto router to ControllerRegister with prefix. | ||||||
| // example beego.AddAutoPrefix("/admin",&MainContorlller{}), | // example beego.AddAutoPrefix("/admin",&MainController{}), | ||||||
| // MainController has method List and Page. | // MainController has method List and Page. | ||||||
| // visit the url /admin/main/list to execute List function | // visit the url /admin/main/list to execute List function | ||||||
| // /admin/main/page to execute Page function. | // /admin/main/page to execute Page function. | ||||||
|  | |||||||
| @ -20,8 +20,8 @@ | |||||||
| // | // | ||||||
| // Usage: | // Usage: | ||||||
| // import( | // import( | ||||||
| //   _ "github.com/beego/beego/v2/session/couchbase" | //   _ "github.com/beego/beego/v2/server/web/session/couchbase" | ||||||
| //   "github.com/beego/beego/v2/session" | //   "github.com/beego/beego/v2/server/web/session" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| //	func init() { | //	func init() { | ||||||
|  | |||||||
| @ -20,8 +20,8 @@ | |||||||
| // | // | ||||||
| // Usage: | // Usage: | ||||||
| // import( | // import( | ||||||
| //   _ "github.com/beego/beego/v2/session/memcache" | //   _ "github.com/beego/beego/v2/server/web/session/memcache" | ||||||
| //   "github.com/beego/beego/v2/session" | //   "github.com/beego/beego/v2/server/web/session" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| //	func init() { | //	func init() { | ||||||
| @ -37,7 +37,6 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 
 | 
 | ||||||
| 	"github.com/beego/beego/v2/adapter/session" | 	"github.com/beego/beego/v2/adapter/session" | ||||||
| 
 |  | ||||||
| 	beemem "github.com/beego/beego/v2/server/web/session/memcache" | 	beemem "github.com/beego/beego/v2/server/web/session/memcache" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -28,8 +28,8 @@ | |||||||
| // | // | ||||||
| // Usage: | // Usage: | ||||||
| // import( | // import( | ||||||
| //   _ "github.com/beego/beego/v2/session/mysql" | //   _ "github.com/beego/beego/v2/server/web/session/mysql" | ||||||
| //   "github.com/beego/beego/v2/session" | //   "github.com/beego/beego/v2/server/web/session" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| //	func init() { | //	func init() { | ||||||
| @ -44,11 +44,11 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 
 | 
 | ||||||
| 	"github.com/beego/beego/v2/adapter/session" |  | ||||||
| 	"github.com/beego/beego/v2/server/web/session/mysql" |  | ||||||
| 
 |  | ||||||
| 	// import mysql driver | 	// import mysql driver | ||||||
| 	_ "github.com/go-sql-driver/mysql" | 	_ "github.com/go-sql-driver/mysql" | ||||||
|  | 
 | ||||||
|  | 	"github.com/beego/beego/v2/adapter/session" | ||||||
|  | 	"github.com/beego/beego/v2/server/web/session/mysql" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( | var ( | ||||||
|  | |||||||
| @ -38,8 +38,8 @@ | |||||||
| // | // | ||||||
| // Usage: | // Usage: | ||||||
| // import( | // import( | ||||||
| //   _ "github.com/beego/beego/v2/session/postgresql" | //   _ "github.com/beego/beego/v2/server/web/session/postgresql" | ||||||
| //   "github.com/beego/beego/v2/session" | //   "github.com/beego/beego/v2/server/web/session" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| //	func init() { | //	func init() { | ||||||
| @ -54,10 +54,10 @@ import ( | |||||||
| 	"context" | 	"context" | ||||||
| 	"net/http" | 	"net/http" | ||||||
| 
 | 
 | ||||||
| 	"github.com/beego/beego/v2/adapter/session" |  | ||||||
| 	// import postgresql Driver | 	// import postgresql Driver | ||||||
| 	_ "github.com/lib/pq" | 	_ "github.com/lib/pq" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/beego/beego/v2/adapter/session" | ||||||
| 	"github.com/beego/beego/v2/server/web/session/postgres" | 	"github.com/beego/beego/v2/server/web/session/postgres" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -20,8 +20,8 @@ | |||||||
| // | // | ||||||
| // Usage: | // Usage: | ||||||
| // import( | // import( | ||||||
| //   _ "github.com/beego/beego/v2/session/redis" | //   _ "github.com/beego/beego/v2/server/web/session/redis" | ||||||
| //   "github.com/beego/beego/v2/session" | //   "github.com/beego/beego/v2/server/web/session" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| // 	func init() { | // 	func init() { | ||||||
| @ -37,7 +37,6 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 
 | 
 | ||||||
| 	"github.com/beego/beego/v2/adapter/session" | 	"github.com/beego/beego/v2/adapter/session" | ||||||
| 
 |  | ||||||
| 	beeRedis "github.com/beego/beego/v2/server/web/session/redis" | 	beeRedis "github.com/beego/beego/v2/server/web/session/redis" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -20,8 +20,8 @@ | |||||||
| // | // | ||||||
| // Usage: | // Usage: | ||||||
| // import( | // import( | ||||||
| //   _ "github.com/beego/beego/v2/session/redis_cluster" | //   _ "github.com/beego/beego/v2/server/web/session/redis_cluster" | ||||||
| //   "github.com/beego/beego/v2/session" | //   "github.com/beego/beego/v2/server/web/session" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| //	func init() { | //	func init() { | ||||||
|  | |||||||
| @ -20,8 +20,8 @@ | |||||||
| // | // | ||||||
| // Usage: | // Usage: | ||||||
| // import( | // import( | ||||||
| //   _ "github.com/beego/beego/v2/session/redis_sentinel" | //   _ "github.com/beego/beego/v2/server/web/session/redis_sentinel" | ||||||
| //   "github.com/beego/beego/v2/session" | //   "github.com/beego/beego/v2/server/web/session" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| //	func init() { | //	func init() { | ||||||
| @ -37,7 +37,6 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 
 | 
 | ||||||
| 	"github.com/beego/beego/v2/adapter/session" | 	"github.com/beego/beego/v2/adapter/session" | ||||||
| 
 |  | ||||||
| 	sentinel "github.com/beego/beego/v2/server/web/session/redis_sentinel" | 	sentinel "github.com/beego/beego/v2/server/web/session/redis_sentinel" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -5,6 +5,8 @@ import ( | |||||||
| 	"net/http/httptest" | 	"net/http/httptest" | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | 
 | ||||||
| 	"github.com/beego/beego/v2/adapter/session" | 	"github.com/beego/beego/v2/adapter/session" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| @ -19,72 +21,55 @@ func TestRedisSentinel(t *testing.T) { | |||||||
| 		ProviderConfig:  "127.0.0.1:6379,100,,0,master", | 		ProviderConfig:  "127.0.0.1:6379,100,,0,master", | ||||||
| 	} | 	} | ||||||
| 	globalSessions, e := session.NewManager("redis_sentinel", sessionConfig) | 	globalSessions, e := session.NewManager("redis_sentinel", sessionConfig) | ||||||
|  | 
 | ||||||
| 	if e != nil { | 	if e != nil { | ||||||
| 		t.Log(e) | 		t.Log(e) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	// todo test if e==nil | 
 | ||||||
| 	go globalSessions.GC() | 	go globalSessions.GC() | ||||||
| 
 | 
 | ||||||
| 	r, _ := http.NewRequest("GET", "/", nil) | 	r, _ := http.NewRequest("GET", "/", nil) | ||||||
| 	w := httptest.NewRecorder() | 	w := httptest.NewRecorder() | ||||||
| 
 | 
 | ||||||
| 	sess, err := globalSessions.SessionStart(w, r) | 	sess, err := globalSessions.SessionStart(w, r) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal("session start failed:", err) |  | ||||||
| 	} |  | ||||||
| 	defer sess.SessionRelease(w) | 	defer sess.SessionRelease(w) | ||||||
| 
 | 
 | ||||||
| 	// SET AND GET | 	// SET AND GET | ||||||
| 	err = sess.Set("username", "astaxie") | 	err = sess.Set("username", "astaxie") | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal("set username failed:", err) |  | ||||||
| 	} |  | ||||||
| 	username := sess.Get("username") | 	username := sess.Get("username") | ||||||
| 	if username != "astaxie" { | 	assert.Equal(t, "astaxie", username) | ||||||
| 		t.Fatal("get username failed") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// DELETE | 	// DELETE | ||||||
| 	err = sess.Delete("username") | 	err = sess.Delete("username") | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal("delete username failed:", err) | 
 | ||||||
| 	} |  | ||||||
| 	username = sess.Get("username") | 	username = sess.Get("username") | ||||||
| 	if username != nil { | 	assert.Nil(t, username) | ||||||
| 		t.Fatal("delete username failed") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// FLUSH | 	// FLUSH | ||||||
| 	err = sess.Set("username", "astaxie") | 	err = sess.Set("username", "astaxie") | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal("set failed:", err) | 
 | ||||||
| 	} |  | ||||||
| 	err = sess.Set("password", "1qaz2wsx") | 	err = sess.Set("password", "1qaz2wsx") | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal("set failed:", err) | 
 | ||||||
| 	} |  | ||||||
| 	username = sess.Get("username") | 	username = sess.Get("username") | ||||||
| 	if username != "astaxie" { | 	assert.Equal(t, "astaxie", username) | ||||||
| 		t.Fatal("get username failed") | 
 | ||||||
| 	} |  | ||||||
| 	password := sess.Get("password") | 	password := sess.Get("password") | ||||||
| 	if password != "1qaz2wsx" { | 	assert.Equal(t, "1qaz2wsx", password) | ||||||
| 		t.Fatal("get password failed") | 
 | ||||||
| 	} |  | ||||||
| 	err = sess.Flush() | 	err = sess.Flush() | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal("flush failed:", err) | 
 | ||||||
| 	} |  | ||||||
| 	username = sess.Get("username") | 	username = sess.Get("username") | ||||||
| 	if username != nil { | 	assert.Nil(t, username) | ||||||
| 		t.Fatal("flush failed") | 
 | ||||||
| 	} |  | ||||||
| 	password = sess.Get("password") | 	password = sess.Get("password") | ||||||
| 	if password != nil { | 	assert.Nil(t, password) | ||||||
| 		t.Fatal("flush failed") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	sess.SessionRelease(w) | 	sess.SessionRelease(w) | ||||||
| 
 |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -22,6 +22,8 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | const setCookieKey = "Set-Cookie" | ||||||
|  | 
 | ||||||
| func TestCookie(t *testing.T) { | func TestCookie(t *testing.T) { | ||||||
| 	config := `{"cookieName":"gosessionid","enableSetCookie":false,"gclifetime":3600,"ProviderConfig":"{\"cookieName\":\"gosessionid\",\"securityKey\":\"beegocookiehashkey\"}"}` | 	config := `{"cookieName":"gosessionid","enableSetCookie":false,"gclifetime":3600,"ProviderConfig":"{\"cookieName\":\"gosessionid\",\"securityKey\":\"beegocookiehashkey\"}"}` | ||||||
| 	conf := new(ManagerConfig) | 	conf := new(ManagerConfig) | ||||||
| @ -46,7 +48,8 @@ func TestCookie(t *testing.T) { | |||||||
| 		t.Fatal("get username error") | 		t.Fatal("get username error") | ||||||
| 	} | 	} | ||||||
| 	sess.SessionRelease(w) | 	sess.SessionRelease(w) | ||||||
| 	if cookiestr := w.Header().Get("Set-Cookie"); cookiestr == "" { | 
 | ||||||
|  | 	if cookiestr := w.Header().Get(setCookieKey); cookiestr == "" { | ||||||
| 		t.Fatal("setcookie error") | 		t.Fatal("setcookie error") | ||||||
| 	} else { | 	} else { | ||||||
| 		parts := strings.Split(strings.TrimSpace(cookiestr), ";") | 		parts := strings.Split(strings.TrimSpace(cookiestr), ";") | ||||||
| @ -79,7 +82,7 @@ func TestDestorySessionCookie(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	// request again ,will get same sesssion id . | 	// request again ,will get same sesssion id . | ||||||
| 	r1, _ := http.NewRequest("GET", "/", nil) | 	r1, _ := http.NewRequest("GET", "/", nil) | ||||||
| 	r1.Header.Set("Cookie", w.Header().Get("Set-Cookie")) | 	r1.Header.Set("Cookie", w.Header().Get(setCookieKey)) | ||||||
| 	w = httptest.NewRecorder() | 	w = httptest.NewRecorder() | ||||||
| 	newSession, err := globalSessions.SessionStart(w, r1) | 	newSession, err := globalSessions.SessionStart(w, r1) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| @ -92,7 +95,7 @@ func TestDestorySessionCookie(t *testing.T) { | |||||||
| 	// After destroy session , will get a new session id . | 	// After destroy session , will get a new session id . | ||||||
| 	globalSessions.SessionDestroy(w, r1) | 	globalSessions.SessionDestroy(w, r1) | ||||||
| 	r2, _ := http.NewRequest("GET", "/", nil) | 	r2, _ := http.NewRequest("GET", "/", nil) | ||||||
| 	r2.Header.Set("Cookie", w.Header().Get("Set-Cookie")) | 	r2.Header.Set("Cookie", w.Header().Get(setCookieKey)) | ||||||
| 
 | 
 | ||||||
| 	w = httptest.NewRecorder() | 	w = httptest.NewRecorder() | ||||||
| 	newSession, err = globalSessions.SessionStart(w, r2) | 	newSession, err = globalSessions.SessionStart(w, r2) | ||||||
|  | |||||||
| @ -22,15 +22,15 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const sid = "Session_id" | const ( | ||||||
| const sidNew = "Session_id_new" | 	sid         = "Session_id" | ||||||
| const sessionPath = "./_session_runtime" | 	sidNew      = "Session_id_new" | ||||||
| 
 | 	sessionPath = "./_session_runtime" | ||||||
| var ( |  | ||||||
| 	mutex sync.Mutex |  | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestFileProvider_SessionExist(t *testing.T) { | var mutex sync.Mutex | ||||||
|  | 
 | ||||||
|  | func TestFileProviderSessionExist(t *testing.T) { | ||||||
| 	mutex.Lock() | 	mutex.Lock() | ||||||
| 	defer mutex.Unlock() | 	defer mutex.Unlock() | ||||||
| 	os.RemoveAll(sessionPath) | 	os.RemoveAll(sessionPath) | ||||||
| @ -53,7 +53,7 @@ func TestFileProvider_SessionExist(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestFileProvider_SessionExist2(t *testing.T) { | func TestFileProviderSessionExist2(t *testing.T) { | ||||||
| 	mutex.Lock() | 	mutex.Lock() | ||||||
| 	defer mutex.Unlock() | 	defer mutex.Unlock() | ||||||
| 	os.RemoveAll(sessionPath) | 	os.RemoveAll(sessionPath) | ||||||
| @ -75,7 +75,7 @@ func TestFileProvider_SessionExist2(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestFileProvider_SessionRead(t *testing.T) { | func TestFileProviderSessionRead(t *testing.T) { | ||||||
| 	mutex.Lock() | 	mutex.Lock() | ||||||
| 	defer mutex.Unlock() | 	defer mutex.Unlock() | ||||||
| 	os.RemoveAll(sessionPath) | 	os.RemoveAll(sessionPath) | ||||||
| @ -97,7 +97,7 @@ func TestFileProvider_SessionRead(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestFileProvider_SessionRead1(t *testing.T) { | func TestFileProviderSessionRead1(t *testing.T) { | ||||||
| 	mutex.Lock() | 	mutex.Lock() | ||||||
| 	defer mutex.Unlock() | 	defer mutex.Unlock() | ||||||
| 	os.RemoveAll(sessionPath) | 	os.RemoveAll(sessionPath) | ||||||
| @ -117,7 +117,7 @@ func TestFileProvider_SessionRead1(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestFileProvider_SessionAll(t *testing.T) { | func TestFileProviderSessionAll(t *testing.T) { | ||||||
| 	mutex.Lock() | 	mutex.Lock() | ||||||
| 	defer mutex.Unlock() | 	defer mutex.Unlock() | ||||||
| 	os.RemoveAll(sessionPath) | 	os.RemoveAll(sessionPath) | ||||||
| @ -140,7 +140,7 @@ func TestFileProvider_SessionAll(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestFileProvider_SessionRegenerate(t *testing.T) { | func TestFileProviderSessionRegenerate(t *testing.T) { | ||||||
| 	mutex.Lock() | 	mutex.Lock() | ||||||
| 	defer mutex.Unlock() | 	defer mutex.Unlock() | ||||||
| 	os.RemoveAll(sessionPath) | 	os.RemoveAll(sessionPath) | ||||||
| @ -172,7 +172,7 @@ func TestFileProvider_SessionRegenerate(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestFileProvider_SessionDestroy(t *testing.T) { | func TestFileProviderSessionDestroy(t *testing.T) { | ||||||
| 	mutex.Lock() | 	mutex.Lock() | ||||||
| 	defer mutex.Unlock() | 	defer mutex.Unlock() | ||||||
| 	os.RemoveAll(sessionPath) | 	os.RemoveAll(sessionPath) | ||||||
| @ -200,7 +200,7 @@ func TestFileProvider_SessionDestroy(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestFileProvider_SessionGC(t *testing.T) { | func TestFileProviderSessionGC(t *testing.T) { | ||||||
| 	mutex.Lock() | 	mutex.Lock() | ||||||
| 	defer mutex.Unlock() | 	defer mutex.Unlock() | ||||||
| 	os.RemoveAll(sessionPath) | 	os.RemoveAll(sessionPath) | ||||||
| @ -226,7 +226,7 @@ func TestFileProvider_SessionGC(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestFileSessionStore_Set(t *testing.T) { | func TestFileSessionStoreSet(t *testing.T) { | ||||||
| 	mutex.Lock() | 	mutex.Lock() | ||||||
| 	defer mutex.Unlock() | 	defer mutex.Unlock() | ||||||
| 	os.RemoveAll(sessionPath) | 	os.RemoveAll(sessionPath) | ||||||
| @ -245,7 +245,7 @@ func TestFileSessionStore_Set(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestFileSessionStore_Get(t *testing.T) { | func TestFileSessionStoreGet(t *testing.T) { | ||||||
| 	mutex.Lock() | 	mutex.Lock() | ||||||
| 	defer mutex.Unlock() | 	defer mutex.Unlock() | ||||||
| 	os.RemoveAll(sessionPath) | 	os.RemoveAll(sessionPath) | ||||||
| @ -266,7 +266,7 @@ func TestFileSessionStore_Get(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestFileSessionStore_Delete(t *testing.T) { | func TestFileSessionStoreDelete(t *testing.T) { | ||||||
| 	mutex.Lock() | 	mutex.Lock() | ||||||
| 	defer mutex.Unlock() | 	defer mutex.Unlock() | ||||||
| 	os.RemoveAll(sessionPath) | 	os.RemoveAll(sessionPath) | ||||||
| @ -289,7 +289,7 @@ func TestFileSessionStore_Delete(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestFileSessionStore_Flush(t *testing.T) { | func TestFileSessionStoreFlush(t *testing.T) { | ||||||
| 	mutex.Lock() | 	mutex.Lock() | ||||||
| 	defer mutex.Unlock() | 	defer mutex.Unlock() | ||||||
| 	os.RemoveAll(sessionPath) | 	os.RemoveAll(sessionPath) | ||||||
| @ -313,7 +313,7 @@ func TestFileSessionStore_Flush(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestFileSessionStore_SessionID(t *testing.T) { | func TestFileSessionStoreSessionID(t *testing.T) { | ||||||
| 	mutex.Lock() | 	mutex.Lock() | ||||||
| 	defer mutex.Unlock() | 	defer mutex.Unlock() | ||||||
| 	os.RemoveAll(sessionPath) | 	os.RemoveAll(sessionPath) | ||||||
|  | |||||||
| @ -18,7 +18,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func Test_gob(t *testing.T) { | func TestGob(t *testing.T) { | ||||||
| 	a := make(map[interface{}]interface{}) | 	a := make(map[interface{}]interface{}) | ||||||
| 	a["username"] = "astaxie" | 	a["username"] = "astaxie" | ||||||
| 	a[12] = 234 | 	a[12] = 234 | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ | |||||||
| // | // | ||||||
| // Usage: | // Usage: | ||||||
| // import( | // import( | ||||||
| //   "github.com/beego/beego/v2/session" | //   "github.com/beego/beego/v2/server/web/session" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| //	func init() { | //	func init() { | ||||||
|  | |||||||
| @ -5,7 +5,6 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 
 | 
 | ||||||
| 	"github.com/beego/beego/v2/adapter/session" | 	"github.com/beego/beego/v2/adapter/session" | ||||||
| 
 |  | ||||||
| 	beeSsdb "github.com/beego/beego/v2/server/web/session/ssdb" | 	beeSsdb "github.com/beego/beego/v2/server/web/session/ssdb" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -118,7 +118,6 @@ func AssetsJs(text string) template.HTML { | |||||||
| 
 | 
 | ||||||
| // AssetsCSS returns stylesheet link tag with src string. | // AssetsCSS returns stylesheet link tag with src string. | ||||||
| func AssetsCSS(text string) template.HTML { | func AssetsCSS(text string) template.HTML { | ||||||
| 
 |  | ||||||
| 	text = "<link href=\"" + text + "\" rel=\"stylesheet\" />" | 	text = "<link href=\"" + text + "\" rel=\"stylesheet\" />" | ||||||
| 
 | 
 | ||||||
| 	return template.HTML(text) | 	return template.HTML(text) | ||||||
|  | |||||||
| @ -19,19 +19,15 @@ import ( | |||||||
| 	"net/url" | 	"net/url" | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestSubstr(t *testing.T) { | func TestSubstr(t *testing.T) { | ||||||
| 	s := `012345` | 	s := `012345` | ||||||
| 	if Substr(s, 0, 2) != "01" { | 	assert.Equal(t, "01", Substr(s, 0, 2)) | ||||||
| 		t.Error("should be equal") | 	assert.Equal(t, "012345", Substr(s, 0, 100)) | ||||||
| 	} | 	assert.Equal(t, "012345", Substr(s, 12, 100)) | ||||||
| 	if Substr(s, 0, 100) != "012345" { |  | ||||||
| 		t.Error("should be equal") |  | ||||||
| 	} |  | ||||||
| 	if Substr(s, 12, 100) != "012345" { |  | ||||||
| 		t.Error("should be equal") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestHtml2str(t *testing.T) { | func TestHtml2str(t *testing.T) { | ||||||
| @ -39,73 +35,50 @@ func TestHtml2str(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| 	\n` | 	\n` | ||||||
| 	if HTML2str(h) != "123\\n\n\\n" { | 	assert.Equal(t, "123\\n\n\\n", HTML2str(h)) | ||||||
| 		t.Error("should be equal") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestDateFormat(t *testing.T) { | func TestDateFormat(t *testing.T) { | ||||||
| 	ts := "Mon, 01 Jul 2013 13:27:42 CST" | 	ts := "Mon, 01 Jul 2013 13:27:42 CST" | ||||||
| 	tt, _ := time.Parse(time.RFC1123, ts) | 	tt, _ := time.Parse(time.RFC1123, ts) | ||||||
| 
 | 
 | ||||||
| 	if ss := DateFormat(tt, "2006-01-02 15:04:05"); ss != "2013-07-01 13:27:42" { | 	assert.Equal(t, "2013-07-01 13:27:42", DateFormat(tt, "2006-01-02 15:04:05")) | ||||||
| 		t.Errorf("2013-07-01 13:27:42 does not equal %v", ss) |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestDate(t *testing.T) { | func TestDate(t *testing.T) { | ||||||
| 	ts := "Mon, 01 Jul 2013 13:27:42 CST" | 	ts := "Mon, 01 Jul 2013 13:27:42 CST" | ||||||
| 	tt, _ := time.Parse(time.RFC1123, ts) | 	tt, _ := time.Parse(time.RFC1123, ts) | ||||||
| 
 | 
 | ||||||
| 	if ss := Date(tt, "Y-m-d H:i:s"); ss != "2013-07-01 13:27:42" { | 	assert.Equal(t, "2013-07-01 13:27:42", Date(tt, "Y-m-d H:i:s")) | ||||||
| 		t.Errorf("2013-07-01 13:27:42 does not equal %v", ss) | 
 | ||||||
| 	} | 	assert.Equal(t, "13-7-1 01:27:42 PM", Date(tt, "y-n-j h:i:s A")) | ||||||
| 	if ss := Date(tt, "y-n-j h:i:s A"); ss != "13-7-1 01:27:42 PM" { | 	assert.Equal(t, "Mon, 01 Jul 2013 1:27:42 pm", Date(tt, "D, d M Y g:i:s a")) | ||||||
| 		t.Errorf("13-7-1 01:27:42 PM does not equal %v", ss) | 	assert.Equal(t, "Monday, 01 July 2013 13:27:42", Date(tt, "l, d F Y G:i:s")) | ||||||
| 	} |  | ||||||
| 	if ss := Date(tt, "D, d M Y g:i:s a"); ss != "Mon, 01 Jul 2013 1:27:42 pm" { |  | ||||||
| 		t.Errorf("Mon, 01 Jul 2013 1:27:42 pm does not equal %v", ss) |  | ||||||
| 	} |  | ||||||
| 	if ss := Date(tt, "l, d F Y G:i:s"); ss != "Monday, 01 July 2013 13:27:42" { |  | ||||||
| 		t.Errorf("Monday, 01 July 2013 13:27:42 does not equal %v", ss) |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestCompareRelated(t *testing.T) { | func TestCompareRelated(t *testing.T) { | ||||||
| 	if !Compare("abc", "abc") { | 	assert.True(t, Compare("abc", "abc")) | ||||||
| 		t.Error("should be equal") | 
 | ||||||
| 	} | 	assert.False(t, Compare("abc", "aBc")) | ||||||
| 	if Compare("abc", "aBc") { | 
 | ||||||
| 		t.Error("should be not equal") | 	assert.True(t, Compare("1", 1)) | ||||||
| 	} | 
 | ||||||
| 	if !Compare("1", 1) { | 	assert.False(t, CompareNot("abc", "abc")) | ||||||
| 		t.Error("should be equal") | 
 | ||||||
| 	} | 	assert.True(t, CompareNot("abc", "aBc")) | ||||||
| 	if CompareNot("abc", "abc") { | 	assert.True(t, NotNil("a string")) | ||||||
| 		t.Error("should be equal") |  | ||||||
| 	} |  | ||||||
| 	if !CompareNot("abc", "aBc") { |  | ||||||
| 		t.Error("should be not equal") |  | ||||||
| 	} |  | ||||||
| 	if !NotNil("a string") { |  | ||||||
| 		t.Error("should not be nil") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestHtmlquote(t *testing.T) { | func TestHtmlquote(t *testing.T) { | ||||||
| 	h := `<' ”“&">` | 	h := `<' ”“&">` | ||||||
| 	s := `<' ”“&">` | 	s := `<' ”“&">` | ||||||
| 	if Htmlquote(s) != h { | 	assert.Equal(t, h, Htmlquote(s)) | ||||||
| 		t.Error("should be equal") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestHtmlunquote(t *testing.T) { | func TestHtmlunquote(t *testing.T) { | ||||||
| 	h := `<' ”“&">` | 	h := `<' ”“&">` | ||||||
| 	s := `<' ”“&">` | 	s := `<' ”“&">` | ||||||
| 	if Htmlunquote(h) != s { | 	assert.Equal(t, s, Htmlunquote(h)) | ||||||
| 		t.Error("should be equal") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestParseForm(t *testing.T) { | func TestParseForm(t *testing.T) { | ||||||
| @ -148,55 +121,42 @@ func TestParseForm(t *testing.T) { | |||||||
| 		"hobby":        []string{"", "Basketball", "Football"}, | 		"hobby":        []string{"", "Basketball", "Football"}, | ||||||
| 		"memo":         []string{"nothing"}, | 		"memo":         []string{"nothing"}, | ||||||
| 	} | 	} | ||||||
| 	if err := ParseForm(form, u); err == nil { | 
 | ||||||
| 		t.Fatal("nothing will be changed") | 	assert.NotNil(t, ParseForm(form, u)) | ||||||
| 	} | 
 | ||||||
| 	if err := ParseForm(form, &u); err != nil { | 	assert.Nil(t, ParseForm(form, &u)) | ||||||
| 		t.Fatal(err) | 
 | ||||||
| 	} | 	assert.Equal(t, 0, u.ID) | ||||||
| 	if u.ID != 0 { | 
 | ||||||
| 		t.Errorf("ID should equal 0 but got %v", u.ID) | 	assert.Equal(t, 0, len(u.tag)) | ||||||
| 	} | 
 | ||||||
| 	if len(u.tag) != 0 { | 	assert.Equal(t, "test", u.Name) | ||||||
| 		t.Errorf("tag's length should equal 0 but got %v", len(u.tag)) | 
 | ||||||
| 	} | 	assert.Equal(t, 40, u.Age) | ||||||
| 	if u.Name.(string) != "test" { | 
 | ||||||
| 		t.Errorf("Name should equal `test` but got `%v`", u.Name.(string)) | 	assert.Equal(t, "test@gmail.com", u.Email) | ||||||
| 	} | 
 | ||||||
| 	if u.Age != 40 { | 	assert.Equal(t, "I am an engineer!", u.Intro) | ||||||
| 		t.Errorf("Age should equal 40 but got %v", u.Age) | 
 | ||||||
| 	} | 	assert.True(t, u.StrBool) | ||||||
| 	if u.Email != "test@gmail.com" { | 
 | ||||||
| 		t.Errorf("Email should equal `test@gmail.com` but got `%v`", u.Email) |  | ||||||
| 	} |  | ||||||
| 	if u.Intro != "I am an engineer!" { |  | ||||||
| 		t.Errorf("Intro should equal `I am an engineer!` but got `%v`", u.Intro) |  | ||||||
| 	} |  | ||||||
| 	if !u.StrBool { |  | ||||||
| 		t.Errorf("strboll should equal `true`, but got `%v`", u.StrBool) |  | ||||||
| 	} |  | ||||||
| 	y, m, d := u.Date.Date() | 	y, m, d := u.Date.Date() | ||||||
| 	if y != 2014 || m.String() != "November" || d != 12 { | 
 | ||||||
| 		t.Errorf("Date should equal `2014-11-12`, but got `%v`", u.Date.String()) | 	assert.Equal(t, 2014, y) | ||||||
| 	} | 	assert.Equal(t, "November", m.String()) | ||||||
| 	if u.Organization != "beego" { | 	assert.Equal(t, 12, d) | ||||||
| 		t.Errorf("Organization should equal `beego`, but got `%v`", u.Organization) | 
 | ||||||
| 	} | 	assert.Equal(t, "beego", u.Organization) | ||||||
| 	if u.Title != "CXO" { | 
 | ||||||
| 		t.Errorf("Title should equal `CXO`, but got `%v`", u.Title) | 	assert.Equal(t, "CXO", u.Title) | ||||||
| 	} | 
 | ||||||
| 	if u.Hobby[0] != "" { | 	assert.Equal(t, "", u.Hobby[0]) | ||||||
| 		t.Errorf("Hobby should equal ``, but got `%v`", u.Hobby[0]) | 
 | ||||||
| 	} | 	assert.Equal(t, "Basketball", u.Hobby[1]) | ||||||
| 	if u.Hobby[1] != "Basketball" { | 
 | ||||||
| 		t.Errorf("Hobby should equal `Basketball`, but got `%v`", u.Hobby[1]) | 	assert.Equal(t, "Football", u.Hobby[2]) | ||||||
| 	} | 
 | ||||||
| 	if u.Hobby[2] != "Football" { | 	assert.Equal(t, 0, len(u.Memo)) | ||||||
| 		t.Errorf("Hobby should equal `Football`, but got `%v`", u.Hobby[2]) |  | ||||||
| 	} |  | ||||||
| 	if len(u.Memo) != 0 { |  | ||||||
| 		t.Errorf("Memo's length should equal 0 but got %v", len(u.Memo)) |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestRenderForm(t *testing.T) { | func TestRenderForm(t *testing.T) { | ||||||
| @ -212,18 +172,14 @@ func TestRenderForm(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	u := user{Name: "test", Intro: "Some Text"} | 	u := user{Name: "test", Intro: "Some Text"} | ||||||
| 	output := RenderForm(u) | 	output := RenderForm(u) | ||||||
| 	if output != template.HTML("") { | 	assert.Equal(t, template.HTML(""), output) | ||||||
| 		t.Errorf("output should be empty but got %v", output) |  | ||||||
| 	} |  | ||||||
| 	output = RenderForm(&u) | 	output = RenderForm(&u) | ||||||
| 	result := template.HTML( | 	result := template.HTML( | ||||||
| 		`Name: <input name="username" type="text" value="test"></br>` + | 		`Name: <input name="username" type="text" value="test"></br>` + | ||||||
| 			`年龄:<input name="age" type="text" value="0"></br>` + | 			`年龄:<input name="age" type="text" value="0"></br>` + | ||||||
| 			`Sex: <input name="Sex" type="text" value=""></br>` + | 			`Sex: <input name="Sex" type="text" value=""></br>` + | ||||||
| 			`Intro: <textarea name="Intro">Some Text</textarea>`) | 			`Intro: <textarea name="Intro">Some Text</textarea>`) | ||||||
| 	if output != result { | 	assert.Equal(t, result, output) | ||||||
| 		t.Errorf("output should equal `%v` but got `%v`", result, output) |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestMapGet(t *testing.T) { | func TestMapGet(t *testing.T) { | ||||||
| @ -233,29 +189,17 @@ func TestMapGet(t *testing.T) { | |||||||
| 		"1": 2, | 		"1": 2, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if res, err := MapGet(m1, "a"); err == nil { | 	res, err := MapGet(m1, "a") | ||||||
| 		if res.(int64) != 1 { | 	assert.Nil(t, err) | ||||||
| 			t.Errorf("Should return 1, but return %v", res) | 	assert.Equal(t, int64(1), res) | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		t.Errorf("Error happens %v", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if res, err := MapGet(m1, "1"); err == nil { | 	res, err = MapGet(m1, "1") | ||||||
| 		if res.(int64) != 2 { | 	assert.Nil(t, err) | ||||||
| 			t.Errorf("Should return 2, but return %v", res) | 	assert.Equal(t, int64(2), res) | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		t.Errorf("Error happens %v", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if res, err := MapGet(m1, 1); err == nil { | 	res, err = MapGet(m1, 1) | ||||||
| 		if res.(int64) != 2 { | 	assert.Nil(t, err) | ||||||
| 			t.Errorf("Should return 2, but return %v", res) | 	assert.Equal(t, int64(2), res) | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		t.Errorf("Error happens %v", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test 2 level map | 	// test 2 level map | ||||||
| 	m2 := M{ | 	m2 := M{ | ||||||
| @ -264,13 +208,9 @@ func TestMapGet(t *testing.T) { | |||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if res, err := MapGet(m2, 1, 2); err == nil { | 	res, err = MapGet(m2, 1, 2) | ||||||
| 		if res.(float64) != 3.5 { | 	assert.Nil(t, err) | ||||||
| 			t.Errorf("Should return 3.5, but return %v", res) | 	assert.Equal(t, 3.5, res) | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		t.Errorf("Error happens %v", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test 5 level map | 	// test 5 level map | ||||||
| 	m5 := M{ | 	m5 := M{ | ||||||
| @ -285,20 +225,12 @@ func TestMapGet(t *testing.T) { | |||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if res, err := MapGet(m5, 1, 2, 3, 4, 5); err == nil { | 	res, err = MapGet(m5, 1, 2, 3, 4, 5) | ||||||
| 		if res.(float64) != 1.2 { | 	assert.Nil(t, err) | ||||||
| 			t.Errorf("Should return 1.2, but return %v", res) | 	assert.Equal(t, 1.2, res) | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		t.Errorf("Error happens %v", err) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// check whether element not exists in map | 	// check whether element not exists in map | ||||||
| 	if res, err := MapGet(m5, 5, 4, 3, 2, 1); err == nil { | 	res, err = MapGet(m5, 5, 4, 3, 2, 1) | ||||||
| 		if res != nil { | 	assert.Nil(t, err) | ||||||
| 			t.Errorf("Should return nil, but return %v", res) | 	assert.Nil(t, res) | ||||||
| 		} |  | ||||||
| 	} else { |  | ||||||
| 		t.Errorf("Error happens %v", err) |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -14,12 +14,7 @@ | |||||||
| 
 | 
 | ||||||
| package testing | package testing | ||||||
| 
 | 
 | ||||||
| import ( | import "github.com/beego/beego/v2/client/httplib/testing" | ||||||
| 	"github.com/beego/beego/v2/client/httplib/testing" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| var port = "" |  | ||||||
| var baseURL = "http://localhost:" |  | ||||||
| 
 | 
 | ||||||
| // TestHTTPRequest beego test request client | // TestHTTPRequest beego test request client | ||||||
| type TestHTTPRequest testing.TestHTTPRequest | type TestHTTPRequest testing.TestHTTPRequest | ||||||
|  | |||||||
| @ -16,19 +16,10 @@ package toolbox | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"io" | 	"io" | ||||||
| 	"os" |  | ||||||
| 	"time" |  | ||||||
| 
 | 
 | ||||||
| 	"github.com/beego/beego/v2/core/admin" | 	"github.com/beego/beego/v2/core/admin" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var startTime = time.Now() |  | ||||||
| var pid int |  | ||||||
| 
 |  | ||||||
| func init() { |  | ||||||
| 	pid = os.Getpid() |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| // ProcessInput parse input command string | // ProcessInput parse input command string | ||||||
| func ProcessInput(input string, w io.Writer) { | func ProcessInput(input string, w io.Writer) { | ||||||
| 	admin.ProcessInput(input, w) | 	admin.ProcessInput(input, w) | ||||||
|  | |||||||
| @ -21,13 +21,16 @@ import ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestStatics(t *testing.T) { | func TestStatics(t *testing.T) { | ||||||
| 	StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(2000)) | 	userApi := "/api/user" | ||||||
| 	StatisticsMap.AddStatistics("POST", "/api/user", "&admin.user", time.Duration(120000)) | 	post := "POST" | ||||||
| 	StatisticsMap.AddStatistics("GET", "/api/user", "&admin.user", time.Duration(13000)) | 	adminUser := "&admin.user" | ||||||
| 	StatisticsMap.AddStatistics("POST", "/api/admin", "&admin.user", time.Duration(14000)) | 	StatisticsMap.AddStatistics(post, userApi, adminUser, time.Duration(2000)) | ||||||
| 	StatisticsMap.AddStatistics("POST", "/api/user/astaxie", "&admin.user", time.Duration(12000)) | 	StatisticsMap.AddStatistics(post, userApi, adminUser, time.Duration(120000)) | ||||||
| 	StatisticsMap.AddStatistics("POST", "/api/user/xiemengjun", "&admin.user", time.Duration(13000)) | 	StatisticsMap.AddStatistics("GET", userApi, adminUser, time.Duration(13000)) | ||||||
| 	StatisticsMap.AddStatistics("DELETE", "/api/user", "&admin.user", time.Duration(1400)) | 	StatisticsMap.AddStatistics(post, "/api/admin", adminUser, time.Duration(14000)) | ||||||
|  | 	StatisticsMap.AddStatistics(post, "/api/user/astaxie", adminUser, time.Duration(12000)) | ||||||
|  | 	StatisticsMap.AddStatistics(post, "/api/user/xiemengjun", adminUser, time.Duration(13000)) | ||||||
|  | 	StatisticsMap.AddStatistics("DELETE", userApi, adminUser, time.Duration(1400)) | ||||||
| 	t.Log(StatisticsMap.GetMap()) | 	t.Log(StatisticsMap.GetMap()) | ||||||
| 
 | 
 | ||||||
| 	data := StatisticsMap.GetMapData() | 	data := StatisticsMap.GetMapData() | ||||||
|  | |||||||
| @ -80,7 +80,6 @@ type Task struct { | |||||||
| 
 | 
 | ||||||
| // NewTask add new task with name, time and func | // NewTask add new task with name, time and func | ||||||
| func NewTask(tname string, spec string, f TaskFunc) *Task { | func NewTask(tname string, spec string, f TaskFunc) *Task { | ||||||
| 
 |  | ||||||
| 	task := task.NewTask(tname, spec, func(ctx context.Context) error { | 	task := task.NewTask(tname, spec, func(ctx context.Context) error { | ||||||
| 		return f() | 		return f() | ||||||
| 	}) | 	}) | ||||||
| @ -98,7 +97,6 @@ func (t *Task) GetSpec() string { | |||||||
| 
 | 
 | ||||||
| // GetStatus get current task status | // GetStatus get current task status | ||||||
| func (t *Task) GetStatus() string { | func (t *Task) GetStatus() string { | ||||||
| 
 |  | ||||||
| 	t.initDelegate() | 	t.initDelegate() | ||||||
| 
 | 
 | ||||||
| 	return t.delegate.GetStatus(context.Background()) | 	return t.delegate.GetStatus(context.Background()) | ||||||
| @ -222,7 +220,6 @@ type MapSorter task.MapSorter | |||||||
| 
 | 
 | ||||||
| // NewMapSorter create new tasker map | // NewMapSorter create new tasker map | ||||||
| func NewMapSorter(m map[string]Tasker) *MapSorter { | func NewMapSorter(m map[string]Tasker) *MapSorter { | ||||||
| 
 |  | ||||||
| 	newTaskerMap := make(map[string]task.Tasker, len(m)) | 	newTaskerMap := make(map[string]task.Tasker, len(m)) | ||||||
| 
 | 
 | ||||||
| 	for key, value := range m { | 	for key, value := range m { | ||||||
| @ -249,6 +246,7 @@ func (ms *MapSorter) Less(i, j int) bool { | |||||||
| 	} | 	} | ||||||
| 	return ms.Vals[i].GetNext(context.Background()).Before(ms.Vals[j].GetNext(context.Background())) | 	return ms.Vals[i].GetNext(context.Background()).Before(ms.Vals[j].GetNext(context.Background())) | ||||||
| } | } | ||||||
|  | 
 | ||||||
| func (ms *MapSorter) Swap(i, j int) { | func (ms *MapSorter) Swap(i, j int) { | ||||||
| 	ms.Vals[i], ms.Vals[j] = ms.Vals[j], ms.Vals[i] | 	ms.Vals[i], ms.Vals[j] = ms.Vals[j], ms.Vals[i] | ||||||
| 	ms.Keys[i], ms.Keys[j] = ms.Keys[j], ms.Keys[i] | 	ms.Keys[i], ms.Keys[j] = ms.Keys[j], ms.Keys[i] | ||||||
| @ -289,3 +287,7 @@ func (o *oldToNewAdapter) SetPrev(ctx context.Context, t time.Time) { | |||||||
| func (o *oldToNewAdapter) GetPrev(ctx context.Context) time.Time { | func (o *oldToNewAdapter) GetPrev(ctx context.Context) time.Time { | ||||||
| 	return o.delegate.GetPrev() | 	return o.delegate.GetPrev() | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | func (o *oldToNewAdapter) GetTimeout(ctx context.Context) time.Duration { | ||||||
|  | 	return 0 | ||||||
|  | } | ||||||
|  | |||||||
| @ -16,9 +16,8 @@ package adapter | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"github.com/beego/beego/v2/adapter/context" | 	"github.com/beego/beego/v2/adapter/context" | ||||||
| 	beecontext "github.com/beego/beego/v2/server/web/context" |  | ||||||
| 
 |  | ||||||
| 	"github.com/beego/beego/v2/server/web" | 	"github.com/beego/beego/v2/server/web" | ||||||
|  | 	beecontext "github.com/beego/beego/v2/server/web/context" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Tree has three elements: FixRouter/wildcard/leaves | // Tree has three elements: FixRouter/wildcard/leaves | ||||||
|  | |||||||
| @ -7,8 +7,8 @@ package controllers | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"github.com/beego/beego/v2" | 	"github.com/beego/beego/v2" | ||||||
| 	"github.com/beego/beego/v2/cache" | 	"github.com/beego/beego/v2/client/cache" | ||||||
| 	"github.com/beego/beego/v2/utils/captcha" | 	"github.com/beego/beego/v2/server/web/captcha" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var cpt *captcha.Captcha | var cpt *captcha.Captcha | ||||||
|  | |||||||
| @ -20,8 +20,8 @@ | |||||||
| // | // | ||||||
| // import ( | // import ( | ||||||
| // 	"github.com/beego/beego/v2" | // 	"github.com/beego/beego/v2" | ||||||
| // 	"github.com/beego/beego/v2/cache" | // 	"github.com/beego/beego/v2/client/cache" | ||||||
| // 	"github.com/beego/beego/v2/utils/captcha" | // 	"github.com/beego/beego/v2/server/web/captcha" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| // var cpt *captcha.Captcha | // var cpt *captcha.Captcha | ||||||
| @ -63,16 +63,13 @@ import ( | |||||||
| 	"net/http" | 	"net/http" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/beego/beego/v2/server/web/captcha" |  | ||||||
| 	beecontext "github.com/beego/beego/v2/server/web/context" |  | ||||||
| 
 |  | ||||||
| 	"github.com/beego/beego/v2/adapter/cache" | 	"github.com/beego/beego/v2/adapter/cache" | ||||||
| 	"github.com/beego/beego/v2/adapter/context" | 	"github.com/beego/beego/v2/adapter/context" | ||||||
|  | 	"github.com/beego/beego/v2/server/web/captcha" | ||||||
|  | 	beecontext "github.com/beego/beego/v2/server/web/context" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( | var defaultChars = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} | ||||||
| 	defaultChars = []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9} |  | ||||||
| ) |  | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
| 	// default captcha attributes | 	// default captcha attributes | ||||||
|  | |||||||
| @ -28,8 +28,8 @@ func TestPrint(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestPrintPoint(t *testing.T) { | func TestPrintPoint(t *testing.T) { | ||||||
| 	var v1 = new(mytype) | 	v1 := new(mytype) | ||||||
| 	var v2 = new(mytype) | 	v2 := new(mytype) | ||||||
| 
 | 
 | ||||||
| 	v1.prev = nil | 	v1.prev = nil | ||||||
| 	v1.next = v2 | 	v1.next = v2 | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ In your beego.Controller: | |||||||
| 
 | 
 | ||||||
|  package controllers |  package controllers | ||||||
| 
 | 
 | ||||||
|  import "github.com/beego/beego/v2/utils/pagination" |  import "github.com/beego/beego/v2/server/web/pagination" | ||||||
| 
 | 
 | ||||||
|  type PostsController struct { |  type PostsController struct { | ||||||
|    beego.Controller |    beego.Controller | ||||||
|  | |||||||
| @ -16,7 +16,7 @@ package utils | |||||||
| 
 | 
 | ||||||
| import "testing" | import "testing" | ||||||
| 
 | 
 | ||||||
| func TestRand_01(t *testing.T) { | func TestRand01(t *testing.T) { | ||||||
| 	bs0 := RandomCreateBytes(16) | 	bs0 := RandomCreateBytes(16) | ||||||
| 	bs1 := RandomCreateBytes(16) | 	bs1 := RandomCreateBytes(16) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ import ( | |||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| type reducetype func(interface{}) interface{} | type reducetype func(interface{}) interface{} | ||||||
|  | 
 | ||||||
| type filtertype func(interface{}) bool | type filtertype func(interface{}) bool | ||||||
| 
 | 
 | ||||||
| // InSlice checks given string in string slice or not. | // InSlice checks given string in string slice or not. | ||||||
|  | |||||||
| @ -27,9 +27,7 @@ const ( | |||||||
| 	LabelTag = validation.LabelTag | 	LabelTag = validation.LabelTag | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var ( | var ErrInt64On32 = validation.ErrInt64On32 | ||||||
| 	ErrInt64On32 = validation.ErrInt64On32 |  | ||||||
| ) |  | ||||||
| 
 | 
 | ||||||
| // CustomFunc is for custom validate function | // CustomFunc is for custom validate function | ||||||
| type CustomFunc func(v *Validation, obj interface{}, key string) | type CustomFunc func(v *Validation, obj interface{}, key string) | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ | |||||||
| // Package validation for validations | // Package validation for validations | ||||||
| // | // | ||||||
| //	import ( | //	import ( | ||||||
| //		"github.com/beego/beego/v2/validation" | //		"github.com/beego/beego/v2/core/validation" | ||||||
| //		"log" | //		"log" | ||||||
| //	) | //	) | ||||||
| // | // | ||||||
|  | |||||||
| @ -18,131 +18,82 @@ import ( | |||||||
| 	"regexp" | 	"regexp" | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestRequired(t *testing.T) { | func TestRequired(t *testing.T) { | ||||||
| 	valid := Validation{} | 	valid := Validation{} | ||||||
| 
 | 
 | ||||||
| 	if valid.Required(nil, "nil").Ok { | 	assert.False(t, valid.Required(nil, "nil").Ok) | ||||||
| 		t.Error("nil object should be false") | 	assert.True(t, valid.Required(true, "bool").Ok) | ||||||
| 	} | 
 | ||||||
| 	if !valid.Required(true, "bool").Ok { | 	assert.True(t, valid.Required(false, "bool").Ok) | ||||||
| 		t.Error("Bool value should always return true") | 	assert.False(t, valid.Required("", "string").Ok) | ||||||
| 	} | 	assert.False(t, valid.Required(" ", "string").Ok) | ||||||
| 	if !valid.Required(false, "bool").Ok { | 	assert.False(t, valid.Required("\n", "string").Ok) | ||||||
| 		t.Error("Bool value should always return true") | 
 | ||||||
| 	} | 	assert.True(t, valid.Required("astaxie", "string").Ok) | ||||||
| 	if valid.Required("", "string").Ok { | 	assert.False(t, valid.Required(0, "zero").Ok) | ||||||
| 		t.Error("\"'\" string should be false") | 
 | ||||||
| 	} | 	assert.True(t, valid.Required(1, "int").Ok) | ||||||
| 	if valid.Required(" ", "string").Ok { | 
 | ||||||
| 		t.Error("\" \" string should be false") // For #2361 | 	assert.True(t, valid.Required(time.Now(), "time").Ok) | ||||||
| 	} | 
 | ||||||
| 	if valid.Required("\n", "string").Ok { | 	assert.False(t, valid.Required([]string{}, "emptySlice").Ok) | ||||||
| 		t.Error("new line string should be false") // For #2361 | 
 | ||||||
| 	} | 	assert.True(t, valid.Required([]interface{}{"ok"}, "slice").Ok) | ||||||
| 	if !valid.Required("astaxie", "string").Ok { |  | ||||||
| 		t.Error("string should be true") |  | ||||||
| 	} |  | ||||||
| 	if valid.Required(0, "zero").Ok { |  | ||||||
| 		t.Error("Integer should not be equal 0") |  | ||||||
| 	} |  | ||||||
| 	if !valid.Required(1, "int").Ok { |  | ||||||
| 		t.Error("Integer except 0 should be true") |  | ||||||
| 	} |  | ||||||
| 	if !valid.Required(time.Now(), "time").Ok { |  | ||||||
| 		t.Error("time should be true") |  | ||||||
| 	} |  | ||||||
| 	if valid.Required([]string{}, "emptySlice").Ok { |  | ||||||
| 		t.Error("empty slice should be false") |  | ||||||
| 	} |  | ||||||
| 	if !valid.Required([]interface{}{"ok"}, "slice").Ok { |  | ||||||
| 		t.Error("slice should be true") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestMin(t *testing.T) { | func TestMin(t *testing.T) { | ||||||
| 	valid := Validation{} | 	valid := Validation{} | ||||||
| 
 | 
 | ||||||
| 	if valid.Min(-1, 0, "min0").Ok { | 	assert.False(t, valid.Min(-1, 0, "min0").Ok) | ||||||
| 		t.Error("-1 is less than the minimum value of 0 should be false") | 	assert.True(t, valid.Min(1, 0, "min0").Ok) | ||||||
| 	} |  | ||||||
| 	if !valid.Min(1, 0, "min0").Ok { |  | ||||||
| 		t.Error("1 is greater or equal than the minimum value of 0 should be true") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestMax(t *testing.T) { | func TestMax(t *testing.T) { | ||||||
| 	valid := Validation{} | 	valid := Validation{} | ||||||
| 
 | 
 | ||||||
| 	if valid.Max(1, 0, "max0").Ok { | 	assert.False(t, valid.Max(1, 0, "max0").Ok) | ||||||
| 		t.Error("1 is greater than the minimum value of 0 should be false") | 	assert.True(t, valid.Max(-1, 0, "max0").Ok) | ||||||
| 	} |  | ||||||
| 	if !valid.Max(-1, 0, "max0").Ok { |  | ||||||
| 		t.Error("-1 is less or equal than the maximum value of 0 should be true") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestRange(t *testing.T) { | func TestRange(t *testing.T) { | ||||||
| 	valid := Validation{} | 	valid := Validation{} | ||||||
| 
 | 
 | ||||||
| 	if valid.Range(-1, 0, 1, "range0_1").Ok { | 	assert.False(t, valid.Range(-1, 0, 1, "range0_1").Ok) | ||||||
| 		t.Error("-1 is between 0 and 1 should be false") | 
 | ||||||
| 	} | 	assert.True(t, valid.Range(1, 0, 1, "range0_1").Ok) | ||||||
| 	if !valid.Range(1, 0, 1, "range0_1").Ok { |  | ||||||
| 		t.Error("1 is between 0 and 1 should be true") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestMinSize(t *testing.T) { | func TestMinSize(t *testing.T) { | ||||||
| 	valid := Validation{} | 	valid := Validation{} | ||||||
| 
 | 
 | ||||||
| 	if valid.MinSize("", 1, "minSize1").Ok { | 	assert.False(t, valid.MinSize("", 1, "minSize1").Ok) | ||||||
| 		t.Error("the length of \"\" is less than the minimum value of 1 should be false") | 
 | ||||||
| 	} | 	assert.True(t, valid.MinSize("ok", 1, "minSize1").Ok) | ||||||
| 	if !valid.MinSize("ok", 1, "minSize1").Ok { | 	assert.False(t, valid.MinSize([]string{}, 1, "minSize1").Ok) | ||||||
| 		t.Error("the length of \"ok\" is greater or equal than the minimum value of 1 should be true") | 	assert.True(t, valid.MinSize([]interface{}{"ok"}, 1, "minSize1").Ok) | ||||||
| 	} |  | ||||||
| 	if valid.MinSize([]string{}, 1, "minSize1").Ok { |  | ||||||
| 		t.Error("the length of empty slice is less than the minimum value of 1 should be false") |  | ||||||
| 	} |  | ||||||
| 	if !valid.MinSize([]interface{}{"ok"}, 1, "minSize1").Ok { |  | ||||||
| 		t.Error("the length of [\"ok\"] is greater or equal than the minimum value of 1 should be true") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestMaxSize(t *testing.T) { | func TestMaxSize(t *testing.T) { | ||||||
| 	valid := Validation{} | 	valid := Validation{} | ||||||
| 
 | 
 | ||||||
| 	if valid.MaxSize("ok", 1, "maxSize1").Ok { | 	assert.False(t, valid.MaxSize("ok", 1, "maxSize1").Ok) | ||||||
| 		t.Error("the length of \"ok\" is greater than the maximum value of 1 should be false") | 	assert.True(t, valid.MaxSize("", 1, "maxSize1").Ok) | ||||||
| 	} | 	assert.False(t, valid.MaxSize([]interface{}{"ok", false}, 1, "maxSize1").Ok) | ||||||
| 	if !valid.MaxSize("", 1, "maxSize1").Ok { | 	assert.True(t, valid.MaxSize([]string{}, 1, "maxSize1").Ok) | ||||||
| 		t.Error("the length of \"\" is less or equal than the maximum value of 1 should be true") |  | ||||||
| 	} |  | ||||||
| 	if valid.MaxSize([]interface{}{"ok", false}, 1, "maxSize1").Ok { |  | ||||||
| 		t.Error("the length of [\"ok\", false] is greater than the maximum value of 1 should be false") |  | ||||||
| 	} |  | ||||||
| 	if !valid.MaxSize([]string{}, 1, "maxSize1").Ok { |  | ||||||
| 		t.Error("the length of empty slice is less or equal than the maximum value of 1 should be true") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestLength(t *testing.T) { | func TestLength(t *testing.T) { | ||||||
| 	valid := Validation{} | 	valid := Validation{} | ||||||
| 
 | 
 | ||||||
| 	if valid.Length("", 1, "length1").Ok { | 	assert.False(t, valid.Length("", 1, "length1").Ok) | ||||||
| 		t.Error("the length of \"\" must equal 1 should be false") | 	assert.True(t, valid.Length("1", 1, "length1").Ok) | ||||||
| 	} | 
 | ||||||
| 	if !valid.Length("1", 1, "length1").Ok { | 	assert.False(t, valid.Length([]string{}, 1, "length1").Ok) | ||||||
| 		t.Error("the length of \"1\" must equal 1 should be true") | 	assert.True(t, valid.Length([]interface{}{"ok"}, 1, "length1").Ok) | ||||||
| 	} |  | ||||||
| 	if valid.Length([]string{}, 1, "length1").Ok { |  | ||||||
| 		t.Error("the length of empty slice must equal 1 should be false") |  | ||||||
| 	} |  | ||||||
| 	if !valid.Length([]interface{}{"ok"}, 1, "length1").Ok { |  | ||||||
| 		t.Error("the length of [\"ok\"] must equal 1 should be true") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestAlpha(t *testing.T) { | func TestAlpha(t *testing.T) { | ||||||
| @ -178,13 +129,16 @@ func TestAlphaNumeric(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | const email = "suchuangji@gmail.com" | ||||||
|  | 
 | ||||||
| func TestMatch(t *testing.T) { | func TestMatch(t *testing.T) { | ||||||
| 	valid := Validation{} | 	valid := Validation{} | ||||||
| 
 | 
 | ||||||
| 	if valid.Match("suchuangji@gmail", regexp.MustCompile(`^\w+@\w+\.\w+$`), "match").Ok { | 	if valid.Match("suchuangji@gmail", regexp.MustCompile(`^\w+@\w+\.\w+$`), "match").Ok { | ||||||
| 		t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\"  should be false") | 		t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\"  should be false") | ||||||
| 	} | 	} | ||||||
| 	if !valid.Match("suchuangji@gmail.com", regexp.MustCompile(`^\w+@\w+\.\w+$`), "match").Ok { | 
 | ||||||
|  | 	if !valid.Match(email, regexp.MustCompile(`^\w+@\w+\.\w+$`), "match").Ok { | ||||||
| 		t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\"  should be true") | 		t.Error("\"suchuangji@gmail\" match \"^\\w+@\\w+\\.\\w+$\"  should be true") | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -217,7 +171,7 @@ func TestEmail(t *testing.T) { | |||||||
| 	if valid.Email("not@a email", "email").Ok { | 	if valid.Email("not@a email", "email").Ok { | ||||||
| 		t.Error("\"not@a email\" is a valid email address should be false") | 		t.Error("\"not@a email\" is a valid email address should be false") | ||||||
| 	} | 	} | ||||||
| 	if !valid.Email("suchuangji@gmail.com", "email").Ok { | 	if !valid.Email(email, "email").Ok { | ||||||
| 		t.Error("\"suchuangji@gmail.com\" is a valid email address should be true") | 		t.Error("\"suchuangji@gmail.com\" is a valid email address should be true") | ||||||
| 	} | 	} | ||||||
| 	if valid.Email("@suchuangji@gmail.com", "email").Ok { | 	if valid.Email("@suchuangji@gmail.com", "email").Ok { | ||||||
| @ -242,7 +196,7 @@ func TestIP(t *testing.T) { | |||||||
| func TestBase64(t *testing.T) { | func TestBase64(t *testing.T) { | ||||||
| 	valid := Validation{} | 	valid := Validation{} | ||||||
| 
 | 
 | ||||||
| 	if valid.Base64("suchuangji@gmail.com", "base64").Ok { | 	if valid.Base64(email, "base64").Ok { | ||||||
| 		t.Error("\"suchuangji@gmail.com\" are a valid base64 characters should be false") | 		t.Error("\"suchuangji@gmail.com\" are a valid base64 characters should be false") | ||||||
| 	} | 	} | ||||||
| 	if !valid.Base64("c3VjaHVhbmdqaUBnbWFpbC5jb20=", "base64").Ok { | 	if !valid.Base64("c3VjaHVhbmdqaUBnbWFpbC5jb20=", "base64").Ok { | ||||||
| @ -370,44 +324,25 @@ func TestValid(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	u := user{Name: "test@/test/;com", Age: 40} | 	u := user{Name: "test@/test/;com", Age: 40} | ||||||
| 	b, err := valid.Valid(u) | 	b, err := valid.Valid(u) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal(err) | 	assert.True(t, b) | ||||||
| 	} |  | ||||||
| 	if !b { |  | ||||||
| 		t.Error("validation should be passed") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	uptr := &user{Name: "test", Age: 40} | 	uptr := &user{Name: "test", Age: 40} | ||||||
| 	valid.Clear() | 	valid.Clear() | ||||||
| 	b, err = valid.Valid(uptr) | 	b, err = valid.Valid(uptr) | ||||||
| 	if err != nil { | 
 | ||||||
| 		t.Fatal(err) | 	assert.Nil(t, err) | ||||||
| 	} | 	assert.False(t, b) | ||||||
| 	if b { | 	assert.Equal(t, 1, len(valid.Errors)) | ||||||
| 		t.Error("validation should not be passed") | 	assert.Equal(t, "Name.Match", valid.Errors[0].Key) | ||||||
| 	} |  | ||||||
| 	if len(valid.Errors) != 1 { |  | ||||||
| 		t.Fatalf("valid errors len should be 1 but got %d", len(valid.Errors)) |  | ||||||
| 	} |  | ||||||
| 	if valid.Errors[0].Key != "Name.Match" { |  | ||||||
| 		t.Errorf("Message key should be `Name.Match` but got %s", valid.Errors[0].Key) |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	u = user{Name: "test@/test/;com", Age: 180} | 	u = user{Name: "test@/test/;com", Age: 180} | ||||||
| 	valid.Clear() | 	valid.Clear() | ||||||
| 	b, err = valid.Valid(u) | 	b, err = valid.Valid(u) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal(err) | 	assert.False(t, b) | ||||||
| 	} | 	assert.Equal(t, 1, len(valid.Errors)) | ||||||
| 	if b { | 	assert.Equal(t, "Age.Range.", valid.Errors[0].Key) | ||||||
| 		t.Error("validation should not be passed") |  | ||||||
| 	} |  | ||||||
| 	if len(valid.Errors) != 1 { |  | ||||||
| 		t.Fatalf("valid errors len should be 1 but got %d", len(valid.Errors)) |  | ||||||
| 	} |  | ||||||
| 	if valid.Errors[0].Key != "Age.Range." { |  | ||||||
| 		t.Errorf("Message key should be `Age.Range` but got %s", valid.Errors[0].Key) |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestRecursiveValid(t *testing.T) { | func TestRecursiveValid(t *testing.T) { | ||||||
| @ -432,12 +367,8 @@ func TestRecursiveValid(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	u := Account{Password: "abc123_", U: User{}} | 	u := Account{Password: "abc123_", U: User{}} | ||||||
| 	b, err := valid.RecursiveValid(u) | 	b, err := valid.RecursiveValid(u) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal(err) | 	assert.False(t, b) | ||||||
| 	} |  | ||||||
| 	if b { |  | ||||||
| 		t.Error("validation should not be passed") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestSkipValid(t *testing.T) { | func TestSkipValid(t *testing.T) { | ||||||
| @ -474,21 +405,13 @@ func TestSkipValid(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	valid := Validation{} | 	valid := Validation{} | ||||||
| 	b, err := valid.Valid(u) | 	b, err := valid.Valid(u) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal(err) | 	assert.False(t, b) | ||||||
| 	} |  | ||||||
| 	if b { |  | ||||||
| 		t.Fatal("validation should not be passed") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	valid = Validation{RequiredFirst: true} | 	valid = Validation{RequiredFirst: true} | ||||||
| 	b, err = valid.Valid(u) | 	b, err = valid.Valid(u) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal(err) | 	assert.True(t, b) | ||||||
| 	} |  | ||||||
| 	if !b { |  | ||||||
| 		t.Fatal("validation should be passed") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestPointer(t *testing.T) { | func TestPointer(t *testing.T) { | ||||||
| @ -506,12 +429,8 @@ func TestPointer(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	valid := Validation{} | 	valid := Validation{} | ||||||
| 	b, err := valid.Valid(u) | 	b, err := valid.Valid(u) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal(err) | 	assert.False(t, b) | ||||||
| 	} |  | ||||||
| 	if b { |  | ||||||
| 		t.Fatal("validation should not be passed") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	validEmail := "a@a.com" | 	validEmail := "a@a.com" | ||||||
| 	u = User{ | 	u = User{ | ||||||
| @ -521,12 +440,8 @@ func TestPointer(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	valid = Validation{RequiredFirst: true} | 	valid = Validation{RequiredFirst: true} | ||||||
| 	b, err = valid.Valid(u) | 	b, err = valid.Valid(u) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal(err) | 	assert.True(t, b) | ||||||
| 	} |  | ||||||
| 	if !b { |  | ||||||
| 		t.Fatal("validation should be passed") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	u = User{ | 	u = User{ | ||||||
| 		ReqEmail: &validEmail, | 		ReqEmail: &validEmail, | ||||||
| @ -535,12 +450,8 @@ func TestPointer(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	valid = Validation{} | 	valid = Validation{} | ||||||
| 	b, err = valid.Valid(u) | 	b, err = valid.Valid(u) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal(err) | 	assert.False(t, b) | ||||||
| 	} |  | ||||||
| 	if b { |  | ||||||
| 		t.Fatal("validation should not be passed") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	invalidEmail := "a@a" | 	invalidEmail := "a@a" | ||||||
| 	u = User{ | 	u = User{ | ||||||
| @ -550,12 +461,8 @@ func TestPointer(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	valid = Validation{RequiredFirst: true} | 	valid = Validation{RequiredFirst: true} | ||||||
| 	b, err = valid.Valid(u) | 	b, err = valid.Valid(u) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal(err) | 	assert.False(t, b) | ||||||
| 	} |  | ||||||
| 	if b { |  | ||||||
| 		t.Fatal("validation should not be passed") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	u = User{ | 	u = User{ | ||||||
| 		ReqEmail: &validEmail, | 		ReqEmail: &validEmail, | ||||||
| @ -564,12 +471,8 @@ func TestPointer(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	valid = Validation{} | 	valid = Validation{} | ||||||
| 	b, err = valid.Valid(u) | 	b, err = valid.Valid(u) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal(err) | 	assert.False(t, b) | ||||||
| 	} |  | ||||||
| 	if b { |  | ||||||
| 		t.Fatal("validation should not be passed") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestCanSkipAlso(t *testing.T) { | func TestCanSkipAlso(t *testing.T) { | ||||||
| @ -589,21 +492,13 @@ func TestCanSkipAlso(t *testing.T) { | |||||||
| 
 | 
 | ||||||
| 	valid := Validation{RequiredFirst: true} | 	valid := Validation{RequiredFirst: true} | ||||||
| 	b, err := valid.Valid(u) | 	b, err := valid.Valid(u) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Fatal(err) | 	assert.False(t, b) | ||||||
| 	} |  | ||||||
| 	if b { |  | ||||||
| 		t.Fatal("validation should not be passed") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	valid = Validation{RequiredFirst: true} | 	valid = Validation{RequiredFirst: true} | ||||||
| 	valid.CanSkipAlso("Range") | 	valid.CanSkipAlso("Range") | ||||||
| 	b, err = valid.Valid(u) | 	b, err = valid.Valid(u) | ||||||
| 	if err != nil { |  | ||||||
| 		t.Fatal(err) |  | ||||||
| 	} |  | ||||||
| 	if !b { |  | ||||||
| 		t.Fatal("validation should be passed") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.True(t, b) | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										4
									
								
								client/cache/README.md
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								client/cache/README.md
									
									
									
									
										vendored
									
									
								
							| @ -4,7 +4,7 @@ cache is a Go cache manager. It can use many cache adapters. The repo is inspire | |||||||
| 
 | 
 | ||||||
| ## How to install? | ## How to install? | ||||||
| 
 | 
 | ||||||
| 	go get github.com/beego/beego/v2/cache | 	go get github.com/beego/beego/v2/client/cache | ||||||
| 
 | 
 | ||||||
| ## What adapters are supported? | ## What adapters are supported? | ||||||
| 
 | 
 | ||||||
| @ -15,7 +15,7 @@ As of now this cache support memory, Memcache and Redis. | |||||||
| First you must import it | First you must import it | ||||||
| 
 | 
 | ||||||
| 	import ( | 	import ( | ||||||
| 		"github.com/beego/beego/v2/cache" | 		"github.com/beego/beego/v2/client/cache" | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
| Then init a Cache (example with memory adapter) | Then init a Cache (example with memory adapter) | ||||||
|  | |||||||
							
								
								
									
										11
									
								
								client/cache/cache.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										11
									
								
								client/cache/cache.go
									
									
									
									
										vendored
									
									
								
							| @ -16,7 +16,7 @@ | |||||||
| // Usage: | // Usage: | ||||||
| // | // | ||||||
| // import( | // import( | ||||||
| //   "github.com/beego/beego/v2/cache" | //   "github.com/beego/beego/v2/client/cache" | ||||||
| // ) | // ) | ||||||
| // | // | ||||||
| // bm, err := cache.NewCache("memory", `{"interval":60}`) | // bm, err := cache.NewCache("memory", `{"interval":60}`) | ||||||
| @ -33,8 +33,9 @@ package cache | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"fmt" |  | ||||||
| 	"time" | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/beego/beego/v2/core/berror" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // Cache interface contains all behaviors for cache adapter. | // Cache interface contains all behaviors for cache adapter. | ||||||
| @ -55,12 +56,14 @@ type Cache interface { | |||||||
| 	// Set a cached value with key and expire time. | 	// Set a cached value with key and expire time. | ||||||
| 	Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error | 	Put(ctx context.Context, key string, val interface{}, timeout time.Duration) error | ||||||
| 	// Delete cached value by key. | 	// Delete cached value by key. | ||||||
|  | 	// Should not return error if key not found | ||||||
| 	Delete(ctx context.Context, key string) error | 	Delete(ctx context.Context, key string) error | ||||||
| 	// Increment a cached int value by key, as a counter. | 	// Increment a cached int value by key, as a counter. | ||||||
| 	Incr(ctx context.Context, key string) error | 	Incr(ctx context.Context, key string) error | ||||||
| 	// Decrement a cached int value by key, as a counter. | 	// Decrement a cached int value by key, as a counter. | ||||||
| 	Decr(ctx context.Context, key string) error | 	Decr(ctx context.Context, key string) error | ||||||
| 	// Check if a cached value exists or not. | 	// Check if a cached value exists or not. | ||||||
|  | 	// if key is expired, return (false, nil) | ||||||
| 	IsExist(ctx context.Context, key string) (bool, error) | 	IsExist(ctx context.Context, key string) (bool, error) | ||||||
| 	// Clear all cache. | 	// Clear all cache. | ||||||
| 	ClearAll(ctx context.Context) error | 	ClearAll(ctx context.Context) error | ||||||
| @ -78,7 +81,7 @@ var adapters = make(map[string]Instance) | |||||||
| // it panics. | // it panics. | ||||||
| func Register(name string, adapter Instance) { | func Register(name string, adapter Instance) { | ||||||
| 	if adapter == nil { | 	if adapter == nil { | ||||||
| 		panic("cache: Register adapter is nil") | 		panic(berror.Error(NilCacheAdapter, "cache: Register adapter is nil").Error()) | ||||||
| 	} | 	} | ||||||
| 	if _, ok := adapters[name]; ok { | 	if _, ok := adapters[name]; ok { | ||||||
| 		panic("cache: Register called twice for adapter " + name) | 		panic("cache: Register called twice for adapter " + name) | ||||||
| @ -92,7 +95,7 @@ func Register(name string, adapter Instance) { | |||||||
| func NewCache(adapterName, config string) (adapter Cache, err error) { | func NewCache(adapterName, config string) (adapter Cache, err error) { | ||||||
| 	instanceFunc, ok := adapters[adapterName] | 	instanceFunc, ok := adapters[adapterName] | ||||||
| 	if !ok { | 	if !ok { | ||||||
| 		err = fmt.Errorf("cache: unknown adapter name %q (forgot to import?)", adapterName) | 		err = berror.Errorf(UnknownAdapter, "cache: unknown adapter name %s (forgot to import?)", adapterName) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 	adapter = instanceFunc() | 	adapter = instanceFunc() | ||||||
|  | |||||||
							
								
								
									
										224
									
								
								client/cache/cache_test.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										224
									
								
								client/cache/cache_test.go
									
									
									
									
										vendored
									
									
								
							| @ -16,17 +16,19 @@ package cache | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"context" | 	"context" | ||||||
|  | 	"math" | ||||||
| 	"os" | 	"os" | ||||||
|  | 	"strings" | ||||||
| 	"sync" | 	"sync" | ||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestCacheIncr(t *testing.T) { | func TestCacheIncr(t *testing.T) { | ||||||
| 	bm, err := NewCache("memory", `{"interval":20}`) | 	bm, err := NewCache("memory", `{"interval":20}`) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Error("init err") |  | ||||||
| 	} |  | ||||||
| 	// timeoutDuration := 10 * time.Second | 	// timeoutDuration := 10 * time.Second | ||||||
| 
 | 
 | ||||||
| 	bm.Put(context.Background(), "edwardhey", 0, time.Second*20) | 	bm.Put(context.Background(), "edwardhey", 0, time.Second*20) | ||||||
| @ -46,11 +48,9 @@ func TestCacheIncr(t *testing.T) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestCache(t *testing.T) { | func TestCache(t *testing.T) { | ||||||
| 	bm, err := NewCache("memory", `{"interval":20}`) | 	bm, err := NewCache("memory", `{"interval":1}`) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Error("init err") | 	timeoutDuration := 5 * time.Second | ||||||
| 	} |  | ||||||
| 	timeoutDuration := 10 * time.Second |  | ||||||
| 	if err = bm.Put(context.Background(), "astaxie", 1, timeoutDuration); err != nil { | 	if err = bm.Put(context.Background(), "astaxie", 1, timeoutDuration); err != nil { | ||||||
| 		t.Error("set Error", err) | 		t.Error("set Error", err) | ||||||
| 	} | 	} | ||||||
| @ -62,7 +62,7 @@ func TestCache(t *testing.T) { | |||||||
| 		t.Error("get err") | 		t.Error("get err") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	time.Sleep(30 * time.Second) | 	time.Sleep(7 * time.Second) | ||||||
| 
 | 
 | ||||||
| 	if res, _ := bm.IsExist(context.Background(), "astaxie"); res { | 	if res, _ := bm.IsExist(context.Background(), "astaxie"); res { | ||||||
| 		t.Error("check err") | 		t.Error("check err") | ||||||
| @ -73,130 +73,95 @@ func TestCache(t *testing.T) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// test different integer type for incr & decr | 	// test different integer type for incr & decr | ||||||
| 	testMultiIncrDecr(t, bm, timeoutDuration) | 	testMultiTypeIncrDecr(t, bm, timeoutDuration) | ||||||
|  | 
 | ||||||
|  | 	// test overflow of incr&decr | ||||||
|  | 	testIncrOverFlow(t, bm, timeoutDuration) | ||||||
|  | 	testDecrOverFlow(t, bm, timeoutDuration) | ||||||
| 
 | 
 | ||||||
| 	bm.Delete(context.Background(), "astaxie") | 	bm.Delete(context.Background(), "astaxie") | ||||||
| 	if res, _ := bm.IsExist(context.Background(), "astaxie"); res { | 	res, _ := bm.IsExist(context.Background(), "astaxie") | ||||||
| 		t.Error("delete err") | 	assert.False(t, res) | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test GetMulti | 	assert.Nil(t, bm.Put(context.Background(), "astaxie", "author", timeoutDuration)) | ||||||
| 	if err = bm.Put(context.Background(), "astaxie", "author", timeoutDuration); err != nil { |  | ||||||
| 		t.Error("set Error", err) |  | ||||||
| 	} |  | ||||||
| 	if res, _ := bm.IsExist(context.Background(), "astaxie"); !res { |  | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 	if v, _ := bm.Get(context.Background(), "astaxie"); v.(string) != "author" { |  | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if err = bm.Put(context.Background(), "astaxie1", "author1", timeoutDuration); err != nil { | 	res, _ = bm.IsExist(context.Background(), "astaxie") | ||||||
| 		t.Error("set Error", err) | 	assert.True(t, res) | ||||||
| 	} | 
 | ||||||
| 	if res, _ := bm.IsExist(context.Background(), "astaxie1"); !res { | 	v, _ := bm.Get(context.Background(), "astaxie") | ||||||
| 		t.Error("check err") | 	assert.Equal(t, "author", v) | ||||||
| 	} | 
 | ||||||
|  | 	assert.Nil(t, bm.Put(context.Background(), "astaxie1", "author1", timeoutDuration)) | ||||||
|  | 
 | ||||||
|  | 	res, _ = bm.IsExist(context.Background(), "astaxie1") | ||||||
|  | 	assert.True(t, res) | ||||||
| 
 | 
 | ||||||
| 	vv, _ := bm.GetMulti(context.Background(), []string{"astaxie", "astaxie1"}) | 	vv, _ := bm.GetMulti(context.Background(), []string{"astaxie", "astaxie1"}) | ||||||
| 	if len(vv) != 2 { | 	assert.Equal(t, 2, len(vv)) | ||||||
| 		t.Error("GetMulti ERROR") | 	assert.Equal(t, "author", vv[0]) | ||||||
| 	} | 	assert.Equal(t, "author1", vv[1]) | ||||||
| 	if vv[0].(string) != "author" { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 	if vv[1].(string) != "author1" { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	vv, err = bm.GetMulti(context.Background(), []string{"astaxie0", "astaxie1"}) | 	vv, err = bm.GetMulti(context.Background(), []string{"astaxie0", "astaxie1"}) | ||||||
| 	if len(vv) != 2 { | 	assert.Equal(t, 2, len(vv)) | ||||||
| 		t.Error("GetMulti ERROR") | 	assert.Nil(t, vv[0]) | ||||||
| 	} | 	assert.Equal(t, "author1", vv[1]) | ||||||
| 	if vv[0] != nil { | 
 | ||||||
| 		t.Error("GetMulti ERROR") | 	assert.NotNil(t, err) | ||||||
| 	} | 	assert.True(t, strings.Contains(err.Error(), "key isn't exist")) | ||||||
| 	if vv[1].(string) != "author1" { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 	if err != nil && err.Error() != "key [astaxie0] error: the key isn't exist" { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestFileCache(t *testing.T) { | func TestFileCache(t *testing.T) { | ||||||
| 	bm, err := NewCache("file", `{"CachePath":"cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"}`) | 	bm, err := NewCache("file", `{"CachePath":"cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"}`) | ||||||
| 	if err != nil { | 	assert.Nil(t, err) | ||||||
| 		t.Error("init err") |  | ||||||
| 	} |  | ||||||
| 	timeoutDuration := 10 * time.Second | 	timeoutDuration := 10 * time.Second | ||||||
| 	if err = bm.Put(context.Background(), "astaxie", 1, timeoutDuration); err != nil { | 	assert.Nil(t, bm.Put(context.Background(), "astaxie", 1, timeoutDuration)) | ||||||
| 		t.Error("set Error", err) |  | ||||||
| 	} |  | ||||||
| 	if res, _ := bm.IsExist(context.Background(), "astaxie"); !res { |  | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if v, _ := bm.Get(context.Background(), "astaxie"); v.(int) != 1 { | 	res, _ := bm.IsExist(context.Background(), "astaxie") | ||||||
| 		t.Error("get err") | 	assert.True(t, res) | ||||||
| 	} | 	v, _ := bm.Get(context.Background(), "astaxie") | ||||||
|  | 	assert.Equal(t, 1, v) | ||||||
| 
 | 
 | ||||||
| 	// test different integer type for incr & decr | 	// test different integer type for incr & decr | ||||||
| 	testMultiIncrDecr(t, bm, timeoutDuration) | 	testMultiTypeIncrDecr(t, bm, timeoutDuration) | ||||||
|  | 
 | ||||||
|  | 	// test overflow of incr&decr | ||||||
|  | 	testIncrOverFlow(t, bm, timeoutDuration) | ||||||
|  | 	testDecrOverFlow(t, bm, timeoutDuration) | ||||||
| 
 | 
 | ||||||
| 	bm.Delete(context.Background(), "astaxie") | 	bm.Delete(context.Background(), "astaxie") | ||||||
| 	if res, _ := bm.IsExist(context.Background(), "astaxie"); res { | 	res, _ = bm.IsExist(context.Background(), "astaxie") | ||||||
| 		t.Error("delete err") | 	assert.False(t, res) | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test string | 	// test string | ||||||
| 	if err = bm.Put(context.Background(), "astaxie", "author", timeoutDuration); err != nil { | 	assert.Nil(t, bm.Put(context.Background(), "astaxie", "author", timeoutDuration)) | ||||||
| 		t.Error("set Error", err) | 	res, _ = bm.IsExist(context.Background(), "astaxie") | ||||||
| 	} | 	assert.True(t, res) | ||||||
| 	if res, _ := bm.IsExist(context.Background(), "astaxie"); !res { | 
 | ||||||
| 		t.Error("check err") | 	v, _ = bm.Get(context.Background(), "astaxie") | ||||||
| 	} | 	assert.Equal(t, "author", v) | ||||||
| 	if v, _ := bm.Get(context.Background(), "astaxie"); v.(string) != "author" { |  | ||||||
| 		t.Error("get err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	// test GetMulti | 	// test GetMulti | ||||||
| 	if err = bm.Put(context.Background(), "astaxie1", "author1", timeoutDuration); err != nil { | 	assert.Nil(t, bm.Put(context.Background(), "astaxie1", "author1", timeoutDuration)) | ||||||
| 		t.Error("set Error", err) | 
 | ||||||
| 	} | 	res, _ = bm.IsExist(context.Background(), "astaxie1") | ||||||
| 	if res, _ := bm.IsExist(context.Background(), "astaxie1"); !res { | 	assert.True(t, res) | ||||||
| 		t.Error("check err") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	vv, _ := bm.GetMulti(context.Background(), []string{"astaxie", "astaxie1"}) | 	vv, _ := bm.GetMulti(context.Background(), []string{"astaxie", "astaxie1"}) | ||||||
| 	if len(vv) != 2 { | 	assert.Equal(t, 2, len(vv)) | ||||||
| 		t.Error("GetMulti ERROR") | 	assert.Equal(t, "author", vv[0]) | ||||||
| 	} | 	assert.Equal(t, "author1", vv[1]) | ||||||
| 	if vv[0].(string) != "author" { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 	if vv[1].(string) != "author1" { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	vv, err = bm.GetMulti(context.Background(), []string{"astaxie0", "astaxie1"}) | 	vv, err = bm.GetMulti(context.Background(), []string{"astaxie0", "astaxie1"}) | ||||||
| 	if len(vv) != 2 { | 	assert.Equal(t, 2, len(vv)) | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 	if vv[0] != nil { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 	if vv[1].(string) != "author1" { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 	if err == nil { |  | ||||||
| 		t.Error("GetMulti ERROR") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
|  | 	assert.Nil(t, vv[0]) | ||||||
|  | 
 | ||||||
|  | 	assert.Equal(t, "author1", vv[1]) | ||||||
|  | 	assert.NotNil(t, err) | ||||||
| 	os.RemoveAll("cache") | 	os.RemoveAll("cache") | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func testMultiIncrDecr(t *testing.T, c Cache, timeout time.Duration) { | func testMultiTypeIncrDecr(t *testing.T, c Cache, timeout time.Duration) { | ||||||
| 	testIncrDecr(t, c, 1, 2, timeout) | 	testIncrDecr(t, c, 1, 2, timeout) | ||||||
| 	testIncrDecr(t, c, int32(1), int32(2), timeout) | 	testIncrDecr(t, c, int32(1), int32(2), timeout) | ||||||
| 	testIncrDecr(t, c, int64(1), int64(2), timeout) | 	testIncrDecr(t, c, int64(1), int64(2), timeout) | ||||||
| @ -206,30 +171,51 @@ func testMultiIncrDecr(t *testing.T, c Cache, timeout time.Duration) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func testIncrDecr(t *testing.T, c Cache, beforeIncr interface{}, afterIncr interface{}, timeout time.Duration) { | func testIncrDecr(t *testing.T, c Cache, beforeIncr interface{}, afterIncr interface{}, timeout time.Duration) { | ||||||
| 	var err error |  | ||||||
| 	ctx := context.Background() | 	ctx := context.Background() | ||||||
| 	key := "incDecKey" | 	key := "incDecKey" | ||||||
| 	if err = c.Put(ctx, key, beforeIncr, timeout); err != nil { | 
 | ||||||
| 		t.Error("Get Error", err) | 	assert.Nil(t, c.Put(ctx, key, beforeIncr, timeout)) | ||||||
|  | 	assert.Nil(t, c.Incr(ctx, key)) | ||||||
|  | 
 | ||||||
|  | 	v, _ := c.Get(ctx, key) | ||||||
|  | 	assert.Equal(t, afterIncr, v) | ||||||
|  | 
 | ||||||
|  | 	assert.Nil(t, c.Decr(ctx, key)) | ||||||
|  | 
 | ||||||
|  | 	v, _ = c.Get(ctx, key) | ||||||
|  | 	assert.Equal(t, v, beforeIncr) | ||||||
|  | 	assert.Nil(t, c.Delete(ctx, key)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 	if err = c.Incr(ctx, key); err != nil { | func testIncrOverFlow(t *testing.T, c Cache, timeout time.Duration) { | ||||||
| 		t.Error("Incr Error", err) | 	ctx := context.Background() | ||||||
|  | 	key := "incKey" | ||||||
|  | 
 | ||||||
|  | 	assert.Nil(t, c.Put(ctx, key, int64(math.MaxInt64), timeout)) | ||||||
|  | 	// int64 | ||||||
|  | 	defer func() { | ||||||
|  | 		assert.Nil(t, c.Delete(ctx, key)) | ||||||
|  | 	}() | ||||||
|  | 	assert.NotNil(t, c.Incr(ctx, key)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| 	if v, _ := c.Get(ctx, key); v != afterIncr { | func testDecrOverFlow(t *testing.T, c Cache, timeout time.Duration) { | ||||||
| 		t.Error("Get Error") | 	var err error | ||||||
| 	} | 	ctx := context.Background() | ||||||
|  | 	key := "decKey" | ||||||
| 
 | 
 | ||||||
| 	if err = c.Decr(ctx, key); err != nil { | 	// int64 | ||||||
| 		t.Error("Decr Error", err) | 	if err = c.Put(ctx, key, int64(math.MinInt64), timeout); err != nil { | ||||||
|  | 		t.Error("Put Error: ", err.Error()) | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 	defer func() { | ||||||
| 	if v, _ := c.Get(ctx, key); v != beforeIncr { | 		if err = c.Delete(ctx, key); err != nil { | ||||||
| 		t.Error("Get Error") | 			t.Errorf("Delete error: %s", err.Error()) | ||||||
| 		} | 		} | ||||||
| 
 | 	}() | ||||||
| 	if err := c.Delete(ctx, key); err != nil { | 	if err = c.Decr(ctx, key); err == nil { | ||||||
| 		t.Error("Delete Error") | 		t.Error("Decr error") | ||||||
|  | 		return | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										95
									
								
								client/cache/calc_utils.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										95
									
								
								client/cache/calc_utils.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,95 @@ | |||||||
|  | package cache | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"math" | ||||||
|  | 
 | ||||||
|  | 	"github.com/beego/beego/v2/core/berror" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	ErrIncrementOverflow = berror.Error(IncrementOverflow, "this incr invocation will overflow.") | ||||||
|  | 	ErrDecrementOverflow = berror.Error(DecrementOverflow, "this decr invocation will overflow.") | ||||||
|  | 	ErrNotIntegerType    = berror.Error(NotIntegerType, "item val is not (u)int (u)int32 (u)int64") | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	MinUint32 uint32 = 0 | ||||||
|  | 	MinUint64 uint64 = 0 | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func incr(originVal interface{}) (interface{}, error) { | ||||||
|  | 	switch val := originVal.(type) { | ||||||
|  | 	case int: | ||||||
|  | 		tmp := val + 1 | ||||||
|  | 		if val > 0 && tmp < 0 { | ||||||
|  | 			return nil, ErrIncrementOverflow | ||||||
|  | 		} | ||||||
|  | 		return tmp, nil | ||||||
|  | 	case int32: | ||||||
|  | 		if val == math.MaxInt32 { | ||||||
|  | 			return nil, ErrIncrementOverflow | ||||||
|  | 		} | ||||||
|  | 		return val + 1, nil | ||||||
|  | 	case int64: | ||||||
|  | 		if val == math.MaxInt64 { | ||||||
|  | 			return nil, ErrIncrementOverflow | ||||||
|  | 		} | ||||||
|  | 		return val + 1, nil | ||||||
|  | 	case uint: | ||||||
|  | 		tmp := val + 1 | ||||||
|  | 		if tmp < val { | ||||||
|  | 			return nil, ErrIncrementOverflow | ||||||
|  | 		} | ||||||
|  | 		return tmp, nil | ||||||
|  | 	case uint32: | ||||||
|  | 		if val == math.MaxUint32 { | ||||||
|  | 			return nil, ErrIncrementOverflow | ||||||
|  | 		} | ||||||
|  | 		return val + 1, nil | ||||||
|  | 	case uint64: | ||||||
|  | 		if val == math.MaxUint64 { | ||||||
|  | 			return nil, ErrIncrementOverflow | ||||||
|  | 		} | ||||||
|  | 		return val + 1, nil | ||||||
|  | 	default: | ||||||
|  | 		return nil, ErrNotIntegerType | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func decr(originVal interface{}) (interface{}, error) { | ||||||
|  | 	switch val := originVal.(type) { | ||||||
|  | 	case int: | ||||||
|  | 		tmp := val - 1 | ||||||
|  | 		if val < 0 && tmp > 0 { | ||||||
|  | 			return nil, ErrDecrementOverflow | ||||||
|  | 		} | ||||||
|  | 		return tmp, nil | ||||||
|  | 	case int32: | ||||||
|  | 		if val == math.MinInt32 { | ||||||
|  | 			return nil, ErrDecrementOverflow | ||||||
|  | 		} | ||||||
|  | 		return val - 1, nil | ||||||
|  | 	case int64: | ||||||
|  | 		if val == math.MinInt64 { | ||||||
|  | 			return nil, ErrDecrementOverflow | ||||||
|  | 		} | ||||||
|  | 		return val - 1, nil | ||||||
|  | 	case uint: | ||||||
|  | 		if val == 0 { | ||||||
|  | 			return nil, ErrDecrementOverflow | ||||||
|  | 		} | ||||||
|  | 		return val - 1, nil | ||||||
|  | 	case uint32: | ||||||
|  | 		if val == MinUint32 { | ||||||
|  | 			return nil, ErrDecrementOverflow | ||||||
|  | 		} | ||||||
|  | 		return val - 1, nil | ||||||
|  | 	case uint64: | ||||||
|  | 		if val == MinUint64 { | ||||||
|  | 			return nil, ErrDecrementOverflow | ||||||
|  | 		} | ||||||
|  | 		return val - 1, nil | ||||||
|  | 	default: | ||||||
|  | 		return nil, ErrNotIntegerType | ||||||
|  | 	} | ||||||
|  | } | ||||||
							
								
								
									
										140
									
								
								client/cache/calc_utils_test.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								client/cache/calc_utils_test.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,140 @@ | |||||||
|  | package cache | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"math" | ||||||
|  | 	"strconv" | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestIncr(t *testing.T) { | ||||||
|  | 	// int | ||||||
|  | 	var originVal interface{} = int(1) | ||||||
|  | 	var updateVal interface{} = int(2) | ||||||
|  | 	val, err := incr(originVal) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, val, updateVal) | ||||||
|  | 
 | ||||||
|  | 	_, err = incr(int(1<<(strconv.IntSize-1) - 1)) | ||||||
|  | 	assert.Equal(t, ErrIncrementOverflow, err) | ||||||
|  | 
 | ||||||
|  | 	// int32 | ||||||
|  | 	originVal = int32(1) | ||||||
|  | 	updateVal = int32(2) | ||||||
|  | 	val, err = incr(originVal) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, val, updateVal) | ||||||
|  | 
 | ||||||
|  | 	_, err = incr(int32(math.MaxInt32)) | ||||||
|  | 	assert.Equal(t, ErrIncrementOverflow, err) | ||||||
|  | 
 | ||||||
|  | 	// int64 | ||||||
|  | 	originVal = int64(1) | ||||||
|  | 	updateVal = int64(2) | ||||||
|  | 	val, err = incr(originVal) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, val, updateVal) | ||||||
|  | 
 | ||||||
|  | 	_, err = incr(int64(math.MaxInt64)) | ||||||
|  | 	assert.Equal(t, ErrIncrementOverflow, err) | ||||||
|  | 
 | ||||||
|  | 	// uint | ||||||
|  | 	originVal = uint(1) | ||||||
|  | 	updateVal = uint(2) | ||||||
|  | 	val, err = incr(originVal) | ||||||
|  | 
 | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, val, updateVal) | ||||||
|  | 
 | ||||||
|  | 	_, err = incr(uint(1<<(strconv.IntSize) - 1)) | ||||||
|  | 	assert.Equal(t, ErrIncrementOverflow, err) | ||||||
|  | 
 | ||||||
|  | 	// uint32 | ||||||
|  | 	originVal = uint32(1) | ||||||
|  | 	updateVal = uint32(2) | ||||||
|  | 	val, err = incr(originVal) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, val, updateVal) | ||||||
|  | 
 | ||||||
|  | 	_, err = incr(uint32(math.MaxUint32)) | ||||||
|  | 	assert.Equal(t, ErrIncrementOverflow, err) | ||||||
|  | 
 | ||||||
|  | 	// uint64 | ||||||
|  | 	originVal = uint64(1) | ||||||
|  | 	updateVal = uint64(2) | ||||||
|  | 	val, err = incr(originVal) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, val, updateVal) | ||||||
|  | 
 | ||||||
|  | 	_, err = incr(uint64(math.MaxUint64)) | ||||||
|  | 	assert.Equal(t, ErrIncrementOverflow, err) | ||||||
|  | 	// other type | ||||||
|  | 	_, err = incr("string") | ||||||
|  | 	assert.Equal(t, ErrNotIntegerType, err) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestDecr(t *testing.T) { | ||||||
|  | 	// int | ||||||
|  | 	var originVal interface{} = int(2) | ||||||
|  | 	var updateVal interface{} = int(1) | ||||||
|  | 	val, err := decr(originVal) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, val, updateVal) | ||||||
|  | 
 | ||||||
|  | 	_, err = decr(int(-1 << (strconv.IntSize - 1))) | ||||||
|  | 	assert.Equal(t, ErrDecrementOverflow, err) | ||||||
|  | 	// int32 | ||||||
|  | 	originVal = int32(2) | ||||||
|  | 	updateVal = int32(1) | ||||||
|  | 	val, err = decr(originVal) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, val, updateVal) | ||||||
|  | 
 | ||||||
|  | 	_, err = decr(int32(math.MinInt32)) | ||||||
|  | 	assert.Equal(t, ErrDecrementOverflow, err) | ||||||
|  | 
 | ||||||
|  | 	// int64 | ||||||
|  | 	originVal = int64(2) | ||||||
|  | 	updateVal = int64(1) | ||||||
|  | 	val, err = decr(originVal) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, val, updateVal) | ||||||
|  | 
 | ||||||
|  | 	_, err = decr(int64(math.MinInt64)) | ||||||
|  | 	assert.Equal(t, ErrDecrementOverflow, err) | ||||||
|  | 
 | ||||||
|  | 	// uint | ||||||
|  | 	originVal = uint(2) | ||||||
|  | 	updateVal = uint(1) | ||||||
|  | 	val, err = decr(originVal) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, val, updateVal) | ||||||
|  | 
 | ||||||
|  | 	_, err = decr(uint(0)) | ||||||
|  | 	assert.Equal(t, ErrDecrementOverflow, err) | ||||||
|  | 
 | ||||||
|  | 	// uint32 | ||||||
|  | 	originVal = uint32(2) | ||||||
|  | 	updateVal = uint32(1) | ||||||
|  | 	val, err = decr(originVal) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, val, updateVal) | ||||||
|  | 
 | ||||||
|  | 	_, err = decr(uint32(0)) | ||||||
|  | 	assert.Equal(t, ErrDecrementOverflow, err) | ||||||
|  | 
 | ||||||
|  | 	// uint64 | ||||||
|  | 	originVal = uint64(2) | ||||||
|  | 	updateVal = uint64(1) | ||||||
|  | 	val, err = decr(originVal) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, val, updateVal) | ||||||
|  | 
 | ||||||
|  | 	_, err = decr(uint64(0)) | ||||||
|  | 	assert.Equal(t, ErrDecrementOverflow, err) | ||||||
|  | 
 | ||||||
|  | 	// other type | ||||||
|  | 	_, err = decr("string") | ||||||
|  | 	assert.Equal(t, ErrNotIntegerType, err) | ||||||
|  | } | ||||||
							
								
								
									
										142
									
								
								client/cache/conv_test.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										142
									
								
								client/cache/conv_test.go
									
									
									
									
										vendored
									
									
								
							| @ -16,128 +16,74 @@ package cache | |||||||
| 
 | 
 | ||||||
| import ( | import ( | ||||||
| 	"testing" | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| func TestGetString(t *testing.T) { | func TestGetString(t *testing.T) { | ||||||
| 	var t1 = "test1" | 	t1 := "test1" | ||||||
| 	if "test1" != GetString(t1) { |  | ||||||
| 		t.Error("get string from string error") |  | ||||||
| 	} |  | ||||||
| 	var t2 = []byte("test2") |  | ||||||
| 	if "test2" != GetString(t2) { |  | ||||||
| 		t.Error("get string from byte array error") |  | ||||||
| 	} |  | ||||||
| 	var t3 = 1 |  | ||||||
| 	if "1" != GetString(t3) { |  | ||||||
| 		t.Error("get string from int error") |  | ||||||
| 	} |  | ||||||
| 	var t4 int64 = 1 |  | ||||||
| 	if "1" != GetString(t4) { |  | ||||||
| 		t.Error("get string from int64 error") |  | ||||||
| 	} |  | ||||||
| 	var t5 = 1.1 |  | ||||||
| 	if "1.1" != GetString(t5) { |  | ||||||
| 		t.Error("get string from float64 error") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if "" != GetString(nil) { | 	assert.Equal(t, "test1", GetString(t1)) | ||||||
| 		t.Error("get string from nil error") | 	t2 := []byte("test2") | ||||||
| 	} | 	assert.Equal(t, "test2", GetString(t2)) | ||||||
|  | 	t3 := 1 | ||||||
|  | 	assert.Equal(t, "1", GetString(t3)) | ||||||
|  | 	var t4 int64 = 1 | ||||||
|  | 	assert.Equal(t, "1", GetString(t4)) | ||||||
|  | 	t5 := 1.1 | ||||||
|  | 	assert.Equal(t, "1.1", GetString(t5)) | ||||||
|  | 	assert.Equal(t, "", GetString(nil)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestGetInt(t *testing.T) { | func TestGetInt(t *testing.T) { | ||||||
| 	var t1 = 1 | 	t1 := 1 | ||||||
| 	if 1 != GetInt(t1) { | 	assert.Equal(t, 1, GetInt(t1)) | ||||||
| 		t.Error("get int from int error") |  | ||||||
| 	} |  | ||||||
| 	var t2 int32 = 32 | 	var t2 int32 = 32 | ||||||
| 	if 32 != GetInt(t2) { | 	assert.Equal(t, 32, GetInt(t2)) | ||||||
| 		t.Error("get int from int32 error") | 
 | ||||||
| 	} |  | ||||||
| 	var t3 int64 = 64 | 	var t3 int64 = 64 | ||||||
| 	if 64 != GetInt(t3) { | 	assert.Equal(t, 64, GetInt(t3)) | ||||||
| 		t.Error("get int from int64 error") | 	t4 := "128" | ||||||
| 	} | 
 | ||||||
| 	var t4 = "128" | 	assert.Equal(t, 128, GetInt(t4)) | ||||||
| 	if 128 != GetInt(t4) { | 	assert.Equal(t, 0, GetInt(nil)) | ||||||
| 		t.Error("get int from num string error") |  | ||||||
| 	} |  | ||||||
| 	if 0 != GetInt(nil) { |  | ||||||
| 		t.Error("get int from nil error") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestGetInt64(t *testing.T) { | func TestGetInt64(t *testing.T) { | ||||||
| 	var i int64 = 1 | 	var i int64 = 1 | ||||||
| 	var t1 = 1 | 	t1 := 1 | ||||||
| 	if i != GetInt64(t1) { | 	assert.Equal(t, i, GetInt64(t1)) | ||||||
| 		t.Error("get int64 from int error") |  | ||||||
| 	} |  | ||||||
| 	var t2 int32 = 1 | 	var t2 int32 = 1 | ||||||
| 	if i != GetInt64(t2) { | 
 | ||||||
| 		t.Error("get int64 from int32 error") | 	assert.Equal(t, i, GetInt64(t2)) | ||||||
| 	} |  | ||||||
| 	var t3 int64 = 1 | 	var t3 int64 = 1 | ||||||
| 	if i != GetInt64(t3) { | 	assert.Equal(t, i, GetInt64(t3)) | ||||||
| 		t.Error("get int64 from int64 error") | 	t4 := "1" | ||||||
| 	} | 	assert.Equal(t, i, GetInt64(t4)) | ||||||
| 	var t4 = "1" | 	assert.Equal(t, int64(0), GetInt64(nil)) | ||||||
| 	if i != GetInt64(t4) { |  | ||||||
| 		t.Error("get int64 from num string error") |  | ||||||
| 	} |  | ||||||
| 	if 0 != GetInt64(nil) { |  | ||||||
| 		t.Error("get int64 from nil") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestGetFloat64(t *testing.T) { | func TestGetFloat64(t *testing.T) { | ||||||
| 	var f = 1.11 | 	f := 1.11 | ||||||
| 	var t1 float32 = 1.11 | 	var t1 float32 = 1.11 | ||||||
| 	if f != GetFloat64(t1) { | 	assert.Equal(t, f, GetFloat64(t1)) | ||||||
| 		t.Error("get float64 from float32 error") | 	t2 := 1.11 | ||||||
| 	} | 	assert.Equal(t, f, GetFloat64(t2)) | ||||||
| 	var t2 = 1.11 | 	t3 := "1.11" | ||||||
| 	if f != GetFloat64(t2) { | 	assert.Equal(t, f, GetFloat64(t3)) | ||||||
| 		t.Error("get float64 from float64 error") |  | ||||||
| 	} |  | ||||||
| 	var t3 = "1.11" |  | ||||||
| 	if f != GetFloat64(t3) { |  | ||||||
| 		t.Error("get float64 from string error") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	var f2 float64 = 1 | 	var f2 float64 = 1 | ||||||
| 	var t4 = 1 | 	t4 := 1 | ||||||
| 	if f2 != GetFloat64(t4) { | 	assert.Equal(t, f2, GetFloat64(t4)) | ||||||
| 		t.Error("get float64 from int error") |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	if 0 != GetFloat64(nil) { | 	assert.Equal(t, float64(0), GetFloat64(nil)) | ||||||
| 		t.Error("get float64 from nil error") |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestGetBool(t *testing.T) { | func TestGetBool(t *testing.T) { | ||||||
| 	var t1 = true | 	t1 := true | ||||||
| 	if !GetBool(t1) { | 	assert.True(t, GetBool(t1)) | ||||||
| 		t.Error("get bool from bool error") | 	t2 := "true" | ||||||
| 	} | 	assert.True(t, GetBool(t2)) | ||||||
| 	var t2 = "true" |  | ||||||
| 	if !GetBool(t2) { |  | ||||||
| 		t.Error("get bool from string error") |  | ||||||
| 	} |  | ||||||
| 	if GetBool(nil) { |  | ||||||
| 		t.Error("get bool from nil error") |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| func byteArrayEquals(a []byte, b []byte) bool { | 	assert.False(t, GetBool(nil)) | ||||||
| 	if len(a) != len(b) { |  | ||||||
| 		return false |  | ||||||
| 	} |  | ||||||
| 	for i, v := range a { |  | ||||||
| 		if v != b[i] { |  | ||||||
| 			return false |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 	return true |  | ||||||
| } | } | ||||||
|  | |||||||
							
								
								
									
										176
									
								
								client/cache/error_code.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								client/cache/error_code.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,176 @@ | |||||||
|  | // Copyright 2021 beego | ||||||
|  | // | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | // you may not use this file except in compliance with the License. | ||||||
|  | // You may obtain a copy of the License at | ||||||
|  | // | ||||||
|  | // http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | // | ||||||
|  | // Unless required by applicable law or agreed to in writing, software | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | // See the License for the specific language governing permissions and | ||||||
|  | // limitations under the License. | ||||||
|  | 
 | ||||||
|  | package cache | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"github.com/beego/beego/v2/core/berror" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | var NilCacheAdapter = berror.DefineCode(4002001, moduleName, "NilCacheAdapter", ` | ||||||
|  | It means that you register cache adapter by pass nil. | ||||||
|  | A cache adapter is an instance of Cache interface.  | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var DuplicateAdapter = berror.DefineCode(4002002, moduleName, "DuplicateAdapter", ` | ||||||
|  | You register two adapter with same name. In beego cache module, one name one adapter. | ||||||
|  | Once you got this error, please check the error stack, search adapter  | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var UnknownAdapter = berror.DefineCode(4002003, moduleName, "UnknownAdapter", ` | ||||||
|  | Unknown adapter, do you forget to register the adapter? | ||||||
|  | You must register adapter before use it. For example, if you want to use redis implementation,  | ||||||
|  | you must import the cache/redis package. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var IncrementOverflow = berror.DefineCode(4002004, moduleName, "IncrementOverflow", ` | ||||||
|  | The increment operation will overflow. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var DecrementOverflow = berror.DefineCode(4002005, moduleName, "DecrementOverflow", ` | ||||||
|  | The decrement operation will overflow. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var NotIntegerType = berror.DefineCode(4002006, moduleName, "NotIntegerType", ` | ||||||
|  | The type of value is not (u)int (u)int32 (u)int64.  | ||||||
|  | When you want to call Incr or Decr function of Cache API, you must confirm that the value's type is one of (u)int (u)int32 (u)int64. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var InvalidFileCacheDirectoryLevelCfg = berror.DefineCode(4002007, moduleName, "InvalidFileCacheDirectoryLevelCfg", ` | ||||||
|  | You pass invalid DirectoryLevel parameter when you try to StartAndGC file cache instance. | ||||||
|  | This parameter must be a integer, and please check your input. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var InvalidFileCacheEmbedExpiryCfg = berror.DefineCode(4002008, moduleName, "InvalidFileCacheEmbedExpiryCfg", ` | ||||||
|  | You pass invalid EmbedExpiry parameter when you try to StartAndGC file cache instance. | ||||||
|  | This parameter must be a integer, and please check your input. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var CreateFileCacheDirFailed = berror.DefineCode(4002009, moduleName, "CreateFileCacheDirFailed", ` | ||||||
|  | Beego failed to create file cache directory. There are two cases: | ||||||
|  | 1. You pass invalid CachePath parameter. Please check your input. | ||||||
|  | 2. Beego doesn't have the permission to create this directory. Please check your file mode. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var InvalidFileCachePath = berror.DefineCode(4002010, moduleName, "InvalidFilePath", ` | ||||||
|  | The file path of FileCache is invalid. Please correct the config. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var ReadFileCacheContentFailed = berror.DefineCode(4002011, moduleName, "ReadFileCacheContentFailed", ` | ||||||
|  | Usually you won't got this error. It means that Beego cannot read the data from the file. | ||||||
|  | You need to check whether the file exist. Sometimes it may be deleted by other processes. | ||||||
|  | If the file exists, please check the permission that Beego is able to read data from the file. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var InvalidGobEncodedData = berror.DefineCode(4002012, moduleName, "InvalidEncodedData", ` | ||||||
|  | The data is invalid. When you try to decode the invalid data, you got this error. | ||||||
|  | Please confirm that the data is encoded by GOB correctly. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var GobEncodeDataFailed = berror.DefineCode(4002013, moduleName, "GobEncodeDataFailed", ` | ||||||
|  | Beego could not encode the data to GOB byte array. In general, the data type is invalid.  | ||||||
|  | For example, GOB doesn't support function type. | ||||||
|  | Basic types, string, structure, structure pointer are supported.  | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var KeyExpired = berror.DefineCode(4002014, moduleName, "KeyExpired", ` | ||||||
|  | Cache key is expired. | ||||||
|  | You should notice that, a key is expired and then it may be deleted by GC goroutine.  | ||||||
|  | So when you query a key which may be expired, you may got this code, or KeyNotExist. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var KeyNotExist = berror.DefineCode(4002015, moduleName, "KeyNotExist", ` | ||||||
|  | Key not found. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var MultiGetFailed = berror.DefineCode(4002016, moduleName, "MultiGetFailed", ` | ||||||
|  | Get multiple keys failed. Please check the detail msg to find out the root cause. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var InvalidMemoryCacheCfg = berror.DefineCode(4002017, moduleName, "InvalidMemoryCacheCfg", ` | ||||||
|  | The config is invalid. Please check your input. It must be a json string. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var InvalidMemCacheCfg = berror.DefineCode(4002018, moduleName, "InvalidMemCacheCfg", ` | ||||||
|  | The config is invalid. Please check your input, it must be json string and contains "conn" field. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var InvalidMemCacheValue = berror.DefineCode(4002019, moduleName, "InvalidMemCacheValue", ` | ||||||
|  | The value must be string or byte[], please check your input. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var InvalidRedisCacheCfg = berror.DefineCode(4002020, moduleName, "InvalidRedisCacheCfg", ` | ||||||
|  | The config must be json string, and has "conn" field. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var InvalidSsdbCacheCfg = berror.DefineCode(4002021, moduleName, "InvalidSsdbCacheCfg", ` | ||||||
|  | The config must be json string, and has "conn" field. The value of "conn" field should be "host:port". | ||||||
|  | "port" must be a valid integer. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var InvalidSsdbCacheValue = berror.DefineCode(4002022, moduleName, "InvalidSsdbCacheValue", ` | ||||||
|  | SSDB cache only accept string value. Please check your input. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var DeleteFileCacheItemFailed = berror.DefineCode(5002001, moduleName, "DeleteFileCacheItemFailed", ` | ||||||
|  | Beego try to delete file cache item failed.  | ||||||
|  | Please check whether Beego generated file correctly.  | ||||||
|  | And then confirm whether this file is already deleted by other processes or other people. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var MemCacheCurdFailed = berror.DefineCode(5002002, moduleName, "MemCacheError", ` | ||||||
|  | When you want to get, put, delete key-value from remote memcache servers, you may get error: | ||||||
|  | 1. You pass invalid servers address, so Beego could not connect to remote server; | ||||||
|  | 2. The servers address is correct, but there is some net issue. Typically there is some firewalls between application and memcache server; | ||||||
|  | 3. Key is invalid. The key's length should be less than 250 and must not contains special characters; | ||||||
|  | 4. The response from memcache server is invalid; | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var RedisCacheCurdFailed = berror.DefineCode(5002003, moduleName, "RedisCacheCurdFailed", ` | ||||||
|  | When Beego uses client to send request to redis server, it failed. | ||||||
|  | 1. The server addresses is invalid; | ||||||
|  | 2. Network issue, firewall issue or network is unstable; | ||||||
|  | 3. Client failed to manage connection. In extreme cases, Beego's redis client didn't maintain connections correctly, for example, Beego try to send request via closed connection; | ||||||
|  | 4. The request are huge and redis server spent too much time to process it, and client is timeout; | ||||||
|  | 
 | ||||||
|  | In general, if you always got this error whatever you do, in most cases, it was caused by network issue.  | ||||||
|  | You could check your network state, and confirm that firewall rules are correct. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var InvalidConnection = berror.DefineCode(5002004, moduleName, "InvalidConnection", ` | ||||||
|  | The connection is invalid. Please check your connection info, network, firewall. | ||||||
|  | You could simply uses ping, telnet or write some simple tests to test network. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var DialFailed = berror.DefineCode(5002005, moduleName, "DialFailed", ` | ||||||
|  | When Beego try to dial to remote servers, it failed. Please check your connection info and network state, server state. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var SsdbCacheCurdFailed = berror.DefineCode(5002006, moduleName, "SsdbCacheCurdFailed", ` | ||||||
|  | When you try to use SSDB cache, it failed. There are many cases: | ||||||
|  | 1. servers unavailable; | ||||||
|  | 2. network issue, including network unstable, firewall; | ||||||
|  | 3. connection issue; | ||||||
|  | 4. request are huge and servers spent too much time to process it, got timeout; | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var SsdbBadResponse = berror.DefineCode(5002007, moduleName, "SsdbBadResponse", ` | ||||||
|  | The reponse from SSDB server is invalid.  | ||||||
|  | Usually it indicates something wrong on server side. | ||||||
|  | `) | ||||||
|  | 
 | ||||||
|  | var ( | ||||||
|  | 	ErrKeyExpired  = berror.Error(KeyExpired, "the key is expired") | ||||||
|  | 	ErrKeyNotExist = berror.Error(KeyNotExist, "the key isn't exist") | ||||||
|  | ) | ||||||
							
								
								
									
										198
									
								
								client/cache/file.go
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										198
									
								
								client/cache/file.go
									
									
									
									
										vendored
									
									
								
							| @ -30,7 +30,7 @@ import ( | |||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
| 	"github.com/pkg/errors" | 	"github.com/beego/beego/v2/core/berror" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| // FileCacheItem is basic unit of file cache adapter which | // FileCacheItem is basic unit of file cache adapter which | ||||||
| @ -67,44 +67,65 @@ func NewFileCache() Cache { | |||||||
| // StartAndGC starts gc for file cache. | // StartAndGC starts gc for file cache. | ||||||
| // config must be in the format {CachePath:"/cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"} | // config must be in the format {CachePath:"/cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"} | ||||||
| func (fc *FileCache) StartAndGC(config string) error { | func (fc *FileCache) StartAndGC(config string) error { | ||||||
| 
 |  | ||||||
| 	cfg := make(map[string]string) | 	cfg := make(map[string]string) | ||||||
| 	err := json.Unmarshal([]byte(config), &cfg) | 	err := json.Unmarshal([]byte(config), &cfg) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	if _, ok := cfg["CachePath"]; !ok { |  | ||||||
| 		cfg["CachePath"] = FileCachePath |  | ||||||
| 	} |  | ||||||
| 	if _, ok := cfg["FileSuffix"]; !ok { |  | ||||||
| 		cfg["FileSuffix"] = FileCacheFileSuffix |  | ||||||
| 	} |  | ||||||
| 	if _, ok := cfg["DirectoryLevel"]; !ok { |  | ||||||
| 		cfg["DirectoryLevel"] = strconv.Itoa(FileCacheDirectoryLevel) |  | ||||||
| 	} |  | ||||||
| 	if _, ok := cfg["EmbedExpiry"]; !ok { |  | ||||||
| 		cfg["EmbedExpiry"] = strconv.FormatInt(int64(FileCacheEmbedExpiry.Seconds()), 10) |  | ||||||
| 	} |  | ||||||
| 	fc.CachePath = cfg["CachePath"] |  | ||||||
| 	fc.FileSuffix = cfg["FileSuffix"] |  | ||||||
| 	fc.DirectoryLevel, _ = strconv.Atoi(cfg["DirectoryLevel"]) |  | ||||||
| 	fc.EmbedExpiry, _ = strconv.Atoi(cfg["EmbedExpiry"]) |  | ||||||
| 
 | 
 | ||||||
| 	fc.Init() | 	const cpKey = "CachePath" | ||||||
| 	return nil | 	const fsKey = "FileSuffix" | ||||||
|  | 	const dlKey = "DirectoryLevel" | ||||||
|  | 	const eeKey = "EmbedExpiry" | ||||||
|  | 
 | ||||||
|  | 	if _, ok := cfg[cpKey]; !ok { | ||||||
|  | 		cfg[cpKey] = FileCachePath | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if _, ok := cfg[fsKey]; !ok { | ||||||
|  | 		cfg[fsKey] = FileCacheFileSuffix | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if _, ok := cfg[dlKey]; !ok { | ||||||
|  | 		cfg[dlKey] = strconv.Itoa(FileCacheDirectoryLevel) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if _, ok := cfg[eeKey]; !ok { | ||||||
|  | 		cfg[eeKey] = strconv.FormatInt(int64(FileCacheEmbedExpiry.Seconds()), 10) | ||||||
|  | 	} | ||||||
|  | 	fc.CachePath = cfg[cpKey] | ||||||
|  | 	fc.FileSuffix = cfg[fsKey] | ||||||
|  | 	fc.DirectoryLevel, err = strconv.Atoi(cfg[dlKey]) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return berror.Wrapf(err, InvalidFileCacheDirectoryLevelCfg, | ||||||
|  | 			"invalid directory level config, please check your input, it must be integer: %s", cfg[dlKey]) | ||||||
|  | 	} | ||||||
|  | 	fc.EmbedExpiry, err = strconv.Atoi(cfg[eeKey]) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return berror.Wrapf(err, InvalidFileCacheEmbedExpiryCfg, | ||||||
|  | 			"invalid embed expiry config, please check your input, it must be integer: %s", cfg[eeKey]) | ||||||
|  | 	} | ||||||
|  | 	return fc.Init() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Init makes new a dir for file cache if it does not already exist | // Init makes new a dir for file cache if it does not already exist | ||||||
| func (fc *FileCache) Init() { | func (fc *FileCache) Init() error { | ||||||
| 	if ok, _ := exists(fc.CachePath); !ok { // todo : error handle | 	ok, err := exists(fc.CachePath) | ||||||
| 		_ = os.MkdirAll(fc.CachePath, os.ModePerm) // todo : error handle | 	if err != nil || ok { | ||||||
|  | 		return err | ||||||
| 	} | 	} | ||||||
|  | 	err = os.MkdirAll(fc.CachePath, os.ModePerm) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return berror.Wrapf(err, CreateFileCacheDirFailed, | ||||||
|  | 			"could not create directory, please check the config [%s] and file mode.", fc.CachePath) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // getCachedFilename returns an md5 encoded file name. | // getCachedFilename returns an md5 encoded file name. | ||||||
| func (fc *FileCache) getCacheFileName(key string) string { | func (fc *FileCache) getCacheFileName(key string) (string, error) { | ||||||
| 	m := md5.New() | 	m := md5.New() | ||||||
| 	io.WriteString(m, key) | 	_, _ = io.WriteString(m, key) | ||||||
| 	keyMd5 := hex.EncodeToString(m.Sum(nil)) | 	keyMd5 := hex.EncodeToString(m.Sum(nil)) | ||||||
| 	cachePath := fc.CachePath | 	cachePath := fc.CachePath | ||||||
| 	switch fc.DirectoryLevel { | 	switch fc.DirectoryLevel { | ||||||
| @ -113,18 +134,29 @@ func (fc *FileCache) getCacheFileName(key string) string { | |||||||
| 	case 1: | 	case 1: | ||||||
| 		cachePath = filepath.Join(cachePath, keyMd5[0:2]) | 		cachePath = filepath.Join(cachePath, keyMd5[0:2]) | ||||||
| 	} | 	} | ||||||
| 
 | 	ok, err := exists(cachePath) | ||||||
| 	if ok, _ := exists(cachePath); !ok { // todo : error handle | 	if err != nil { | ||||||
| 		_ = os.MkdirAll(cachePath, os.ModePerm) // todo : error handle | 		return "", err | ||||||
|  | 	} | ||||||
|  | 	if !ok { | ||||||
|  | 		err = os.MkdirAll(cachePath, os.ModePerm) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return "", berror.Wrapf(err, CreateFileCacheDirFailed, | ||||||
|  | 				"could not create the directory: %s", cachePath) | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return filepath.Join(cachePath, fmt.Sprintf("%s%s", keyMd5, fc.FileSuffix)) | 	return filepath.Join(cachePath, fmt.Sprintf("%s%s", keyMd5, fc.FileSuffix)), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Get value from file cache. | // Get value from file cache. | ||||||
| // if nonexistent or expired return an empty string. | // if nonexistent or expired return an empty string. | ||||||
| func (fc *FileCache) Get(ctx context.Context, key string) (interface{}, error) { | func (fc *FileCache) Get(ctx context.Context, key string) (interface{}, error) { | ||||||
| 	fileData, err := FileGetContents(fc.getCacheFileName(key)) | 	fn, err := fc.getCacheFileName(key) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	fileData, err := FileGetContents(fn) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
| @ -136,7 +168,7 @@ func (fc *FileCache) Get(ctx context.Context, key string) (interface{}, error) { | |||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if to.Expired.Before(time.Now()) { | 	if to.Expired.Before(time.Now()) { | ||||||
| 		return nil, errors.New("The key is expired") | 		return nil, ErrKeyExpired | ||||||
| 	} | 	} | ||||||
| 	return to.Data, nil | 	return to.Data, nil | ||||||
| } | } | ||||||
| @ -159,7 +191,7 @@ func (fc *FileCache) GetMulti(ctx context.Context, keys []string) ([]interface{} | |||||||
| 	if len(keysErr) == 0 { | 	if len(keysErr) == 0 { | ||||||
| 		return rc, nil | 		return rc, nil | ||||||
| 	} | 	} | ||||||
| 	return rc, errors.New(strings.Join(keysErr, "; ")) | 	return rc, berror.Error(MultiGetFailed, strings.Join(keysErr, "; ")) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Put value into file cache. | // Put value into file cache. | ||||||
| @ -179,14 +211,26 @@ func (fc *FileCache) Put(ctx context.Context, key string, val interface{}, timeo | |||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 	return FilePutContents(fc.getCacheFileName(key), data) | 
 | ||||||
|  | 	fn, err := fc.getCacheFileName(key) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 	return FilePutContents(fn, data) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Delete file cache value. | // Delete file cache value. | ||||||
| func (fc *FileCache) Delete(ctx context.Context, key string) error { | func (fc *FileCache) Delete(ctx context.Context, key string) error { | ||||||
| 	filename := fc.getCacheFileName(key) | 	filename, err := fc.getCacheFileName(key) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
| 	if ok, _ := exists(filename); ok { | 	if ok, _ := exists(filename); ok { | ||||||
| 		return os.Remove(filename) | 		err = os.Remove(filename) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return berror.Wrapf(err, DeleteFileCacheItemFailed, | ||||||
|  | 				"can not delete this file cache key-value, key is %s and file name is %s", key, filename) | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
| @ -199,25 +243,12 @@ func (fc *FileCache) Incr(ctx context.Context, key string) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var res interface{} | 	val, err := incr(data) | ||||||
| 	switch val := data.(type) { | 	if err != nil { | ||||||
| 	case int: | 		return err | ||||||
| 		res = val + 1 |  | ||||||
| 	case int32: |  | ||||||
| 		res = val + 1 |  | ||||||
| 	case int64: |  | ||||||
| 		res = val + 1 |  | ||||||
| 	case uint: |  | ||||||
| 		res = val + 1 |  | ||||||
| 	case uint32: |  | ||||||
| 		res = val + 1 |  | ||||||
| 	case uint64: |  | ||||||
| 		res = val + 1 |  | ||||||
| 	default: |  | ||||||
| 		return errors.Errorf("data is not (u)int (u)int32 (u)int64") |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return fc.Put(context.Background(), key, res, time.Duration(fc.EmbedExpiry)) | 	return fc.Put(context.Background(), key, val, time.Duration(fc.EmbedExpiry)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Decr decreases cached int value. | // Decr decreases cached int value. | ||||||
| @ -227,43 +258,21 @@ func (fc *FileCache) Decr(ctx context.Context, key string) error { | |||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	var res interface{} | 	val, err := decr(data) | ||||||
| 	switch val := data.(type) { | 	if err != nil { | ||||||
| 	case int: | 		return err | ||||||
| 		res = val - 1 |  | ||||||
| 	case int32: |  | ||||||
| 		res = val - 1 |  | ||||||
| 	case int64: |  | ||||||
| 		res = val - 1 |  | ||||||
| 	case uint: |  | ||||||
| 		if val > 0 { |  | ||||||
| 			res = val - 1 |  | ||||||
| 		} else { |  | ||||||
| 			return errors.New("data val is less than 0") |  | ||||||
| 		} |  | ||||||
| 	case uint32: |  | ||||||
| 		if val > 0 { |  | ||||||
| 			res = val - 1 |  | ||||||
| 		} else { |  | ||||||
| 			return errors.New("data val is less than 0") |  | ||||||
| 		} |  | ||||||
| 	case uint64: |  | ||||||
| 		if val > 0 { |  | ||||||
| 			res = val - 1 |  | ||||||
| 		} else { |  | ||||||
| 			return errors.New("data val is less than 0") |  | ||||||
| 		} |  | ||||||
| 	default: |  | ||||||
| 		return errors.Errorf("data is not (u)int (u)int32 (u)int64") |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	return fc.Put(context.Background(), key, res, time.Duration(fc.EmbedExpiry)) | 	return fc.Put(context.Background(), key, val, time.Duration(fc.EmbedExpiry)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // IsExist checks if value exists. | // IsExist checks if value exists. | ||||||
| func (fc *FileCache) IsExist(ctx context.Context, key string) (bool, error) { | func (fc *FileCache) IsExist(ctx context.Context, key string) (bool, error) { | ||||||
| 	ret, _ := exists(fc.getCacheFileName(key)) | 	fn, err := fc.getCacheFileName(key) | ||||||
| 	return ret, nil | 	if err != nil { | ||||||
|  | 		return false, err | ||||||
|  | 	} | ||||||
|  | 	return exists(fn) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // ClearAll cleans cached files (not implemented) | // ClearAll cleans cached files (not implemented) | ||||||
| @ -280,13 +289,19 @@ func exists(path string) (bool, error) { | |||||||
| 	if os.IsNotExist(err) { | 	if os.IsNotExist(err) { | ||||||
| 		return false, nil | 		return false, nil | ||||||
| 	} | 	} | ||||||
| 	return false, err | 	return false, berror.Wrapf(err, InvalidFileCachePath, "file cache path is invalid: %s", path) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // FileGetContents Reads bytes from a file. | // FileGetContents Reads bytes from a file. | ||||||
| // if non-existent, create this file. | // if non-existent, create this file. | ||||||
| func FileGetContents(filename string) (data []byte, e error) { | func FileGetContents(filename string) ([]byte, error) { | ||||||
| 	return ioutil.ReadFile(filename) | 	data, err := ioutil.ReadFile(filename) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, berror.Wrapf(err, ReadFileCacheContentFailed, | ||||||
|  | 			"could not read the data from the file: %s, "+ | ||||||
|  | 				"please confirm that file exist and Beego has the permission to read the content.", filename) | ||||||
|  | 	} | ||||||
|  | 	return data, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // FilePutContents puts bytes into a file. | // FilePutContents puts bytes into a file. | ||||||
| @ -301,16 +316,21 @@ func GobEncode(data interface{}) ([]byte, error) { | |||||||
| 	enc := gob.NewEncoder(buf) | 	enc := gob.NewEncoder(buf) | ||||||
| 	err := enc.Encode(data) | 	err := enc.Encode(data) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, berror.Wrap(err, GobEncodeDataFailed, "could not encode this data") | ||||||
| 	} | 	} | ||||||
| 	return buf.Bytes(), err | 	return buf.Bytes(), nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // GobDecode Gob decodes a file cache item. | // GobDecode Gob decodes a file cache item. | ||||||
| func GobDecode(data []byte, to *FileCacheItem) error { | func GobDecode(data []byte, to *FileCacheItem) error { | ||||||
| 	buf := bytes.NewBuffer(data) | 	buf := bytes.NewBuffer(data) | ||||||
| 	dec := gob.NewDecoder(buf) | 	dec := gob.NewDecoder(buf) | ||||||
| 	return dec.Decode(&to) | 	err := dec.Decode(&to) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return berror.Wrap(err, InvalidGobEncodedData, | ||||||
|  | 			"could not decode this data to FileCacheItem. Make sure that the data is encoded by GOB.") | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func init() { | func init() { | ||||||
|  | |||||||
							
								
								
									
										108
									
								
								client/cache/file_test.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								client/cache/file_test.go
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,108 @@ | |||||||
|  | // Copyright 2021 beego | ||||||
|  | // | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | // you may not use this file except in compliance with the License. | ||||||
|  | // You may obtain a copy of the License at | ||||||
|  | // | ||||||
|  | // http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | // | ||||||
|  | // Unless required by applicable law or agreed to in writing, software | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | // See the License for the specific language governing permissions and | ||||||
|  | // limitations under the License. | ||||||
|  | 
 | ||||||
|  | package cache | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"context" | ||||||
|  | 	"fmt" | ||||||
|  | 	"os" | ||||||
|  | 	"path/filepath" | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/stretchr/testify/assert" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestFileCacheStartAndGC(t *testing.T) { | ||||||
|  | 	fc := NewFileCache().(*FileCache) | ||||||
|  | 	err := fc.StartAndGC(`{`) | ||||||
|  | 	assert.NotNil(t, err) | ||||||
|  | 	err = fc.StartAndGC(`{}`) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 
 | ||||||
|  | 	assert.Equal(t, fc.CachePath, FileCachePath) | ||||||
|  | 	assert.Equal(t, fc.DirectoryLevel, FileCacheDirectoryLevel) | ||||||
|  | 	assert.Equal(t, fc.EmbedExpiry, int(FileCacheEmbedExpiry)) | ||||||
|  | 	assert.Equal(t, fc.FileSuffix, FileCacheFileSuffix) | ||||||
|  | 
 | ||||||
|  | 	err = fc.StartAndGC(`{"CachePath":"/cache","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"}`) | ||||||
|  | 	// could not create dir | ||||||
|  | 	assert.NotNil(t, err) | ||||||
|  | 
 | ||||||
|  | 	str := getTestCacheFilePath() | ||||||
|  | 	err = fc.StartAndGC(fmt.Sprintf(`{"CachePath":"%s","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"0"}`, str)) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, fc.CachePath, str) | ||||||
|  | 	assert.Equal(t, fc.DirectoryLevel, 2) | ||||||
|  | 	assert.Equal(t, fc.EmbedExpiry, 0) | ||||||
|  | 	assert.Equal(t, fc.FileSuffix, ".bin") | ||||||
|  | 
 | ||||||
|  | 	err = fc.StartAndGC(fmt.Sprintf(`{"CachePath":"%s","FileSuffix":".bin","DirectoryLevel":"aaa","EmbedExpiry":"0"}`, str)) | ||||||
|  | 	assert.NotNil(t, err) | ||||||
|  | 
 | ||||||
|  | 	err = fc.StartAndGC(fmt.Sprintf(`{"CachePath":"%s","FileSuffix":".bin","DirectoryLevel":"2","EmbedExpiry":"aaa"}`, str)) | ||||||
|  | 	assert.NotNil(t, err) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestFileCacheInit(t *testing.T) { | ||||||
|  | 	fc := NewFileCache().(*FileCache) | ||||||
|  | 	fc.CachePath = "////aaa" | ||||||
|  | 	err := fc.Init() | ||||||
|  | 	assert.NotNil(t, err) | ||||||
|  | 	fc.CachePath = getTestCacheFilePath() | ||||||
|  | 	err = fc.Init() | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestFileGetContents(t *testing.T) { | ||||||
|  | 	_, err := FileGetContents("/bin/aaa") | ||||||
|  | 	assert.NotNil(t, err) | ||||||
|  | 	fn := filepath.Join(os.TempDir(), "fileCache.txt") | ||||||
|  | 	f, err := os.Create(fn) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	_, err = f.WriteString("text") | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	data, err := FileGetContents(fn) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, "text", string(data)) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestGobEncodeDecode(t *testing.T) { | ||||||
|  | 	_, err := GobEncode(func() { | ||||||
|  | 		fmt.Print("test func") | ||||||
|  | 	}) | ||||||
|  | 	assert.NotNil(t, err) | ||||||
|  | 	data, err := GobEncode(&FileCacheItem{ | ||||||
|  | 		Data: "hello", | ||||||
|  | 	}) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	err = GobDecode([]byte("wrong data"), &FileCacheItem{}) | ||||||
|  | 	assert.NotNil(t, err) | ||||||
|  | 	dci := &FileCacheItem{} | ||||||
|  | 	err = GobDecode(data, dci) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	assert.Equal(t, "hello", dci.Data) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestFileCacheDelete(t *testing.T) { | ||||||
|  | 	fc := NewFileCache() | ||||||
|  | 	err := fc.StartAndGC(`{}`) | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | 	err = fc.Delete(context.Background(), "my-key") | ||||||
|  | 	assert.Nil(t, err) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func getTestCacheFilePath() string { | ||||||
|  | 	return filepath.Join(os.TempDir(), "test", "file.txt") | ||||||
|  | } | ||||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user