git.iko.soy/typeable/minio-hs
on master help sign in
CI: Add support for GHC 8.10, stack and live-server testing (#156)

* CI: Add support for GHC 8.10, stack and live-server testing * Fix live-server tests for all platforms * Fix windows tests * Fix resourcet cleanup exceptions * Mark minio-hs builds GHC 8.4, 8.8 on windows experimental * Use minio with erasure code backend for tests * Fix matrix combinations for cabal and stack Co-authored-by: Krishnan Parthasarathi <kp@minio.io>

commita3538aa46ccf5d3814d89daa6aecd1ddfe2175aa authorAditya Manthramurthy <donatello@users.noreply.github.com> dateWed 24 Jun 2020, 10:35 (6 years ago) parent3dd235a
6 files changed+318−95
.github/workflows/haskell-cabal.yml+119 .github/workflows/haskell-stack.yml+105 .github/workflows/haskell.yml−54 test/LiveServer.hs+47−41 test/cert/private.key+28 test/cert/public.crt+19
.github/workflows/haskell-cabal.ymlnew file+119
@@ -0,0 +1,119 @@
1+name: Haskell CI (Cabal)
2+
3+on:
4+ schedule:
5+ # Run every weekday
6+ - cron: '0 0 * * 1-5'
7+ push:
8+ branches: [ master ]
9+ pull_request:
10+ branches: [ master ]
11+
12+jobs:
13+ cabal-build:
14+
15+ runs-on: ${{ matrix.os }}
16+ continue-on-error: ${{ matrix.experimental }}
17+ strategy:
18+ fail-fast: false
19+ matrix:
20+ ghc: ['8.4', '8.6', '8.8', '8.10']
21+ cabal: ['3.2']
22+ os: [ubuntu-latest, macOS-latest]
23+ experimental: [false]
24+ include:
25+ - ghc: '8.6'
26+ cabal: '3.2'
27+ os: windows-latest
28+ experimental: false
29+ - ghc: '8.10'
30+ cabal: '3.2'
31+ os: windows-latest
32+ experimental: false
33+
34+ # Appears to be buggy to build in windows with ghc 8.4 and 8.8
35+ - ghc: '8.4'
36+ cabal: '3.2'
37+ os: windows-latest
38+ experimental: true
39+ - ghc: '8.8'
40+ cabal: '3.2'
41+ os: windows-latest
42+ experimental: true
43+
44+ steps:
45+ - uses: actions/checkout@v2
46+ - uses: actions/setup-haskell@v1.1
47+ with:
48+ ghc-version: ${{ matrix.ghc }}
49+ cabal-version: ${{ matrix.cabal }}
50+
51+ - name: Cache
52+ uses: actions/cache@v2
53+ env:
54+ cache-name: cabal-cache-${{ matrix.ghc }}-${{ matrix.cabal }}
55+ with:
56+ path: |
57+ ~/.cabal
58+ ~/.stack
59+ key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/*.cabal') }}-${{ hashFiles('**/stack.yaml') }}
60+ restore-keys: |
61+ ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/*.cabal') }}-${{ hashFiles('**/stack.yaml') }}
62+ ${{ runner.os }}-build-${{ env.cache-name }}-
63+ ${{ runner.os }}-build-
64+ ${{ runner.os }}-
65+
66+ - name: Before install (Linux)
67+ if: matrix.os == 'ubuntu-latest'
68+ run: |
69+ mkdir -p /tmp/minio /tmp/minio-config/certs
70+ cp test/cert/* /tmp/minio-config/certs/
71+ (cd /tmp/minio; wget -q https://dl.min.io/server/minio/release/linux-amd64/minio; chmod +x ./minio)
72+ sudo cp /tmp/minio-config/certs/public.crt /usr/local/share/ca-certificates/
73+ sudo update-ca-certificates
74+
75+ - name: Before install (MacOS)
76+ if: matrix.os == 'macos-latest'
77+ run: |
78+ mkdir -p /tmp/minio /tmp/minio-config/certs
79+ cp test/cert/* /tmp/minio-config/certs/
80+ (cd /tmp/minio; wget -q https://dl.min.io/server/minio/release/darwin-amd64/minio; chmod +x ./minio)
81+ sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /tmp/minio-config/certs/public.crt
82+
83+ - name: Before install (Windows)
84+ if: matrix.os == 'windows-latest'
85+ run: |
86+ New-Item -ItemType Directory -Path "$env:temp/minio-config/certs/"
87+ Copy-Item -Path test\cert\* -Destination "$env:temp/minio-config/certs/"
88+ Invoke-WebRequest -Uri https://dl.minio.io/server/minio/release/windows-amd64/minio.exe -OutFile $HOME/minio.exe
89+ Import-Certificate -FilePath "$env:temp/minio-config/certs/public.crt" -CertStoreLocation Cert:\LocalMachine\Root
90+
91+ - name: Install dependencies, build and test (Non-Windows)
92+ if: matrix.os != 'windows-latest'
93+ env:
94+ MINIO_ACCESS_KEY: minio
95+ MINIO_SECRET_KEY: minio123
96+ MINIO_LOCAL: 1
97+ MINIO_SECURE: 1
98+ run: |
99+ /tmp/minio/minio server --quiet --certs-dir /tmp/minio-config/certs data1 data2 data3 data4 2>&1 > minio.log &
100+ ghc --version
101+ cabal --version
102+ cabal new-update
103+ cabal new-build --enable-tests --enable-benchmarks -fexamples
104+ cabal new-test --enable-tests -flive-test
105+
106+ - name: Install dependencies, build and test (Windows)
107+ if: matrix.os == 'windows-latest'
108+ env:
109+ MINIO_ACCESS_KEY: minio
110+ MINIO_SECRET_KEY: minio123
111+ MINIO_LOCAL: 1
112+ MINIO_SECURE: 1
113+ run: |
114+ Start-Process -NoNewWindow -FilePath "$HOME/minio.exe" -ArgumentList "--certs-dir", "$env:temp/minio-config/certs", "server", "$env:temp/data1", "$env:temp/data2", "$env:temp/data3", "$env:temp/data4"
115+ ghc --version
116+ cabal --version
117+ cabal new-update
118+ cabal new-build --enable-tests --enable-benchmarks -fexamples
119+ cabal new-test --enable-tests -flive-test
.github/workflows/haskell-stack.ymlnew file+105
@@ -0,0 +1,105 @@
1+name: Haskell CI (Stack)
2+
3+on:
4+ schedule:
5+ # Run every weekday
6+ - cron: '0 0 * * 1-5'
7+ push:
8+ branches: [ master ]
9+ pull_request:
10+ branches: [ master ]
11+
12+jobs:
13+ stack-build:
14+
15+ runs-on: ${{ matrix.os }}
16+ continue-on-error: ${{ matrix.experimental }}
17+ strategy:
18+ fail-fast: false
19+ matrix:
20+ ghc: ['8.8']
21+ cabal: ['3.2']
22+ os: [ubuntu-latest, macOS-latest]
23+ experimental: [false]
24+ include:
25+ # Appears to be buggy to build in windows with ghc 8.8
26+ - ghc: '8.8'
27+ cabal: '3.2'
28+ os: windows-latest
29+ experimental: true
30+
31+ steps:
32+ - uses: actions/checkout@v2
33+ - uses: actions/setup-haskell@v1.1
34+ with:
35+ ghc-version: ${{ matrix.ghc }}
36+ cabal-version: ${{ matrix.cabal }}
37+ enable-stack: true
38+
39+ - name: Cache
40+ uses: actions/cache@v2
41+ env:
42+ cache-name: stack-cache-${{ matrix.ghc }}-${{ matrix.cabal }}
43+ with:
44+ path: |
45+ ~/.cabal
46+ ~/.stack
47+ key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/*.cabal') }}-${{ hashFiles('**/stack.yaml') }}
48+ restore-keys: |
49+ ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/*.cabal') }}-${{ hashFiles('**/stack.yaml') }}
50+ ${{ runner.os }}-build-${{ env.cache-name }}-
51+ ${{ runner.os }}-build-
52+ ${{ runner.os }}-
53+
54+ - name: Before install (Linux)
55+ if: matrix.os == 'ubuntu-latest'
56+ run: |
57+ mkdir -p /tmp/minio /tmp/minio-config/certs
58+ cp test/cert/* /tmp/minio-config/certs/
59+ (cd /tmp/minio; wget -q https://dl.min.io/server/minio/release/linux-amd64/minio; chmod +x ./minio)
60+ sudo cp /tmp/minio-config/certs/public.crt /usr/local/share/ca-certificates/
61+ sudo update-ca-certificates
62+
63+ - name: Before install (MacOS)
64+ if: matrix.os == 'macos-latest'
65+ run: |
66+ mkdir -p /tmp/minio /tmp/minio-config/certs
67+ cp test/cert/* /tmp/minio-config/certs/
68+ (cd /tmp/minio; wget -q https://dl.min.io/server/minio/release/darwin-amd64/minio; chmod +x ./minio)
69+ sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain /tmp/minio-config/certs/public.crt
70+
71+ - name: Before install (Windows)
72+ if: matrix.os == 'windows-latest'
73+ run: |
74+ New-Item -ItemType Directory -Path "$env:temp/minio-config/certs/"
75+ Copy-Item -Path test\cert\* -Destination "$env:temp/minio-config/certs/"
76+ Invoke-WebRequest -Uri https://dl.minio.io/server/minio/release/windows-amd64/minio.exe -OutFile $HOME/minio.exe
77+ Import-Certificate -FilePath "$env:temp/minio-config/certs/public.crt" -CertStoreLocation Cert:\LocalMachine\Root
78+
79+ - name: Install dependencies, build and test (Non-Windows)
80+ if: matrix.os != 'windows-latest'
81+ env:
82+ MINIO_ACCESS_KEY: minio
83+ MINIO_SECRET_KEY: minio123
84+ MINIO_LOCAL: 1
85+ MINIO_SECURE: 1
86+ run: |
87+ /tmp/minio/minio server --quiet --certs-dir /tmp/minio-config/certs data1 data2 data3 data4 2>&1 > minio.log &
88+ ghc --version
89+ stack --version
90+ stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks --flag minio-hs:examples
91+ stack test --system-ghc --flag minio-hs:live-test
92+
93+ - name: Install dependencies, build and test (Windows)
94+ if: matrix.os == 'windows-latest'
95+ env:
96+ MINIO_ACCESS_KEY: minio
97+ MINIO_SECRET_KEY: minio123
98+ MINIO_LOCAL: 1
99+ MINIO_SECURE: 1
100+ run: |
101+ Start-Process -NoNewWindow -FilePath "$HOME/minio.exe" -ArgumentList "--certs-dir", "$env:temp/minio-config/certs", "server", "$env:temp/data1", "$env:temp/data2", "$env:temp/data3", "$env:temp/data4"
102+ ghc --version
103+ stack --version
104+ stack build --system-ghc --test --bench --no-run-tests --no-run-benchmarks --flag minio-hs:examples
105+ stack test --system-ghc --flag minio-hs:live-test
.github/workflows/haskell.ymldeleted−54
@@ -1,54 +0,0 @@
1−name: Haskell CI
2−
3−on:
4− push:
5− branches: [ master ]
6− pull_request:
7− branches: [ master ]
8−
9−jobs:
10− build:
11−
12− runs-on: ${{ matrix.os }}
13−
14− strategy:
15− fail-fast: false
16− matrix:
17− ghc: ['8.6.5', '8.8.3']
18− cabal: ['2.4', '3.0', '3.2']
19− os: [ubuntu-latest, macOS-latest, windows-latest]
20− exclude:
21− # GHC 8.8+ only works with cabal v3+
22− - ghc: 8.8.3
23− cabal: 2.4
24− # Appears to be buggy to build in windows
25− - ghc: 8.8.3
26− os: windows-latest
27−
28− steps:
29− - uses: actions/checkout@v2
30− - uses: actions/setup-haskell@v1.1
31− with:
32− ghc-version: ${{ matrix.ghc }}
33− cabal-version: ${{ matrix.cabal }}
34−
35− - name: Cache
36− uses: actions/cache@v1
37− env:
38− cache-name: cache-cabal
39− with:
40− path: ~/.cabal
41− key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/*.cabal') }}-${{ hashFiles('**/cabal.project') }}
42− restore-keys: |
43− ${{ runner.os }}-build-${{ env.cache-name }}-
44− ${{ runner.os }}-build-
45− ${{ runner.os }}-
46−
47− - name: Install dependencies
48− run: |
49− cabal v2-update
50− cabal v2-build --only-dependencies --enable-tests --enable-benchmarks
51− - name: Build
52− run: cabal v2-build --enable-tests --enable-benchmarks all
53− - name: Run tests
54− run: cabal v2-test all
test/LiveServer.hs+47−41
@@ -39,11 +39,11 @@ import Network.Minio.S3API
3939import Network.Minio.Utils
4040import System.Directory (getTemporaryDirectory)
4141import System.Environment (lookupEnv)
42−import qualified System.IO as SIO
4342import qualified Test.QuickCheck as Q
4443import Test.Tasty
4544import Test.Tasty.HUnit
4645import Test.Tasty.QuickCheck as QC
46+import qualified UnliftIO.IO as UIO
4747
4848main :: IO ()
4949main = defaultMain tests
@@ -72,7 +72,7 @@ randomDataSrc s' = genBS s'
7272
7373mkRandFile :: R.MonadResource m => Int64 -> m FilePath
7474mkRandFile size = do
75− dir <- liftIO $ getTemporaryDirectory
75+ dir <- liftIO getTemporaryDirectory
7676 C.runConduit $ randomDataSrc size C..| CB.sinkTempFile dir "miniohstest.random"
7777
7878funTestBucketPrefix :: Text
@@ -158,17 +158,18 @@ basicTests = funTestWithBucket "Basic tests" $
158158 liftIO $ region == "us-east-1" @? ("Got unexpected region => " ++ show region)
159159
160160 step "singlepart putObject works"
161− fPutObject bucket "lsb-release" "/etc/lsb-release" defaultPutObjectOptions
161+ testFilepath <- mkRandFile 200
162+ fPutObject bucket "test-file" testFilepath defaultPutObjectOptions
162163
163164 step "fPutObject onto a non-existent bucket and check for NoSuchBucket exception"
164− fpE <- try $ fPutObject "nosuchbucket" "lsb-release" "/etc/lsb-release" defaultPutObjectOptions
165+ fpE <- try $ fPutObject "nosuchbucket" "test-file-2" testFilepath defaultPutObjectOptions
165166 case fpE of
166167 Left exn -> liftIO $ exn @?= NoSuchBucket
167168 _ -> return ()
168169
169170 outFile <- mkRandFile 0
170171 step "simple fGetObject works"
171− fGetObject bucket "lsb-release" outFile defaultGetObjectOptions
172+ fGetObject bucket "test-file" outFile defaultGetObjectOptions
172173
173174 let unmodifiedTime = UTCTime (fromGregorian 2010 11 26) 69857
174175 step "fGetObject an object which is modified now but requesting as un-modified in past, check for exception"
@@ -176,7 +177,7 @@ basicTests = funTestWithBucket "Basic tests" $
176177 try $
177178 fGetObject
178179 bucket
179− "lsb-release"
180+ "test-file"
180181 outFile
181182 defaultGetObjectOptions
182183 { gooIfUnmodifiedSince = (Just unmodifiedTime)
@@ -190,7 +191,7 @@ basicTests = funTestWithBucket "Basic tests" $
190191 try $
191192 fGetObject
192193 bucket
193− "lsb-release"
194+ "test-file"
194195 outFile
195196 defaultGetObjectOptions
196197 { gooIfMatch = (Just "invalid-etag")
@@ -204,10 +205,10 @@ basicTests = funTestWithBucket "Basic tests" $
204205 try $
205206 fGetObject
206207 bucket
207− "lsb-release"
208+ "test-file"
208209 outFile
209210 defaultGetObjectOptions
210− { gooRange = (Just $ HT.ByteRangeFromTo 100 200)
211+ { gooRange = (Just $ HT.ByteRangeFromTo 100 300)
211212 }
212213 case resE2 of
213214 Left exn -> liftIO $ exn @?= ServiceErr "InvalidRange" "The requested range is not satisfiable"
@@ -216,7 +217,7 @@ basicTests = funTestWithBucket "Basic tests" $
216217 step "fGetObject on object with a valid range"
217218 fGetObject
218219 bucket
219− "lsb-release"
220+ "test-file"
220221 outFile
221222 defaultGetObjectOptions
222223 { gooRange = (Just $ HT.ByteRangeFrom 1)
@@ -236,7 +237,7 @@ basicTests = funTestWithBucket "Basic tests" $
236237 abortMultipartUpload bucket "newmpupload" uid
237238
238239 step "delete object works"
239− deleteObject bucket "lsb-release"
240+ deleteObject bucket "test-file"
240241
241242 step "statObject test"
242243 let object = "sample"
@@ -266,8 +267,9 @@ lowLevelMultipartTest = funTestWithBucket "Low-level Multipart Test" $
266267 randFile <- mkRandFile mb15
267268
268269 step "put object parts 1 of 1"
269− h <- liftIO $ SIO.openBinaryFile randFile SIO.ReadMode
270− partInfo <- putObjectPart bucket object uid 1 [] $ PayloadH h 0 mb15
270+ partInfo <-
271+ UIO.withBinaryFile randFile UIO.ReadMode $ \h ->
272+ putObjectPart bucket object uid 1 [] $ PayloadH h 0 mb15
271273
272274 step "complete multipart"
273275 void $ completeMultipartUpload bucket object uid [partInfo]
@@ -353,8 +355,9 @@ highLevelListingTest = funTestWithBucket "High-level listObjects Test" $
353355 )
354356 os
355357
358+ testFilepath <- mkRandFile 200
356359 forM_ expectedObjects $
357− \obj -> fPutObject bucket obj "/etc/lsb-release" defaultPutObjectOptions
360+ \obj -> fPutObject bucket obj testFilepath defaultPutObjectOptions
358361
359362 step "High-level listing of objects"
360363 items <- C.runConduit $ listObjects bucket Nothing False C..| sinkList
@@ -452,9 +455,9 @@ highLevelListingTest = funTestWithBucket "High-level listObjects Test" $
452455
453456 step "put object parts 1..10"
454457 inputFile <- mkRandFile mb5
455− h <- liftIO $ SIO.openBinaryFile inputFile SIO.ReadMode
456− forM_ [1 .. 10] $ \pnum ->
457− putObjectPart bucket object uid pnum [] $ PayloadH h 0 mb5
458+ UIO.withBinaryFile inputFile UIO.ReadMode $ \h ->
459+ forM_ [1 .. 10] $ \pnum ->
460+ putObjectPart bucket object uid pnum [] $ PayloadH h 0 mb5
458461
459462 step "fetch list parts"
460463 incompleteParts <-
@@ -470,10 +473,11 @@ listingTest :: TestTree
470473listingTest = funTestWithBucket "Listing Test" $ \step bucket -> do
471474 step "listObjects' test"
472475 step "put 10 objects"
473− let objects = (\s -> T.concat ["lsb-release", T.pack (show s)]) <$> [1 .. 10 :: Int]
476+ let objects = (\s -> T.concat ["test-file-", T.pack (show s)]) <$> [1 .. 10 :: Int]
474477
478+ testFilepath <- mkRandFile 200
475479 forM_ [1 .. 10 :: Int] $ \s ->
476− fPutObject bucket (T.concat ["lsb-release", T.pack (show s)]) "/etc/lsb-release" defaultPutObjectOptions
480+ fPutObject bucket (T.concat ["test-file-", T.pack (show s)]) testFilepath defaultPutObjectOptions
477481
478482 step "Simple list"
479483 res <- listObjects' bucket Nothing Nothing Nothing Nothing
@@ -490,7 +494,7 @@ listingTest = funTestWithBucket "Listing Test" $ \step bucket -> do
490494 sort $
491495 map
492496 ( T.concat
493− . ("lsb-release" :)
497+ . ("test-file-" :)
494498 . (\x -> [x])
495499 . T.pack
496500 . show
@@ -536,9 +540,9 @@ listingTest = funTestWithBucket "Listing Test" $ \step bucket -> do
536540
537541 step "put object parts 1..10"
538542 inputFile <- mkRandFile mb5
539− h <- liftIO $ SIO.openBinaryFile inputFile SIO.ReadMode
540− forM_ [1 .. 10] $ \pnum ->
541− putObjectPart bucket object uid pnum [] $ PayloadH h 0 mb5
543+ UIO.withBinaryFile inputFile UIO.ReadMode $ \h ->
544+ forM_ [1 .. 10] $ \pnum ->
545+ putObjectPart bucket object uid pnum [] $ PayloadH h 0 mb5
542546
543547 step "fetch list parts"
544548 listPartsResult <- listIncompleteParts' bucket object uid Nothing Nothing
@@ -754,26 +758,28 @@ bucketPolicyFunTest = funTestWithBucket "Bucket Policy tests" $
754758multipartTest :: TestTree
755759multipartTest = funTestWithBucket "Multipart Tests" $
756760 \step bucket -> do
757− step "Prepare for putObjectInternal with non-seekable file, with size."
758− step "Upload multipart file."
759− let mb80 = 80 * 1024 * 1024
760− obj = "mpart"
761+ -- Commenting out test since it's platform specific.
762+ -- FIXME: Need to find a platform agnostic way to test this.
763+ -- step "Prepare for putObjectInternal with non-seekable file, with size."
764+ -- step "Upload multipart file."
765+ -- let mb80 = 80 * 1024 * 1024
766+ -- obj = "mpart"
761767
762− void $ putObjectInternal bucket obj defaultPutObjectOptions $ ODFile "/dev/zero" (Just mb80)
768+ -- void $ putObjectInternal bucket obj defaultPutObjectOptions $ ODFile "/dev/zero" (Just mb80)
763769
764− step "Retrieve and verify file size"
765− destFile <- mkRandFile 0
766− fGetObject bucket obj destFile defaultGetObjectOptions
767− gotSize <- withNewHandle destFile getFileSize
768− liftIO $
769− gotSize == Right (Just mb80)
770− @? "Wrong file size of put file after getting"
770+ -- step "Retrieve and verify file size"
771+ -- destFile <- mkRandFile 0
772+ -- fGetObject bucket obj destFile defaultGetObjectOptions
773+ -- gotSize <- withNewHandle destFile getFileSize
774+ -- liftIO $
775+ -- gotSize == Right (Just mb80)
776+ -- @? "Wrong file size of put file after getting"
771777
772− step "Cleanup actions"
773− removeObject bucket obj
778+ -- step "Cleanup actions"
779+ -- removeObject bucket obj
774780
775− step "cleanup"
776− removeObject bucket "big"
781+ -- step "cleanup"
782+ -- removeObject bucket "big"
777783
778784 step "Prepare for removeIncompleteUpload"
779785 -- low-level multipart operation tests.
@@ -788,8 +794,8 @@ multipartTest = funTestWithBucket "Multipart Tests" $
788794
789795 step "upload 2 parts"
790796 forM_ [1, 2] $ \partNum -> do
791− h <- liftIO $ SIO.openBinaryFile randFile SIO.ReadMode
792− void $ putObjectPart bucket object uid partNum [] $ PayloadH h 0 kb5
797+ UIO.withBinaryFile randFile UIO.ReadMode $ \h ->
798+ void $ putObjectPart bucket object uid partNum [] $ PayloadH h 0 kb5
793799
794800 step "remove ongoing upload"
795801 removeIncompleteUpload bucket object
test/cert/private.keynew file+28
@@ -0,0 +1,28 @@
1+-----BEGIN PRIVATE KEY-----
2+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3G9IiC+adjf0p
3+i/2KYc+4dizeuzUFN7wraSdhiOMdQgCnu9Dc3t2YEsQhNdrARjOTyXd36KeM3TwI
4+rPJ61dRGQSuN12l+mzngFJQjE0sysZHUJOLQC3rVvIrHSQ57utPg8ifxt/SunlPY
5+fhcUcq03onMGq44yOfE6mIhoe0Y9wcPQ3RjjNNS44bgmXiXwa+Do0h2hEn6/essq
6+5KjHL8WW2vGg7G9edpYdxINA/A2fdLtr8BwPNrZhOx84eee2XcUNdBuTtUUxE+0L
7+9yRqItqddriRxJFwOXb5OPW8xx2WGaV2a0wbE4gB2PTwwDvfo72mo9HXHZUHM1A8
8+4TD/RXMbAgMBAAECggEBAJ7r1oUWLyGvinn0tijUm6RNbMQjVvEgXoCO008jr3pF
9+PqxVpgEMrOa/4tmwFBus0jcCNF4t3r2zhddBw3I5A/O1vEdvHnBz6NdDBQ8sP6fP
10+1fF50iEe1Y2MBibQkXFxxVMG2QRB1Gt5nuvXA9ELdqtCovK3EsMk5ukkWb/UvjH5
11+8hcmQsaSqvzFEF4wJSY2mkeGSGIJTphPhhuA22xbhaBMInQyhZu8EHsn0h6s/Wgy
12+C4Cp2+4qZTKaaf6x3/ZjJ8CuKiSX+ZsJKjOEv8sqx7j/Y7QFOmJPewInKDhwazr/
13+xIK+N0KXPbUzeSEz6ZvExNDTxtR5ZlQP2UrRDg28yQECgYEA4Is1O2BvKVzNFOkj
14+bTVz25a/bb0Xrcfgi0Y9rdfLzlNdItFjAkxLTVRSW2Hv9ICl0RDDAG+wTlktXRdh
15+rfvDjwG2CvLQo1VEdMWTTkKVg03SwMEy2hFiWV69lENFGSaY8Y6unZDbia5HQinA
16+EgSS4sCojS+a2jtzG5FVVHJDKlkCgYEA0MKhMhD4SUhr2y1idPBrmLxuW5mVozuW
17+8bYaBeSzmfS0BRsN4fP9JGODPBPDdNbfGfGC9ezWLgD/lmCgjIEyBOq8EmqWSsiS
18+Kihds1+Z7hXtbzGsFGAFJJTIh7blBCsK5QFuyuih2UG0fL9z6K/dy+UUJkzrYqph
19+vSfKixyM8pMCgYEAmUPLsNyw4325aeV8TeWnUCJERaZFDFQa21W1cfyS2yEhuEtN
20+llr3JzBACqn9vFk3VU1onNqfb8sE4L696KCpKeqUFEMK0AG6eS4Gzus53Gb5TKJS
21+kHA/PhshsZp9Bp7G1FJ8s4YVo5N2hh2zQVkn3Wh9Y+kzfHQJrK51nO9lEvkCgYBi
22+BuKWle1gzAcJdnhDHRoJMIJJtQbVDYhFnBMALXJAmu1lcFzGe0GlMq1PKqCfXr6I
23+eiXawQmZtJJP1LPPBmOsd2U06KQGHcS00xucvQmVCOrjSdnZ/3SqxsqbH8DOgj+t
24+ZUzXLwHA+N99rJEK9Hob4kfh7ECjpgobPnIXfKKazQKBgQChAuiXHtf/Qq18hY3u
25+x48zFWjGgfd6GpOBZYkXOwGdCJgnYjZbE26LZEnYbwPh8ZUA2vp7mgHRJkD5e3Fj
26+ERuJLCw86WqyYZmLEuBciYGjCZqR5nbavfwsziWD00jeNruds2ZwKxRfFm4V7o2S
27+WLd/RUatd2Uu9f3B2J78OUdnxg==
28+-----END PRIVATE KEY-----
test/cert/public.crtnew file+19
@@ -0,0 +1,19 @@
1+-----BEGIN CERTIFICATE-----
2+MIIDCzCCAfOgAwIBAgIUaIUOMI78LCu+r1zl0mmFHK8n5/AwDQYJKoZIhvcNAQEL
3+BQAwFDESMBAGA1UEAwwJbG9jYWxob3N0MCAXDTE5MTAyNDE5NTMxOVoYDzIxMTkw
4+OTMwMTk1MzE5WjAUMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB
5+AQUAA4IBDwAwggEKAoIBAQC3G9IiC+adjf0pi/2KYc+4dizeuzUFN7wraSdhiOMd
6+QgCnu9Dc3t2YEsQhNdrARjOTyXd36KeM3TwIrPJ61dRGQSuN12l+mzngFJQjE0sy
7+sZHUJOLQC3rVvIrHSQ57utPg8ifxt/SunlPYfhcUcq03onMGq44yOfE6mIhoe0Y9
8+wcPQ3RjjNNS44bgmXiXwa+Do0h2hEn6/essq5KjHL8WW2vGg7G9edpYdxINA/A2f
9+dLtr8BwPNrZhOx84eee2XcUNdBuTtUUxE+0L9yRqItqddriRxJFwOXb5OPW8xx2W
10+GaV2a0wbE4gB2PTwwDvfo72mo9HXHZUHM1A84TD/RXMbAgMBAAGjUzBRMB0GA1Ud
11+DgQWBBSEWXQ2JRD+OK7/KTmlD+OW16pGmzAfBgNVHSMEGDAWgBSEWXQ2JRD+OK7/
12+KTmlD+OW16pGmzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCF
13+0zYRaabB3X0jzGI9/Lr3Phrb90GvoL1DFLRuiOuTlDkz0vrm/HrZskwHCgMNrkCj
14+OTD9Vpas4D1QZBbQbRzfnf3OOoG4bgmcCwLFZl3dy27yIDAhrmbUP++g9l1Jmy4v
15+vBR/M4lt2scQ8LcZYEPqhEaE5EzFQEjtaxDcKdWDNKY9W1NUzSIABhF9eHiAUNdH
16+AFNJlYeBlCHxcWIeqgon184Dqp/CsvKtz3z3Ni+rlwPM/zuJCFHh1VF+z++0LJjG
17+roBCV0Tro4XyiEz9yp7Cb5kQYMaj1KL9TqBG0tZx0pmv7y+lXc4TT6DEllXz6USy
18+rbIba9/uUet3BqeIMTqj
19+-----END CERTIFICATE-----