diff --git a/CHANGELOG.md b/CHANGELOG.md index ce03673..8d1e673 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). -## [v5.5.10](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.9...v5.5.10) - 2023-03-06 +## [v5.5.10](https://github.com/tencentyun/cos-cpp-sdk-v5/compare/v5.5.9...v5.5.10) - 2023-03-07 ## What's Changed * ut match stage 1 by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/125 @@ -15,6 +15,8 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). * 增加允许不签Host的接口&IsDomainSameToHost支持按实例单独配置 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/130 * fix:修复PutObjectByStream接口 by @Huberyxiao in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/131 * remove unnecessary sdk release library by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/132 +* 修复lcov数据不准确问题 by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/133 +* 修正lcov提取路径 by @chen-honggang in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/134 ## New Contributors * @Huberyxiao made their first contribution in https://github.com/tencentyun/cos-cpp-sdk-v5/pull/128 @@ -23,6 +25,8 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). ### Merged +- 修正lcov提取路径 [`#134`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/134) +- 修复lcov数据不准确问题 [`#133`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/133) - remove unnecessary sdk release library [`#132`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/132) - fix:修复PutObjectByStream接口 [`#131`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/131) - 增加允许不签Host的接口&IsDomainSameToHost支持按实例单独配置 [`#130`](https://github.com/tencentyun/cos-cpp-sdk-v5/pull/130) @@ -33,6 +37,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). - 增加允许不签Host的接口 [`7f87180`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/7f8718097a9efcc9b8dfa7a22f20632dfac0ebb3) - IsDomainSameToHost支持按实例单独配置 [`072ff3d`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/072ff3d1d53fbd2daec34690f0cb5ac13956d527) +- Updated CHANGELOG.md [`4c0c85d`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/4c0c85d69534abbcfc79b3bae30231a2e2f433fc) - Updated CHANGELOG.md [`4dced4b`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/4dced4b8242bda3a193165235bf111559421c5a4) - fix:PutObjectByStream [`e1ea968`](https://github.com/tencentyun/cos-cpp-sdk-v5/commit/e1ea9685c73677763d765fa5cf92ed271e3b7250) diff --git a/demo/cos_demo.cpp b/demo/cos_demo.cpp index 0d30f12..717003f 100644 --- a/demo/cos_demo.cpp +++ b/demo/cos_demo.cpp @@ -86,6 +86,8 @@ void DeleteBucket(qcloud_cos::CosAPI& cos, const std::string& bucket_name) { void PutBucket(qcloud_cos::CosAPI& cos, const std::string& bucket_name) { qcloud_cos::PutBucketReq req(bucket_name); + //创建MAZ存储桶使用下方进行设置 + //req.SetMAZBucket(); qcloud_cos::PutBucketResp resp; qcloud_cos::CosResult result = cos.PutBucket(req, &resp); @@ -327,6 +329,74 @@ void GetBucketACL(qcloud_cos::CosAPI& cos, const std::string& bucket_name) { << std::endl; } +void GetBucketPolicy(qcloud_cos::CosAPI& cos,const std::string& bucket_name) { + qcloud_cos::GetBucketPolicyReq req(bucket_name); + qcloud_cos::GetBucketPolicyResp resp; + qcloud_cos::CosResult result = cos.GetBucketPolicy(req, &resp); + + std::cout << resp.GetPolicy() << std::endl; + std::cout << "===================GetBucketPolicy=====================" + << std::endl; + PrintResult(result, resp); + std::cout + << "====================================================================" + << std::endl; +} + +void PutBucketPolicy(qcloud_cos::CosAPI& cos,const std::string& bucket_name) { + qcloud_cos::PutBucketPolicyReq req(bucket_name); + qcloud_cos::PutBucketPolicyResp resp; + std::string bucket_policy = + " {" + " \"Statement\": [" + " {" + " \"Principal\": {" + " \"qcs\": [" + " \"qcs::cam::uin/100000000001:uin/100000000011\"" //替换成您想授予权限的账户 uin + " ]\n" + " },\n" + " \"Effect\": \"allow\"," + " \"Action\": [" + " \"cos:PutObject\"" + " ],\n" + " \"Resource\": [" //这里改成允许的路径前缀,可以根据自己网站的用户登录态判断允许上传的具体路径,例子: a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用) + " \"qcs::cos:ap-guangzhou:uid/1250000000:examplebucket-1250000000/exampleobject\"" + " ],\n" + " \"Condition\": {" + " \"string_equal\": {" + " \"cos:x-cos-mime-limit\": \"image/jpeg\"" + " }" + " }" + " }" + " ]," + " \"Version\": \"2.0\"" + " }"; + std::cout << bucket_policy << std::endl; + req.SetBody(bucket_policy); + qcloud_cos::CosResult result = cos.PutBucketPolicy(req, &resp); + + std::cout << "===================PutBucketPolicy=====================" + << std::endl; + PrintResult(result, resp); + std::cout + << "====================================================================" + << std::endl; +} + +void DeleteBucketPolicy(qcloud_cos::CosAPI& cos,const std::string& bucket_name) { + qcloud_cos::DeleteBucketPolicyReq req(bucket_name); + qcloud_cos::DeleteBucketPolicyResp resp; + qcloud_cos::CosResult result = cos.DeleteBucketPolicy(req, &resp); + + std::cout << "===================DeleteBucketPolicy=====================" + << std::endl; + PrintResult(result, resp); + std::cout + << "====================================================================" + << std::endl; +} + + void PutBucketCORS(qcloud_cos::CosAPI& cos, const std::string& bucket_name) { qcloud_cos::PutBucketCORSReq req(bucket_name); qcloud_cos::CORSRule rule; diff --git a/demo/test_file/audio.mp3 b/demo/test_file/audio.mp3 new file mode 100644 index 0000000..4b19388 Binary files /dev/null and b/demo/test_file/audio.mp3 differ diff --git a/demo/test_file/document.docx b/demo/test_file/document.docx new file mode 100644 index 0000000..2c0454c Binary files /dev/null and b/demo/test_file/document.docx differ diff --git a/demo/test_file/test.jpg b/demo/test_file/test.jpg new file mode 100644 index 0000000..7cdea36 Binary files /dev/null and b/demo/test_file/test.jpg differ diff --git a/demo/test_file/text.txt b/demo/test_file/text.txt new file mode 100755 index 0000000..8a41cd2 --- /dev/null +++ b/demo/test_file/text.txt @@ -0,0 +1 @@ +texttest \ No newline at end of file diff --git a/demo/test_file/video.mp4 b/demo/test_file/video.mp4 new file mode 100644 index 0000000..81d11df Binary files /dev/null and b/demo/test_file/video.mp4 differ diff --git a/gen_lcov.sh b/gen_lcov.sh index a610551..a2b1cb7 100755 --- a/gen_lcov.sh +++ b/gen_lcov.sh @@ -1,7 +1,7 @@ #!/bin/sh workspace=`pwd` -EXTRACT="${workspace}/*/op/* ${workspace}/*/util/* ${workspace}/*/request/* ${workspace}/*/response/* ${workspace}/*/trsf/* ${workspace}/include" +EXTRACT="${workspace}/*/op/* ${workspace}/*/util/* ${workspace}/*/request/* ${workspace}/*/response/* ${workspace}/*/trsf/* ${workspace}/include/* ${workspace}/src/*" # clear rm UTReport -rf rm UTResport.tar @@ -39,8 +39,8 @@ lcov --extract sevenyou.info ${EXTRACT} -o sevenyou_filted.info genhtml -o UTReport --prefix=`pwd` sevenyou_init_filted.info sevenyou_filted.info tar -cvf UTReport.tar UTReport -rm sevenyou_init.info -rm sevenyou_init_filted.info -rm sevenyou.info -rm sevenyou_filted.info +# rm sevenyou_init.info +# rm sevenyou_init_filted.info +# rm sevenyou.info +# rm sevenyou_filted.info rm UTReport -rf diff --git a/include/cos_api.h b/include/cos_api.h index 99f013a..08c10fb 100644 --- a/include/cos_api.h +++ b/include/cos_api.h @@ -50,7 +50,7 @@ class CosAPI { bool IsObjectExist(const std::string& bucket_name, const std::string& object_name); - /// \brief 创建一个Bucket + /// \brief List Buckets /// 详见: https://cloud.tencent.com/document/api/436/8291 /// /// \param req GetService请求 @@ -189,6 +189,30 @@ class CosAPI { /// \return 本次请求的调用情况(如状态码等) CosResult PutBucketACL(const PutBucketACLReq& req, PutBucketACLResp* resp); + /// \brief 获取Bucket的权限策略 + /// + /// \param req GetBucketPolicy请求 + /// \param resp GetBucketPolicy返回 + /// + /// \return 本次请求的调用情况(如状态码等) + CosResult GetBucketPolicy(const GetBucketPolicyReq& req, GetBucketPolicyResp* resp); + + /// \brief 写入/替换Bucket的权限策略,通过Body传入 + /// + /// \param req PutBucketPolicy请求 + /// \param resp PutBucketPolicy返回 + /// + /// \return 本次请求的调用情况(如状态码等) + CosResult PutBucketPolicy(const PutBucketPolicyReq& req, PutBucketPolicyResp* resp); + + /// \brief 删除Bucket的权限策略 + /// + /// \param req DeleteBucketPolicy请求 + /// \param resp DeleteBucketPolicy返回 + /// + /// \return 本次请求的调用情况(如状态码等) + CosResult DeleteBucketPolicy(const DeleteBucketPolicyReq& req, DeleteBucketPolicyResp* resp); + /// \brief 列出Bucket下的CORS /// /// \param req GetBucketCORS请求 @@ -741,6 +765,12 @@ class CosAPI { SharedAsyncContext AsyncGetObject(const AsyncGetObjectReq& req); SharedAsyncContext AsyncGetObject(const AsyncGetObjectReq& req, Poco::TaskManager*& taskManager); + /// \brief 异步多线程下载对象到本地,支持断点续传 + /// \param req AsyncResumableGetObject + /// \return 返回context + SharedAsyncContext AsyncResumableGetObject(const AsyncGetObjectReq& req); + SharedAsyncContext AsyncResumableGetObject(const AsyncGetObjectReq& req, Poco::TaskManager*& taskManager);; + /// \brief 异步多线程下载对象到本地 /// \param req MultiGetObjectAsync请求 /// \return 返回context @@ -776,6 +806,10 @@ class CosAPI { /* 数据处理接口 */ + /*** 存储桶绑定万象服务 ***/ + CosResult PutBucketToCI(const PutBucketToCIReq& req, + PutBucketToCIResp* resp); + /** 基础图片处理 **/ /** 图片持久化处理 **/ @@ -833,6 +867,10 @@ class CosAPI { CosResult DescribeMediaBuckets(const DescribeMediaBucketsReq& req, DescribeMediaBucketsResp* resp); + /*** 存储桶绑定媒体处理 ***/ + CosResult CreateMediaBucket(const CreateMediaBucketReq& req, + CreateMediaBucketResp* resp); + /*** 获取媒体文件某个时间的截图 ***/ // https://cloud.tencent.com/document/product/436/55671 CosResult GetSnapshot(const GetSnapshotReq& req, GetSnapshotResp* resp); diff --git a/include/cos_sys_config.h b/include/cos_sys_config.h index d19e26c..1cc3b5f 100644 --- a/include/cos_sys_config.h +++ b/include/cos_sys_config.h @@ -118,6 +118,10 @@ class CosSysConfig { static std::string GetCIHost(const std::string& bucket_name, const std::string& region); + /// \brief 获取PIC域名 + static std::string GetPICHost(uint64_t app_id, const std::string& region, + const std::string& bucket_name); + static std::string GetDestDomain(); /// \brief 获取是否使用特定ip和端口号 diff --git a/include/op/bucket_op.h b/include/op/bucket_op.h index af80de1..890390b 100644 --- a/include/op/bucket_op.h +++ b/include/op/bucket_op.h @@ -164,6 +164,30 @@ class BucketOp : public BaseOp { /// \return 本次请求的调用情况(如状态码等) CosResult PutBucketACL(const PutBucketACLReq& req, PutBucketACLResp* resp); + /// \brief 获取Bucket的权限策略 + /// + /// \param req GetBucketPolicy请求 + /// \param resp GetBucketPolicy返回 + /// + /// \return 本次请求的调用情况(如状态码等) + CosResult GetBucketPolicy(const GetBucketPolicyReq& req, GetBucketPolicyResp* resp); + + /// \brief 写入/替换Bucket的权限策略,通过Body传入 + /// + /// \param req PutBucketPolicy请求 + /// \param resp PutBucketPolicy返回 + /// + /// \return 本次请求的调用情况(如状态码等) + CosResult PutBucketPolicy(const PutBucketPolicyReq& req, PutBucketPolicyResp* resp); + + /// \brief 删除Bucket的权限策略 + /// + /// \param req DeleteBucketPolicy请求 + /// \param resp DeleteBucketPolicy返回 + /// + /// \return 本次请求的调用情况(如状态码等) + CosResult DeleteBucketPolicy(const DeleteBucketPolicyReq& req, DeleteBucketPolicyResp* resp); + /// \brief 列出Bucket下的CORS /// /// \param req GetBucketCORS请求 @@ -379,6 +403,15 @@ class BucketOp : public BaseOp { const GetBucketIntelligentTieringReq& req, GetBucketIntelligentTieringResp* resp); + /// \brief 存储桶绑定ci + /// + /// \param req PutBucketToCIReq请求 + /// \param resp PutBucketToCIResp返回 + /// + /// \return 本次请求的调用情况(如状态码等) + CosResult PutBucketToCI(const PutBucketToCIReq& req, + PutBucketToCIResp* resp); + /// \brief 提交文档转码任务 /// \brief https://cloud.tencent.com/document/product/436/54056 /// \param req CreateDocProcessJobs请求 @@ -432,6 +465,14 @@ class BucketOp : public BaseOp { CosResult DescribeMediaBuckets(const DescribeMediaBucketsReq& req, DescribeMediaBucketsResp* resp); + /// \brief 开通媒体处理 + /// \brief https://cloud.tencent.com/document/product/436/72824 + /// \param req DescribeMediaBuckets请求 + /// \param resp DescribeMediaBuckets返回 + /// + /// \return 本次请求的调用情况(如状态码等) + CosResult CreateMediaBucket(const CreateMediaBucketReq& req, + CreateMediaBucketResp* resp); /// \brief 获取媒体文件信息 /// \brief https://cloud.tencent.com/document/product/436/55672 /// \param req GetMediainfo请求 diff --git a/include/op/object_op.h b/include/op/object_op.h index 0bfe267..98ae4b8 100644 --- a/include/op/object_op.h +++ b/include/op/object_op.h @@ -324,7 +324,8 @@ class ObjectOp : public BaseOp { /// \brief 支持断点下载 CosResult ResumableGetObject(const GetObjectByFileReq& req, - GetObjectByFileResp* resp); + GetObjectByFileResp* resp, + const SharedTransferHandler& handler = nullptr); /*批量及目录操作接口*/ CosResult PutObjects(const PutObjectsByDirectoryReq& req, diff --git a/include/request/bucket_req.h b/include/request/bucket_req.h index c2b6045..318821f 100644 --- a/include/request/bucket_req.h +++ b/include/request/bucket_req.h @@ -74,6 +74,14 @@ class PutBucketReq : public BucketReq { void SetXCosGrantFullControl(const std::string& str) { AddHeader("x-cos-grant-full-control", str); } + + //设置桶为多az存储桶 + void SetMAZBucket() { + std::string maz = ""; + maz += " MAZ"; + maz += ""; + SetBody(maz); + } }; class GetBucketReq : public BucketReq { @@ -354,6 +362,39 @@ class PutBucketACLReq : public BucketReq { std::vector m_acl; }; +class GetBucketPolicyReq : public BucketReq { + public: + GetBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) { + SetMethod("GET"); + SetPath("/"); + AddParam("policy", ""); + } + + virtual ~GetBucketPolicyReq() {} +}; + +class PutBucketPolicyReq : public BucketReq { + public: + PutBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) { + SetMethod("PUT"); + SetPath("/"); + AddParam("policy", ""); + } + + virtual ~PutBucketPolicyReq() {} +}; + +class DeleteBucketPolicyReq : public BucketReq { + public: + DeleteBucketPolicyReq(const std::string& bucket_name) : BucketReq(bucket_name) { + SetMethod("DELETE"); + SetPath("/"); + AddParam("policy", ""); + } + + virtual ~DeleteBucketPolicyReq() {} +}; + class DeleteBucketACLReq : public BucketReq { public: DeleteBucketACLReq(const std::string& bucket_name) : BucketReq(bucket_name) { diff --git a/include/request/data_process_req.h b/include/request/data_process_req.h index fc89eed..dbb1b48 100644 --- a/include/request/data_process_req.h +++ b/include/request/data_process_req.h @@ -440,6 +440,17 @@ struct DescribeMediaBucketsResult { } }; +struct CreateMediaBucketResult { + std::string request_id; // 请求的唯一ID + BucketInfo media_bucket; // 媒体Bucket + std::string to_string() const { + std::stringstream ss; + ss << "request_id: " << request_id << std::endl; + ss << media_bucket.to_string() << std::endl; + ss << std::endl; + return ss.str(); + } +}; struct VideoInfo { int index; // 该流的编号 std::string codec_name; // 编解码格式名字 @@ -958,6 +969,26 @@ class GetSnapshotReq : public GetObjectByFileReq { void SetMode(const std::string& mode) { AddParam("mode", mode); } }; +class PutBucketToCIReq : public BucketReq{ + public: + PutBucketToCIReq(const std::string& bucket_name) : BucketReq(bucket_name) { + m_method = "PUT"; + } + + virtual ~PutBucketToCIReq() {} +}; + +class CreateMediaBucketReq : public BucketReq{ + public: + CreateMediaBucketReq(const std::string& bucket_name) : BucketReq(bucket_name) { + m_method = "POST"; + m_path = "/mediabucket"; + SetHttps(); + } + + virtual ~CreateMediaBucketReq() {} +}; + class GetMediaInfoReq : public ObjectReq { public: GetMediaInfoReq(const std::string& bucket_name, diff --git a/include/response/bucket_resp.h b/include/response/bucket_resp.h index c835a51..da54fb7 100644 --- a/include/response/bucket_resp.h +++ b/include/response/bucket_resp.h @@ -244,6 +244,25 @@ class PutBucketACLResp : public BaseResp { virtual ~PutBucketACLResp() {} }; +class GetBucketPolicyResp : public BaseResp { + public: + GetBucketPolicyResp() {} + virtual ~GetBucketPolicyResp() {} + std::string GetPolicy() const { return GetBody(); } +}; + +class PutBucketPolicyResp : public BaseResp { + public: + PutBucketPolicyResp() {} + virtual ~PutBucketPolicyResp() {} +}; + +class DeleteBucketPolicyResp : public BaseResp { + public: + DeleteBucketPolicyResp() {} + virtual ~DeleteBucketPolicyResp() {} +}; + class GetBucketCORSResp : public BaseResp { public: GetBucketCORSResp() {} diff --git a/include/response/data_process_resp.h b/include/response/data_process_resp.h index 540d9dd..d55fcf9 100644 --- a/include/response/data_process_resp.h +++ b/include/response/data_process_resp.h @@ -199,6 +199,24 @@ class DescribeMediaBucketsResp : public BaseResp { DescribeMediaBucketsResult m_result; }; +class PutBucketToCIResp : public BaseResp { + public: + PutBucketToCIResp() {} + virtual ~PutBucketToCIResp() {} +}; + +class CreateMediaBucketResp : public BaseResp { + public: + CreateMediaBucketResp() {} + virtual ~CreateMediaBucketResp() {} + virtual bool ParseFromXmlString(const std::string& body); + + CreateMediaBucketResult GetResult() const { return m_result; } + + private: + CreateMediaBucketResult m_result; +}; + class GetSnapshotResp : public GetObjectByFileResp { public: GetSnapshotResp() {} diff --git a/include/util/test_utils.h b/include/util/test_utils.h index 9f81291..6f2d7a2 100644 --- a/include/util/test_utils.h +++ b/include/util/test_utils.h @@ -16,6 +16,9 @@ class TestUtils { static std::string CalcStringMd5(const std::string& str); static std::string CalcStreamSHA1(std::istream& is); static std::string GetEnvVar(const std::string& env_var_name); + static bool IsDirectoryExists(const std::string& path); + static bool MakeDirectory(const std::string& path); + static bool RemoveDirectory(const std::string& path); }; #define GetEnvVar TestUtils::GetEnvVar diff --git a/src/cos_api.cpp b/src/cos_api.cpp index a36bd74..96c51d6 100644 --- a/src/cos_api.cpp +++ b/src/cos_api.cpp @@ -173,6 +173,21 @@ CosResult CosAPI::PutBucketACL(const PutBucketACLReq& req, return m_bucket_op.PutBucketACL(req, resp); } +CosResult CosAPI::PutBucketPolicy(const PutBucketPolicyReq& req, + PutBucketPolicyResp* resp) { + return m_bucket_op.PutBucketPolicy(req, resp); +} + +CosResult CosAPI::GetBucketPolicy(const GetBucketPolicyReq& req, + GetBucketPolicyResp* resp) { + return m_bucket_op.GetBucketPolicy(req, resp); +} + +CosResult CosAPI::DeleteBucketPolicy(const DeleteBucketPolicyReq& req, + DeleteBucketPolicyResp* resp) { + return m_bucket_op.DeleteBucketPolicy(req, resp); +} + CosResult CosAPI::GetBucketCORS(const GetBucketCORSReq& req, GetBucketCORSResp* resp) { return m_bucket_op.GetBucketCORS(req, resp); @@ -602,6 +617,31 @@ SharedAsyncContext CosAPI::AsyncGetObject(const AsyncGetObjectReq& req, Poco::Ta return context; } +SharedAsyncContext CosAPI::AsyncResumableGetObject(const AsyncGetObjectReq& req) { + SharedTransferHandler handler(new TransferHandler()); + handler->SetRequest(reinterpret_cast(&req)); + TaskFunc fn = [=]() { + GetObjectByFileResp resp; + m_object_op.ResumableGetObject(req, &resp, handler); + }; + GetGlobalTaskManager().start(new AsyncTask(std::move(fn))); + SharedAsyncContext context(new AsyncContext(handler)); + return context; +} + +SharedAsyncContext CosAPI::AsyncResumableGetObject(const AsyncGetObjectReq& req, Poco::TaskManager*& taskManager) { + SharedTransferHandler handler(new TransferHandler()); + handler->SetRequest(reinterpret_cast(&req)); + TaskFunc fn = [=]() { + GetObjectByFileResp resp; + m_object_op.ResumableGetObject(req, &resp, handler); + }; + taskManager = &GetGlobalTaskManager(); + (*taskManager).start(new AsyncTask(std::move(fn))); + SharedAsyncContext context(new AsyncContext(handler)); + return context; +} + SharedAsyncContext CosAPI::AsyncMultiGetObject(const AsyncMultiGetObjectReq& req) { SharedTransferHandler handler(new TransferHandler()); handler->SetRequest(reinterpret_cast(&req)); @@ -671,6 +711,10 @@ CosResult CosAPI::DeleteObjects(const DeleteObjectsByPrefixReq& req, CosResult CosAPI::MoveObject(const MoveObjectReq& req) { return m_object_op.MoveObject(req); } +CosResult CosAPI::PutBucketToCI(const PutBucketToCIReq& req, + PutBucketToCIResp* resp) { + return m_bucket_op.PutBucketToCI(req, resp); +} CosResult CosAPI::PutImage(PutImageByFileReq& req, PutImageByFileResp* resp) { @@ -728,6 +772,11 @@ CosResult CosAPI::DescribeMediaBuckets(const DescribeMediaBucketsReq& req, return m_bucket_op.DescribeMediaBuckets(req, resp); } +CosResult CosAPI::CreateMediaBucket(const CreateMediaBucketReq& req, + CreateMediaBucketResp* resp) { + return m_bucket_op.CreateMediaBucket(req, resp); +} + CosResult CosAPI::GetSnapshot(const GetSnapshotReq& req, GetSnapshotResp* resp) { return m_object_op.GetObject(static_cast(req), diff --git a/src/cos_sys_config.cpp b/src/cos_sys_config.cpp index 0729a94..e959ad9 100644 --- a/src/cos_sys_config.cpp +++ b/src/cos_sys_config.cpp @@ -251,6 +251,16 @@ std::string CosSysConfig::GetCIHost(const std::string& bucket_name, return host; } +std::string CosSysConfig::GetPICHost(uint64_t app_id, const std::string& region, + const std::string& bucket_name) { + std::string app_id_suffix = "-" + StringUtil::Uint64ToString(app_id); + if (app_id == 0 || StringUtil::StringEndsWith(bucket_name, app_id_suffix)) { + return bucket_name + ".pic." + region + ".myqcloud.com"; + } + + return bucket_name + app_id_suffix + ".pic." + region + ".myqcloud.com"; +} + std::string CosSysConfig::GetDestDomain() { std::lock_guard lock(m_dest_domain_lock); return m_dest_domain; diff --git a/src/op/bucket_op.cpp b/src/op/bucket_op.cpp index 47cfa39..2ed9e3c 100644 --- a/src/op/bucket_op.cpp +++ b/src/op/bucket_op.cpp @@ -45,7 +45,8 @@ CosResult BucketOp::PutBucket(const PutBucketReq& req, PutBucketResp* resp) { std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(), req.GetBucketName()); std::string path = req.GetPath(); - return NormalAction(host, path, req, "", false, resp); + std::string req_body = req.GetBody(); + return NormalAction(host, path, req, req_body, false, resp); } CosResult BucketOp::GetBucket(const GetBucketReq& req, GetBucketResp* resp) { @@ -214,6 +215,38 @@ CosResult BucketOp::PutBucketACL(const PutBucketACLReq& req, req_body, false, resp); } +CosResult BucketOp::PutBucketPolicy(const PutBucketPolicyReq& req, + PutBucketPolicyResp* resp) { + std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(), + req.GetBucketName()); + std::string path = req.GetPath(); + + std::string req_body = req.GetBody(); + std::string raw_md5 = CodecUtil::Base64Encode(CodecUtil::RawMd5(req_body)); + + std::map additional_headers; + std::map additional_params; + additional_headers.insert(std::make_pair("Content-MD5", raw_md5)); + return NormalAction(host, path, req, additional_headers, additional_params, + req_body, false, resp); +} + +CosResult BucketOp::GetBucketPolicy(const GetBucketPolicyReq& req, + GetBucketPolicyResp* resp) { + std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(), + req.GetBucketName()); + std::string path = req.GetPath(); + return NormalAction(host, path, req, "", false, resp); +} + +CosResult BucketOp::DeleteBucketPolicy(const DeleteBucketPolicyReq& req, + DeleteBucketPolicyResp* resp) { + std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(), + req.GetBucketName()); + std::string path = req.GetPath(); + return NormalAction(host, path, req, "", false, resp); +} + CosResult BucketOp::GetBucketCORS(const GetBucketCORSReq& req, GetBucketCORSResp* resp) { std::string host = CosSysConfig::GetHost(GetAppId(), m_config->GetRegion(), @@ -521,6 +554,14 @@ CosResult BucketOp::GetBucketIntelligentTiering( return NormalAction(host, path, req, "", false, resp); } +CosResult BucketOp::PutBucketToCI(const PutBucketToCIReq& req, + PutBucketToCIResp* resp) { + std::string host = CosSysConfig::GetPICHost(GetAppId(), m_config->GetRegion(), + req.GetBucketName()); + std::string path = req.GetPath(); + return NormalAction(host, path, req, "", false, resp); +} + CosResult BucketOp::ProcessReq(const BucketReq& req, BaseResp* resp, bool is_ci_req) { std::string host = @@ -579,6 +620,13 @@ CosResult BucketOp::DescribeMediaBuckets(const DescribeMediaBucketsReq& req, return ProcessReq(req, resp, true); } +CosResult BucketOp::CreateMediaBucket(const CreateMediaBucketReq& req, + CreateMediaBucketResp* resp) { + std::string host = CosSysConfig::GetCIHost(req.GetBucketName(), m_config->GetRegion()); + std::string path = req.GetPath(); + return NormalAction(host, path, req, "", false, resp); +} + CosResult BucketOp::BatchImageAuditing(const BatchImageAuditingReq& req, BatchImageAuditingResp* resp) { return ProcessReq(req, resp, true); diff --git a/src/op/object_op.cpp b/src/op/object_op.cpp index 15c6a32..067b939 100644 --- a/src/op/object_op.cpp +++ b/src/op/object_op.cpp @@ -1861,16 +1861,24 @@ ObjectOp::PostLiveChannelVodPlaylist(const PostLiveChannelVodPlaylistReq& req, } CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req, - GetObjectByFileResp* resp) { + GetObjectByFileResp* resp, + const SharedTransferHandler& handler) { CosResult result; - + if (!handler && !resp) { + SetResultAndLogError(result, "invalid input parameter"); + return result; + } CosResult head_result; // 1. 调用HeadObject获取文件长度 HeadObjectReq head_req(req.GetBucketName(), req.GetObjectName()); HeadObjectResp head_resp; head_result = HeadObject(head_req, &head_resp); if (!head_result.IsSucc()) { - SDK_LOG_ERR("failed to get object length before downloading object."); + SetResultAndLogError( + head_result, "failed to get object length before downloading object."); + if (handler) { + handler->UpdateStatus(TransferStatus::FAILED, head_result); + } return head_result; } @@ -1934,6 +1942,9 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req, if (auth_str.empty()) { result.SetErrorMsg( "Generate auth str fail, check your access_key/secret_key."); + if (handler) { + handler->UpdateStatus(TransferStatus::FAILED); + } return result; } headers["Authorization"] = auth_str; @@ -1974,12 +1985,19 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req, ") fail, errno=" + StringUtil::IntToString(errno); SDK_LOG_ERR("%s", err_msg.c_str()); result.SetErrorMsg(err_msg); + if (handler) { + handler->UpdateStatus(TransferStatus::FAILED); + } return result; } // 4. 多线程下载 std::string object_etag = head_resp.GetEtag(); uint64_t file_size = head_resp.GetContentLength(); + if (handler) { + handler->SetTotalSize(file_size); + handler->UpdateStatus(TransferStatus::IN_PROGRESS); + } unsigned pool_size = CosSysConfig::GetUploadThreadPoolSize(); unsigned slice_size = CosSysConfig::GetDownSliceSize(); @@ -1998,7 +2016,7 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req, for (unsigned i = 0; i < pool_size; ++i) { pptaskArr[i] = new FileDownTask(dest_url, headers, params, req.GetConnTimeoutInms(), - req.GetRecvTimeoutInms()); + req.GetRecvTimeoutInms(), handler); } SDK_LOG_INFO( @@ -2018,6 +2036,11 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req, uint64_t resume_update_offset = 0; // 更新offset while (offset < file_size) { + if (handler && !handler->ShouldContinue()) { + task_fail_flag = true; + SetResultAndLogError(result, "Request canceled by user"); + break; + } SDK_LOG_DBG("down data, offset=%" PRIu64 ", file_size=%" PRIu64, offset, file_size); unsigned task_index = 0; @@ -2117,6 +2140,10 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req, // 下载成功则用head得到的content_length和etag设置get response resp->SetContentLength(file_size); resp->SetEtag(object_etag); + if (handler) { + handler->UpdateStatus(TransferStatus::COMPLETED, result, + resp->GetHeaders()); + } // 下载成功,删除任务文件 ::remove(resumable_task_json_file.c_str()); } else { @@ -2137,6 +2164,9 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req, SDK_LOG_ERR("we may encounter network error"); // 可能网络传输错误,需要用户重试 result.SetFail(); + if (handler) { + handler->UpdateStatus(TransferStatus::FAILED, result); + } } } } else { @@ -2156,6 +2186,9 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req, UpdateResumableDownloadTaskFile(resumable_task_json_file, resume_task_check_element, resume_update_offset); + if (handler) { + handler->UpdateStatus(TransferStatus::FAILED, result); + } } // 4. 释放所有资源 @@ -2174,7 +2207,18 @@ CosResult ObjectOp::ResumableGetObject(const GetObjectByFileReq& req, if (need_to_redownload) { // 本地文件不是最新的,需要重新下载 SDK_LOG_INFO("non-resumable download object"); - return MultiThreadDownload(req, resp); + result = MultiThreadDownload(req, resp); + if (handler) { + if (result.IsSucc()){ + handler->UpdateStatus(TransferStatus::COMPLETED, result, + resp->GetHeaders()); + } else { + if (handler) { + handler->UpdateStatus(TransferStatus::FAILED, result); + } + } + } + return result; } return result; diff --git a/src/response/data_process_resp.cpp b/src/response/data_process_resp.cpp index 79c953c..dd4af3a 100644 --- a/src/response/data_process_resp.cpp +++ b/src/response/data_process_resp.cpp @@ -671,6 +671,38 @@ bool DescribeMediaBucketsResp::ParseFromXmlString(const std::string& body) { } return true; } +bool CreateMediaBucketResp::ParseFromXmlString(const std::string& body) { + std::string tmp_body = body; + rapidxml::xml_document<> doc; + + if (!StringUtil::StringToXml(&tmp_body[0], &doc)) { + SDK_LOG_ERR("Parse string to xml doc error, xml_body=%s", body.c_str()); + return false; + } + + rapidxml::xml_node<>* root = doc.first_node("Response"); + if (NULL == root) { + SDK_LOG_ERR("Missing root node Response, xml_body=%s", body.c_str()); + return false; + } + + rapidxml::xml_node<>* node = root->first_node(); + for (; node != NULL; node = node->next_sibling()) { + const std::string& node_name = node->name(); + if ("RequestId" == node_name) { + m_result.request_id = node->value(); + } else if ("MediaBucket" == node_name) { + BucketInfo bucket_info; + DescribeDocProcessBucketsResp::ParseBucketInfo(node, bucket_info); + m_result.media_bucket = bucket_info; + } else { + SDK_LOG_WARN("Unknown field in Response, field_name=%s", + node_name.c_str()); + return false; + } + } + return true; +} bool GetMediaInfoResp::ParseVideo(rapidxml::xml_node<>* root, VideoInfo& video_info) { diff --git a/src/util/auth_tool.cpp b/src/util/auth_tool.cpp index 9e00118..f35fbd2 100644 --- a/src/util/auth_tool.cpp +++ b/src/util/auth_tool.cpp @@ -42,14 +42,8 @@ void AuthTool::FilterAndSetSignHeader( "if-unmodified-since", "origin", "range", - "response-cache-control", - "response-content-disposition", - "response-content-encoding", - "response-content-language", - "response-content-type", - "response-expires", - "transfer-encoding", - "versionid"}; + "transfer-encoding" + }; for (std::map::const_iterator itr = headers.begin(); itr != headers.end(); ++itr) { if (! not_sign_headers.count(itr->first) && (sign_headers.count(StringUtil::StringToLower(itr->first)) > 0 || diff --git a/src/util/test_utils.cpp b/src/util/test_utils.cpp index 6578398..99e08ef 100644 --- a/src/util/test_utils.cpp +++ b/src/util/test_utils.cpp @@ -5,6 +5,9 @@ #include #include +#include +#include +#include #include "Poco/DigestStream.h" #include "Poco/MD5Engine.h" @@ -77,4 +80,26 @@ std::string TestUtils::GetEnvVar(const std::string& env_var_name) { return std::string(tmp); } +bool TestUtils::IsDirectoryExists(const std::string& path) { + struct stat info; + if (0 == stat(path.c_str(), &info) && info.st_mode & S_IFDIR) { + return true; + } else { + return false; + } +} +bool TestUtils::MakeDirectory(const std::string& path) { + if (0 == mkdir(path.c_str(), 0775)) { + return true; + } else { + return false; + } +} +bool TestUtils::RemoveDirectory(const std::string& path) { + if (0 == rmdir(path.c_str())) { + return true; + }else { + return false; + } +} } // namespace qcloud_cos diff --git a/unittest/CMakeLists.txt b/unittest/CMakeLists.txt index 531b471..9a30754 100644 --- a/unittest/CMakeLists.txt +++ b/unittest/CMakeLists.txt @@ -2,7 +2,8 @@ project(cos-cpp-sdk-ut) file(GLOB common_src src/test_utils.cpp) file(GLOB object_request_test_src src/object_request_test.cpp) -file(GLOB object_response_test_src src/object_request_test.cpp) +file(GLOB object_response_test_src src/object_response_test.cpp) +file(GLOB bucket_response_test_src src/bucket_response_test.cpp) file(GLOB util_test_src src/util_test.cpp) file(GLOB object_op_test_src src/object_op_test.cpp) file(GLOB bucket_op_test_src src/bucket_op_test.cpp) @@ -18,6 +19,9 @@ target_link_libraries(object-request-test cossdk ${POCO_LIBS} ${SYSTEM_LIBS} ${G add_executable(object-response-test ${object_response_test_src} ${common_src}) target_link_libraries(object-response-test cossdk ${POCO_LIBS} ${SYSTEM_LIBS} ${GTEST_LIBS}) +add_executable(bucket-response-test ${bucket_response_test_src} ${common_src}) +target_link_libraries(bucket-response-test cossdk ${POCO_LIBS} ${SYSTEM_LIBS} ${GTEST_LIBS}) + add_executable(util-test ${util_test_src} ${common_src}) target_link_libraries(util-test cossdk ${POCO_LIBS} ${SYSTEM_LIBS} ${GTEST_LIBS}) @@ -39,6 +43,7 @@ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage") add_executable(all-test ${object_request_test_src} ${object_response_test_src} + ${bucket_response_test_src} ${util_test_src} ${object_op_test_src} ${bucket_op_test_src} diff --git a/unittest/src/async_op_test.cpp b/unittest/src/async_op_test.cpp index 499c99f..f952f1c 100644 --- a/unittest/src/async_op_test.cpp +++ b/unittest/src/async_op_test.cpp @@ -516,6 +516,215 @@ TEST_F(AsyncOpTest, AsyncOpWithWithDoneCallback) { } } +TEST_F(AsyncOpTest, AsyncPutByStreamWithDoneCallback) { + { + size_t file_size = ((rand() % 100) + 1) * 1024; + std::string object_name = "test_async_by_stream_" + std::to_string(file_size); + std::istringstream iss(TestUtils::GetRandomString(file_size)); + // 完成回调 + auto multi_put_done_cb = [](const SharedAsyncContext& context, + void* user_data) { + CHECK_COMMON_RESULT(context->GetResult()) + AsyncResp resp = context->GetAsyncResp(); + CHECK_COMMON_RESP(resp) + }; + + // 开始上传 + SharedAsyncContext context; + std::cout << "async upload object: " << object_name << std::endl; + + // 异步上传 + qcloud_cos::AsyncPutObjectByStreamReq put_req(m_bucket_name, object_name, + iss); + // 设置上传完成回调 + put_req.SetDoneCallback(multi_put_done_cb); + // 设置私有数据 + put_req.SetUserData(&put_req); + context = m_client->AsyncPutObject(put_req); + // 等待上传结束 + context->WaitUntilFinish(); + CHECK_COMMON_RESULT(context->GetResult()) + AsyncResp put_resp = context->GetAsyncResp(); + CHECK_COMMON_RESP(put_resp) + + // 删除对象 + CosResult del_result; + qcloud_cos::DeleteObjectReq del_req(m_bucket_name, object_name); + qcloud_cos::DeleteObjectResp del_resp; + del_result = m_client->DeleteObject(del_req, &del_resp); + CHECK_COMMON_RESULT(del_result) + CHECK_COMMON_RESP(del_resp) + CHECK_DEL_RESP(del_resp) + } +} + +TEST_F(AsyncOpTest, AsyncPutByStreamWithDoneCallbackWithOutputTaskManager) { + { + size_t file_size = ((rand() % 100) + 1) * 1024; + std::string object_name = "test_async_by_stream_" + std::to_string(file_size); + std::istringstream iss(TestUtils::GetRandomString(file_size)); + // 完成回调 + auto multi_put_done_cb = [](const SharedAsyncContext& context, + void* user_data) { + CHECK_COMMON_RESULT(context->GetResult()) + AsyncResp resp = context->GetAsyncResp(); + CHECK_COMMON_RESP(resp) + }; + + // 开始上传 + SharedAsyncContext context; + Poco::TaskManager* taskManager; + std::cout << "async upload object: " << object_name << std::endl; + + // 异步上传 + qcloud_cos::AsyncPutObjectByStreamReq put_req(m_bucket_name, object_name, + iss); + // 设置上传完成回调 + put_req.SetDoneCallback(multi_put_done_cb); + // 设置私有数据 + put_req.SetUserData(&put_req); + context = m_client->AsyncPutObject(put_req, taskManager); + // 等待上传结束 + context->WaitUntilFinish(); + taskManager->joinAll(); + CHECK_COMMON_RESULT(context->GetResult()) + AsyncResp put_resp = context->GetAsyncResp(); + CHECK_COMMON_RESP(put_resp) + + // 删除对象 + CosResult del_result; + qcloud_cos::DeleteObjectReq del_req(m_bucket_name, object_name); + qcloud_cos::DeleteObjectResp del_resp; + del_result = m_client->DeleteObject(del_req, &del_resp); + CHECK_COMMON_RESULT(del_result) + CHECK_COMMON_RESP(del_resp) + CHECK_DEL_RESP(del_resp) + } +} + + + +TEST_F(AsyncOpTest, AsyncOpWithWithDoneCallbackWithOutputTaskManager) { + std::vector base_file_size_v = { + 1, 5, 35, 356, 1024, 2545, 25678, 1024 * 1024, 5 * 1024 * 1024}; + std::vector op_type_v = {ASYNC_OP, MULTI_ASYNC_OP}; + for (auto& size : base_file_size_v) { + for (auto& op_type : op_type_v) { + std::cout << "base_size: " << size << ", op_type: " << op_type + << std::endl; + size_t file_size = ((rand() % 100) + 1) * size; + GENERATE_LOCAL_FILE(file_size) + + FileInfo file_info = { + object_name, local_file, local_file + "_download", + file_size, file_crc64_origin, file_md5_origin, + op_type}; + + // 完成回调 + auto multi_put_done_cb = [](const SharedAsyncContext& context, + void* user_data) { + CHECK_COMMON_RESULT(context->GetResult()) + FileInfo* file_info = reinterpret_cast(user_data); + std::string file_md5_origin = file_info->m_file_md5_origin; + uint64_t file_crc64_origin = file_info->m_file_crc64_origin; + AsyncResp resp = context->GetAsyncResp(); + CHECK_COMMON_RESP(resp) + CHECK_PUT_RESP(resp, file_info->m_op_type) + }; + + // 开始上传 + SharedAsyncContext context; + Poco::TaskManager* taskManager; + if (op_type == ASYNC_OP) { + std::cout << "async upload object: " << object_name << std::endl; + // 异步上传 + qcloud_cos::AsyncPutObjectReq put_req(m_bucket_name, object_name, + local_file); + // 设置上传完成回调 + put_req.SetDoneCallback(multi_put_done_cb); + // 设置私有数据 + put_req.SetUserData(reinterpret_cast(&file_info)); + + context = m_client->AsyncPutObject(put_req, taskManager); + } else { + std::cout << "multi async upload object: " << object_name << std::endl; + // 异步上传 + qcloud_cos::AsyncMultiPutObjectReq put_req(m_bucket_name, object_name, + local_file); + // 设置上传完成回调 + put_req.SetDoneCallback(multi_put_done_cb); + // 设置私有数据 + put_req.SetUserData(reinterpret_cast(&file_info)); + context = m_client->AsyncMultiPutObject(put_req, taskManager); + } + + // 等待上传结束 + context->WaitUntilFinish(); + taskManager->joinAll(); + CHECK_COMMON_RESULT(context->GetResult()) + AsyncResp put_resp = context->GetAsyncResp(); + CHECK_COMMON_RESP(put_resp) + CHECK_PUT_RESP(put_resp, op_type) + + // 下载 + auto multi_get_done_cb = [](const SharedAsyncContext& context, + void* user_data) { + CHECK_COMMON_RESULT(context->GetResult()) + FileInfo* file_info = (reinterpret_cast(user_data)); + std::string file_md5_origin = file_info->m_file_md5_origin; + std::string local_file_download = file_info->m_local_file_download; + uint64_t file_crc64_origin = file_info->m_file_crc64_origin; + uint64_t file_size = file_info->m_file_size; + AsyncResp resp = context->GetAsyncResp(); + CHECK_COMMON_RESP(resp) + CHECK_GET_RESP(resp, file_info->m_op_type) + }; + std::string local_file_download = local_file + "_download"; + if (op_type == ASYNC_OP) { + std::cout << "async download object: " << object_name << std::endl; + qcloud_cos::AsyncGetObjectReq get_req(m_bucket_name, object_name, + local_file_download); + // 设置完成回调 + get_req.SetDoneCallback(multi_get_done_cb); + // 设置私有数据 + get_req.SetUserData(reinterpret_cast(&file_info)); + context = m_client->AsyncGetObject(get_req, taskManager); + } else { + std::cout << "multi async download object: " << object_name + << std::endl; + qcloud_cos::AsyncMultiGetObjectReq get_req(m_bucket_name, object_name, + local_file_download); + // 设置完成回调 + get_req.SetDoneCallback(multi_get_done_cb); + // 设置私有数据 + get_req.SetUserData(reinterpret_cast(&file_info)); + context = m_client->AsyncMultiGetObject(get_req, taskManager); + } + + // 等待下载结束 + context->WaitUntilFinish(); + taskManager->joinAll(); + CHECK_COMMON_RESULT(context->GetResult()) + AsyncResp get_resp = context->GetAsyncResp(); + CHECK_COMMON_RESP(get_resp) + CHECK_GET_RESP(get_resp, op_type) + + // 删除对象 + CosResult del_result; + qcloud_cos::DeleteObjectReq del_req(m_bucket_name, object_name); + qcloud_cos::DeleteObjectResp del_resp; + del_result = m_client->DeleteObject(del_req, &del_resp); + CHECK_COMMON_RESULT(del_result) + CHECK_COMMON_RESP(del_resp) + CHECK_DEL_RESP(del_resp) + + // 删除本地文件 + TestUtils::RemoveFile(local_file); + TestUtils::RemoveFile(local_file_download); + } + } +} + #if 0 TEST_F(AsyncOpTest, AsyncOpWithConcurrent) { const int concurrent_size = 5; // 并发文件个数为5 @@ -722,6 +931,7 @@ TEST_F(AsyncOpTest, AsyncOpWithConcurrent) { } #endif + TEST_F(AsyncOpTest, AsyncPutWithException) { // cancel op std::vector base_file_size_v = {1, 5, 35, 356, diff --git a/unittest/src/bucket_op_test.cpp b/unittest/src/bucket_op_test.cpp index 20bb55f..5218b14 100644 --- a/unittest/src/bucket_op_test.cpp +++ b/unittest/src/bucket_op_test.cpp @@ -153,6 +153,76 @@ TEST_F(BucketOpTest, PutBucketTest) { } } +TEST_F(BucketOpTest, GetServiceTest) { + bool use_dns_cache = CosSysConfig::GetUseDnsCache(); + CosSysConfig::SetUseDnsCache(false); + // normal true + { + GetServiceReq req; + GetServiceResp resp; + req.AddParam("range","gt"); + auto ms = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()); + req.AddParam("create-time",std::to_string(ms.count()-3600000)); + CosResult result = m_client2->GetService(req, &resp); + EXPECT_TRUE(result.IsSucc()); + } + CosSysConfig::SetUseDnsCache(use_dns_cache); +} + +TEST_F(BucketOpTest, SetCredentailTest) { + { + qcloud_cos::CosConfig config(00000,"secretId","secretKey",GetEnvVar("CPP_SDK_V5_REGION")); + qcloud_cos::CosAPI cos(config); + cos.SetCredentail(GetEnvVar("CPP_SDK_V5_ACCESS_KEY"),GetEnvVar("CPP_SDK_V5_SECRET_KEY"),""); + EXPECT_EQ(config.GetAccessKey(), "secretId"); + EXPECT_EQ(config.GetAppId(), 00000); + EXPECT_EQ(config.GetSecretKey(), "secretKey"); + EXPECT_EQ(config.GetRegion(), GetEnvVar("CPP_SDK_V5_REGION")); + bool result = cos.IsBucketExist(m_bucket_name2); + EXPECT_TRUE(result); + } +} + +TEST_F(BucketOpTest, IsBucketExistTest) { + // normal true + { + bool result = m_client2->IsBucketExist(m_bucket_name2); + EXPECT_TRUE(result); + } + + // wrong false + { + bool result = m_client2->IsBucketExist(m_bucket_name_nil); + EXPECT_TRUE(!result); + } +} + +TEST_F(BucketOpTest, DescribeDocProcessTest) { + bool use_dns_cache = CosSysConfig::GetUseDnsCache(); + CosSysConfig::SetUseDnsCache(false); + { + DescribeDocProcessBucketsReq req; + DescribeDocProcessBucketsResp resp; + CosResult result = m_client->DescribeDocProcessBuckets(req, &resp); + EXPECT_TRUE(result.IsSucc()); + EXPECT_EQ(resp.GetServer(), "tencent-ci"); + } + CosSysConfig::SetUseDnsCache(use_dns_cache); +} + +TEST_F(BucketOpTest, DescribeMediaTest) { + bool use_dns_cache = CosSysConfig::GetUseDnsCache(); + CosSysConfig::SetUseDnsCache(false); + { + DescribeMediaBucketsReq req; + DescribeMediaBucketsResp resp; + CosResult result = m_client->DescribeMediaBuckets(req, &resp); + EXPECT_TRUE(result.IsSucc()); + EXPECT_EQ(resp.GetServer(), "tencent-ci"); + } + CosSysConfig::SetUseDnsCache(use_dns_cache); +} + TEST_F(BucketOpTest, HeadBucketTest) { // normal 200 { @@ -183,6 +253,87 @@ TEST_F(BucketOpTest, HeadBucketTest) { } } +TEST_F(BucketOpTest, PutBucketDomainTest) { + // 400 + { + qcloud_cos::PutBucketDomainReq req(m_bucket_name2); + DomainRule rules; + rules.SetStatus("ENABLED"); + rules.SetName("111"); + rules.SetType("REST"); + req.SetDomainRule(rules); + PutBucketDomainResp resp; + CosResult result = m_client2->PutBucketDomain(req, &resp); + EXPECT_TRUE(!result.IsSucc()); + EXPECT_EQ(result.GetHttpStatus(), 400); + } +} + +TEST_F(BucketOpTest, GetBucketDomainTest) { + // 404 + { + GetBucketDomainReq req(m_bucket_name2); + GetBucketDomainResp resp; + CosResult result = m_client2->GetBucketDomain(req, &resp); + EXPECT_TRUE(!result.IsSucc()); + EXPECT_EQ(result.GetHttpStatus(), 404); + } +} + + +TEST_F(BucketOpTest, GetBucketLocationTest) { + // normal CPP_SDK_V5_REGION + { + std::string location = m_client2->GetBucketLocation(m_bucket_name2); + EXPECT_EQ(location,GetEnvVar("CPP_SDK_V5_REGION")); + } + + // wrong "" + { + std::string location = m_client2->GetBucketLocation(m_bucket_name_wrong); + EXPECT_EQ(location,""); + } +} + +TEST_F(BucketOpTest, BucketIntelligentTieringTest) { + bool use_dns_cache = CosSysConfig::GetUseDnsCache(); + CosSysConfig::SetUseDnsCache(false); + std::string ittest_bucket_name = "ittest-" + GetEnvVar("CPP_SDK_V5_APPID"); + { + PutBucketReq req(ittest_bucket_name); + PutBucketResp resp; + CosResult result = m_client->PutBucket(req, &resp); + EXPECT_TRUE(result.IsSucc()); + } + + { + PutBucketIntelligentTieringReq req(ittest_bucket_name); + PutBucketIntelligentTieringResp resp; + req.SetStatus(true); + req.SetDays(60); + CosResult result = m_client->PutBucketIntelligentTiering(req, &resp); + EXPECT_TRUE(result.IsSucc()); + } + { + GetBucketIntelligentTieringReq req(ittest_bucket_name); + GetBucketIntelligentTieringResp resp; + CosResult result = m_client->GetBucketIntelligentTiering(req, &resp); + EXPECT_TRUE(result.IsSucc()); + EXPECT_EQ(resp.GetStatus(), "Enabled"); + EXPECT_EQ(resp.GetDays(), 60); + } + + { + DeleteBucketReq req(ittest_bucket_name); + DeleteBucketResp resp; + CosResult result = m_client->DeleteBucket(req, &resp); + EXPECT_TRUE(result.IsSucc()); + } + CosSysConfig::SetUseDnsCache(use_dns_cache); +} + + + TEST_F(BucketOpTest, ListMultipartUpload) { { std::string object_name = "testlistuploadpartsdiffer"; diff --git a/unittest/src/bucket_response_test.cpp b/unittest/src/bucket_response_test.cpp new file mode 100644 index 0000000..0d4a800 --- /dev/null +++ b/unittest/src/bucket_response_test.cpp @@ -0,0 +1,92 @@ +#include "gtest/gtest.h" +#include "response/bucket_resp.h" +#include "response/data_process_resp.h" + +namespace qcloud_cos { + +TEST(BucketRespTest, BucketDomainTest) { + { + std::string body; + body += "\n"; + body += " Code\n"; + body += " Message\n"; + body += " RequestId\n"; + body += " TraceId\n"; + body += ""; + PutBucketDomainResp resp; + resp.ParseFromXmlString(body); + ASSERT_EQ(resp.GetDomainErrorMsg().GetCode(), "Code"); + ASSERT_EQ(resp.GetDomainErrorMsg().GetMessage(), "Message"); + ASSERT_EQ(resp.GetDomainErrorMsg().GetRequestid(), "RequestId"); + ASSERT_EQ(resp.GetDomainErrorMsg().GetTraceid(), "TraceId"); + } + { + std::string body; + body += "\n"; + body += " \n"; + body += " Status\n"; + body += " Name\n"; + body += " Type\n"; + body += " \n"; + body += ""; + GetBucketDomainResp resp; + resp.ParseFromXmlString(body); + ASSERT_EQ(resp.GetStatus(), "Status"); + ASSERT_EQ(resp.GetName(), "Name"); + ASSERT_EQ(resp.GetType(), "Type"); + } + { + GetBucketInventoryResp resp; + std::string body; + body += "\n"; + body += " \n"; + body += " \n"; + body += " CSV\n"; + body += " 1250000000\n"; + body += " qcs::cos:ap-guangzhou::examplebucket-1250000000\n"; + body += " list1\n"; + body += " \n"; + body += " \n"; + body += " \n"; + body += " \n"; + body += " \n"; + body += " \n"; + body += " Daily\n"; + body += " \n"; + body += " \n"; + body += " myPrefix\n"; + body += " \n"; + body += " \n"; + body += " Size\n"; + body += " LastModifiedDate\n"; + body += " ETag\n"; + body += " StorageClass\n"; + body += " IsMultipartUploaded\n"; + body += " ReplicationStatus\n"; + body += " \n"; + body += " All\n"; + body += " Id\n"; + body += " true\n"; + body += ""; + resp.ParseFromXmlString(body); + ASSERT_EQ(resp.GetInventory().GetId(), "Id"); + ASSERT_TRUE(resp.GetInventory().GetIsEnable()); + ASSERT_EQ(resp.GetInventory().GetIncludedObjectVersions(), "All"); + ASSERT_TRUE(resp.GetInventory().GetOptionalFields().GetIsETag()); + ASSERT_TRUE(resp.GetInventory().GetOptionalFields().GetIsSize()); + ASSERT_TRUE(resp.GetInventory().GetOptionalFields().GetIsLastModified()); + ASSERT_TRUE(resp.GetInventory().GetOptionalFields().GetIsStorageClass()); + ASSERT_TRUE(resp.GetInventory().GetOptionalFields().GetIsMultipartUploaded()); + ASSERT_TRUE(resp.GetInventory().GetOptionalFields().GetIsReplicationStatus()); + ASSERT_EQ(resp.GetInventory().GetFilter(), "myPrefix"); + ASSERT_EQ(resp.GetInventory().GetFrequency(), "Daily"); + ASSERT_EQ(resp.GetInventory().GetCOSBucketDestination().GetAccountId(), "1250000000"); + ASSERT_EQ(resp.GetInventory().GetCOSBucketDestination().GetBucket(), "qcs::cos:ap-guangzhou::examplebucket-1250000000"); + ASSERT_TRUE(resp.GetInventory().GetCOSBucketDestination().GetEncryption()); + ASSERT_EQ(resp.GetInventory().GetCOSBucketDestination().GetFormat(), "CSV"); + ASSERT_EQ(resp.GetInventory().GetCOSBucketDestination().GetPrefix(), "list1"); + } + +} + +} // namespace qcloud_cos \ No newline at end of file diff --git a/unittest/src/object_op_test.cpp b/unittest/src/object_op_test.cpp index 7a85f32..fe6d581 100644 --- a/unittest/src/object_op_test.cpp +++ b/unittest/src/object_op_test.cpp @@ -7,6 +7,7 @@ #include +#include #include "Poco/MD5Engine.h" #include "Poco/StreamCopier.h" #include "cos_api.h" @@ -421,6 +422,29 @@ TEST_F(ObjectOpTest, HeadObjectTest) { EXPECT_EQ("AES256", head_resp.GetXCosServerSideEncryption()); } } +TEST_F(ObjectOpTest, PutDirectoryTest) { + { + std::string directory_name = "put_directory_test"; + PutDirectoryReq req(m_bucket_name, directory_name); + PutDirectoryResp resp; + CosResult result = m_client->PutDirectory(req, &resp); + ASSERT_TRUE(result.IsSucc()); + } +} + +TEST_F(ObjectOpTest, MoveObjectTest) { + { + std::istringstream iss("put_obj_by_stream_normal_string"); + PutObjectByStreamReq req(m_bucket_name, "move_object_src", iss); + PutObjectByStreamResp resp; + CosResult result = m_client->PutObject(req, &resp); + ASSERT_TRUE(result.IsSucc()); + + MoveObjectReq mv_req(m_bucket_name, "move_object_src", "move_object_dst"); + CosResult mv_result = m_client->MoveObject(mv_req); + ASSERT_TRUE(mv_result.IsSucc()); + } +} TEST_F(ObjectOpTest, DeleteObjectTest) { { @@ -434,6 +458,500 @@ TEST_F(ObjectOpTest, DeleteObjectTest) { } } + +TEST_F(ObjectOpTest, DeleteObjectsTest) { + // 批量上传+批量删除 + { + std::string directory_name = "delete_objects_testfile_directory"; + if(!TestUtils::IsDirectoryExists(directory_name) && TestUtils::MakeDirectory(directory_name)){ + std::string object_name1 = "testfile1"; + std::string object_name2 = "testfile2"; + std::string object_name3 = "testfile3"; + std::string object_name4 = "testfile4"; + std::string local_file1 = "./" + directory_name + "/" + object_name1; + std::string local_file2 = "./" + directory_name + "/" + object_name2; + std::string local_file3 = "./" + directory_name + "/" + object_name3; + std::string local_file4 = "./" + directory_name + "/" + object_name4; + TestUtils::WriteRandomDatatoFile(local_file1, 1024); + TestUtils::WriteRandomDatatoFile(local_file2, 1024); + TestUtils::WriteRandomDatatoFile(local_file3, 1024); + TestUtils::WriteRandomDatatoFile(local_file4, 1024); + + PutObjectsByDirectoryReq req(m_bucket_name, directory_name); + PutObjectsByDirectoryResp resp; + CosResult result = m_client->PutObjects(req, &resp); + ASSERT_TRUE(result.IsSucc()); + TestUtils::RemoveFile(local_file1); + TestUtils::RemoveFile(local_file2); + TestUtils::RemoveFile(local_file3); + TestUtils::RemoveFile(local_file4); + TestUtils::RemoveDirectory(directory_name); + + DeleteObjectsByPrefixReq del_req(m_bucket_name, directory_name); + DeleteObjectsByPrefixResp del_resp; + CosResult del_result = m_client->DeleteObjects(del_req, &del_resp); + ASSERT_TRUE(del_result.IsSucc()); + } + } + //批量删除 + { + std::string object_name1 = "testfile1"; + std::string object_name2 = "testfile2"; + std::string object_name3 = "testfile3"; + std::string object_name4 = "testfile4"; + std::istringstream iss("put_obj_by_stream_normal_string"); + PutObjectByStreamReq put_req1(m_bucket_name, object_name1, iss); + PutObjectByStreamResp put_resp1; + CosResult put_result1 = m_client->PutObject(put_req1, &put_resp1); + ASSERT_TRUE(put_result1.IsSucc()); + PutObjectByStreamReq put_req2(m_bucket_name, object_name2, iss); + PutObjectByStreamResp put_resp2; + CosResult put_result2 = m_client->PutObject(put_req2, &put_resp2); + ASSERT_TRUE(put_result2.IsSucc()); + PutObjectByStreamReq put_req3(m_bucket_name, object_name3, iss); + PutObjectByStreamResp put_resp3; + CosResult put_result3 = m_client->PutObject(put_req3, &put_resp3); + ASSERT_TRUE(put_result3.IsSucc()); + PutObjectByStreamReq put_req4(m_bucket_name, object_name4, iss); + PutObjectByStreamResp put_resp4; + CosResult put_result4 = m_client->PutObject(put_req4, &put_resp4); + ASSERT_TRUE(put_result4.IsSucc()); + + std::vector objects; + std::vector to_be_deleted; + objects.push_back(object_name1); + objects.push_back(object_name2); + objects.push_back(object_name3); + objects.push_back(object_name4); + for (size_t idx = 0; idx < objects.size(); ++idx) { + ObjectVersionPair pair; + pair.m_object_name = objects[idx]; + to_be_deleted.push_back(pair); + } + qcloud_cos::DeleteObjectsReq req(m_bucket_name, to_be_deleted); + qcloud_cos::DeleteObjectsResp resp; + qcloud_cos::CosResult del_result = m_client->DeleteObjects(req, &resp); + ASSERT_TRUE(del_result.IsSucc()); + } +} + +TEST_F(ObjectOpTest, GetObjectByStreamTest) { + { + std::istringstream iss("put_obj_by_stream_normal_string"); + std::string object_name = "get_object_by_stream_test"; + PutObjectByStreamReq put_req(m_bucket_name, object_name, iss); + PutObjectByStreamResp put_resp; + CosResult put_result = m_client->PutObject(put_req, &put_resp); + ASSERT_TRUE(put_result.IsSucc()); + + std::ostringstream os; + GetObjectByStreamReq get_req(m_bucket_name, object_name, os); + GetObjectByStreamResp get_resp; + CosResult get_result = m_client->GetObject(get_req, &get_resp); + ASSERT_TRUE(get_result.IsSucc()); + + DeleteObjectReq del_req(m_bucket_name, object_name); + DeleteObjectResp del_resp; + CosResult del_result = m_client->DeleteObject(del_req, &del_resp); + ASSERT_TRUE(del_result.IsSucc()); + } + + // 下载服务端加密的文件 + { + std::istringstream iss("put_obj_by_stream_normal_string"); + std::string object_name = "get_sse_object_test"; + PutObjectByStreamReq put_req(m_bucket_name, object_name, iss); + put_req.SetXCosServerSideEncryption("AES256"); + PutObjectByStreamResp put_resp; + CosResult put_result = m_client->PutObject(put_req, &put_resp); + ASSERT_TRUE(put_result.IsSucc()); + + std::ostringstream os; + GetObjectByStreamReq get_req(m_bucket_name, object_name, os); + GetObjectByStreamResp get_resp; + CosResult get_result = m_client->GetObject(get_req, &get_resp); + ASSERT_TRUE(get_result.IsSucc()); + EXPECT_EQ("AES256", get_resp.GetXCosServerSideEncryption()); + + DeleteObjectReq del_req(m_bucket_name, object_name); + DeleteObjectResp del_resp; + CosResult del_result = m_client->DeleteObject(del_req, &del_resp); + ASSERT_TRUE(del_result.IsSucc()); + } +} + +TEST_F(ObjectOpTest, GetObjectUrlTest) { + std::string destdomain = m_config->GetDestDomain().empty() ? + CosSysConfig::GetDestDomain() : m_config->GetDestDomain(); + { + std::string object_url = m_client->GetObjectUrl("get_object_url_test_bucket_name", + "get_object_url_test_object_name", + true, + "get_object_url_test_region"); + std::string myUrl = destdomain; + if(destdomain.empty()){ + myUrl = "get_object_url_test_bucket_name.cos.get_object_url_test_region.myqcloud.com/get_object_url_test_object_name"; + } + ASSERT_EQ(object_url, "https://"+myUrl); + } + + { + std::string object_url = m_client->GetObjectUrl("get_object_url_test_bucket_name", + "get_object_url_test_object_name", + false, + ""); + std::string myUrl = destdomain; + if(destdomain.empty()){ + myUrl = "get_object_url_test_bucket_name.cos." + GetEnvVar("CPP_SDK_V5_REGION") + ".myqcloud.com/get_object_url_test_object_name"; + } + ASSERT_EQ(object_url, "http://"+myUrl); + } +} + +TEST_F(ObjectOpTest, PostObjectRestoreTest) { + //上传 + { + std::istringstream iss("put object"); + PutObjectByStreamReq req(m_bucket_name, "post_object_restore", iss); + req.SetXCosStorageClass("ARCHIVE"); + PutObjectByStreamResp resp; + CosResult result = m_client->PutObject(req, &resp); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetXCosStorageClass(), "ARCHIVE"); + } + //post + { + PostObjectRestoreReq req(m_bucket_name, "post_object_restore"); + req.SetExiryDays(30); + req.SetTier("Standard"); + PostObjectRestoreResp resp; + CosResult result = m_client->PostObjectRestore(req, &resp); + ASSERT_TRUE(result.IsSucc()); + } + //删除 + { + DeleteObjectReq req(m_bucket_name, "post_object_restore"); + DeleteObjectResp resp; + CosResult result = m_client->DeleteObject(req, &resp); + ASSERT_TRUE(result.IsSucc()); + } +} + +TEST_F(ObjectOpTest, PutBucketToCITest) { + bool use_dns_cache = CosSysConfig::GetUseDnsCache(); + CosSysConfig::SetUseDnsCache(false); + { + PutBucketToCIReq req(m_bucket_name); + PutBucketToCIResp resp; + CosResult result = m_client->PutBucketToCI(req, &resp); + ASSERT_TRUE(result.IsSucc()); + } + CosSysConfig::SetUseDnsCache(use_dns_cache); +} + +TEST_F(ObjectOpTest, ImageProcessTest) { + bool use_dns_cache = CosSysConfig::GetUseDnsCache(); + CosSysConfig::SetUseDnsCache(false); + std::string object_name = "test.jpg"; + //上传处理 + { + PutImageByFileReq req(m_bucket_name, object_name, "../../demo/test_file/test.jpg"); + PutImageByFileResp resp; + + PicOperation pic_operation; + PicRules rule1; + std::string newname = "/" + object_name + "_put_qrcode.jpg"; + rule1.fileid = newname; + rule1.rule = "QRcode/cover/1"; + pic_operation.AddRule(rule1); + req.SetPicOperation(pic_operation); + CosResult result = m_client->PutImage(req, &resp); + ASSERT_TRUE(result.IsSucc()); + ASSERT_TRUE(m_client->IsObjectExist(m_bucket_name, newname)); + } + //云上处理 + { + CloudImageProcessReq req(m_bucket_name, object_name); + CloudImageProcessResp resp; + PicOperation pic_operation; + PicRules rule; + std::string newname = "/" + object_name + "_cut.jpg"; + rule.fileid = newname; + rule.rule = "imageMogr2/cut/300x300"; + pic_operation.AddRule(rule); + req.SetPicOperation(pic_operation); + CosResult result = m_client->CloudImageProcess(req, &resp); + ASSERT_TRUE(result.IsSucc()); + ASSERT_TRUE(m_client->IsObjectExist(m_bucket_name, newname)); + } + //下载处理 + { + GetQRcodeReq req(m_bucket_name, object_name); + GetQRcodeResp resp; + CosResult result = m_client->GetQRcode(req, &resp); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetResult().qr_code_info[0].code_url, "testimage"); + } + CosSysConfig::SetUseDnsCache(use_dns_cache); +} + +//媒体接口 +TEST_F(ObjectOpTest, MediaTest) { + bool use_dns_cache = CosSysConfig::GetUseDnsCache(); + CosSysConfig::SetUseDnsCache(false); + std::string object_name = "video.mp4"; + //上传媒体 + { + PutObjectByFileReq put_req(m_bucket_name, object_name, "../../demo/test_file/video.mp4"); + put_req.SetRecvTimeoutInms(1000 * 200); + PutObjectByFileResp put_resp; + CosResult put_result = m_client->PutObject(put_req, &put_resp); + ASSERT_TRUE(put_result.IsSucc()); + } + //绑定媒体服务 + { + CreateMediaBucketReq req(m_bucket_name); + CreateMediaBucketResp resp; + CosResult result = m_client->CreateMediaBucket(req, &resp); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetResult().media_bucket.name, m_bucket_name); + ASSERT_EQ(resp.GetResult().media_bucket.region, GetEnvVar("CPP_SDK_V5_REGION")); + } + //info + { + GetMediaInfoReq req(m_bucket_name, object_name); + GetMediaInfoResp resp; + CosResult result = m_client->GetMediaInfo(req, &resp); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetResult().media_info.stream.video.codec_name, "h264"); + ASSERT_EQ(resp.GetResult().media_info.stream.video.height, 360); + ASSERT_EQ(resp.GetResult().media_info.stream.video.width, 640); + ASSERT_EQ(resp.GetResult().media_info.stream.audio.codec_name, "aac"); + ASSERT_EQ(resp.GetResult().media_info.format.num_stream, 4); + } + //截图 + { + GetSnapshotReq req(m_bucket_name, object_name, "local_file_snapshot.jpg"); + GetSnapshotResp resp; + req.SetTime(10); + CosResult result = m_client->GetSnapshot(req, &resp); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetContentType(), "image/jpeg"); + TestUtils::RemoveFile("local_file_snapshot.jpg"); + } + CosSysConfig::SetUseDnsCache(use_dns_cache); +} + + + +//审核接口 +TEST_F(ObjectOpTest, AuditingTest) { + bool use_dns_cache = CosSysConfig::GetUseDnsCache(); + CosSysConfig::SetUseDnsCache(false); + //请勿改变审核测试前后的顺序 + std::string image_object_name = "test.jpg"; + std::string video_object_name = "video.mp4"; + //图片同步审核 + { + GetImageAuditingReq req(m_bucket_name); + GetImageAuditingResp resp; + req.SetObjectKey(image_object_name); + req.SetDataId("data_id_example"); + req.SetDetectType("ads,porn,politics,terrorism"); + req.SetInterval(1); + req.SetMaxFrames(2); + CosResult result = m_client->GetImageAuditing(req, &resp); + resp.GetJobsDetail().to_string(); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetJobsDetail().GetDataId(), "data_id_example"); + ASSERT_EQ(resp.GetJobsDetail().GetState(), "Success"); + ASSERT_EQ(resp.GetJobsDetail().GetObject(), image_object_name); + + DescribeImageAuditingJobReq describe_req(m_bucket_name); + DescribeImageAuditingJobResp describe_resp; + describe_req.SetJobId(resp.GetJobsDetail().GetJobId()); + CosResult describe_result = m_client->DescribeImageAuditingJob(describe_req, &describe_resp); + ASSERT_TRUE(describe_result.IsSucc()); + ASSERT_EQ(describe_resp.GetJobsDetail().GetDataId(), "data_id_example"); + } + //批量图片审核 + { + BatchImageAuditingReq req(m_bucket_name); + BatchImageAuditingResp resp; + AuditingInput input = AuditingInput(); + input.SetObject(image_object_name); + input.SetDataId("data_id_example2"); + req.AddInput(input); + req.SetDetectType("Ads,Porn,Politics,Terrorism"); + CosResult result = m_client->BatchImageAuditing(req, &resp); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetJobsDetails()[0].GetDataId(), "data_id_example2"); + ASSERT_EQ(resp.GetJobsDetails()[0].GetState(), "Success"); + ASSERT_EQ(resp.GetJobsDetails()[0].GetObject(), image_object_name); + } + //提交视频审核任务 + std::string video_job_id; + { + CreateVideoAuditingJobReq req(m_bucket_name); + CreateVideoAuditingJobResp resp; + req.SetObject(video_object_name); + req.SetDataId("DataId"); + SnapShotConf snap_shot = SnapShotConf(); + snap_shot.SetCount(5); + snap_shot.SetMode("Interval"); + req.SetSnapShot(snap_shot); + req.SetDetectType("Porn,Ads,Politics,Terrorism,Abuse,Illegal"); + req.SetDetectContent(0); + CosResult result = m_client->CreateVideoAuditingJob(req, &resp); + video_job_id = resp.GetJobsDetail().GetJobId(); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetJobsDetail().GetState(), "Submitted"); + } + //提交音频审核任务 + std::string audio_object_name = "audio.mp3"; + std::string audio_job_id; + { + { + PutObjectByFileReq put_req(m_bucket_name, audio_object_name, "../../demo/test_file/audio.mp3"); + put_req.SetRecvTimeoutInms(1000 * 200); + PutObjectByFileResp put_resp; + CosResult put_result = m_client->PutObject(put_req, &put_resp); + ASSERT_TRUE(put_result.IsSucc()); + } + { + CreateAudioAuditingJobReq req(m_bucket_name); + CreateAudioAuditingJobResp resp; + req.SetObject(audio_object_name); + req.SetDataId("DataId"); + req.SetDetectType("Porn,Ads,Politics,Terrorism,Abuse,Illegal"); + req.SetCallBackVersion("Simple"); + CosResult result = m_client->CreateAudioAuditingJob(req, &resp); + audio_job_id = resp.GetJobsDetail().GetJobId(); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetJobsDetail().GetState(), "Submitted"); + } + + + } + //提交文本审核任务 + std::string text_object_name = "text.txt"; + std::string text_job_id; + { + { + PutObjectByFileReq put_req(m_bucket_name, text_object_name, "../../demo/test_file/text.txt"); + put_req.SetRecvTimeoutInms(1000 * 200); + PutObjectByFileResp put_resp; + CosResult put_result = m_client->PutObject(put_req, &put_resp); + ASSERT_TRUE(put_result.IsSucc()); + } + { + CreateTextAuditingJobReq req(m_bucket_name); + CreateTextAuditingJobResp resp; + req.SetObject(text_object_name); + req.SetDataId("DataId"); + req.SetDetectType("Porn,Ads,Politics,Terrorism,Abuse,Illegal"); + req.SetCallBackVersion("Simple"); + CosResult result = m_client->CreateTextAuditingJob(req, &resp); + text_job_id = resp.GetJobsDetail().GetJobId(); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetJobsDetail().GetState(), "Submitted"); + } + } + //提交文档审核任务 + std::string document_object_name = "document.docx"; + std::string document_job_id; + { + { + PutObjectByFileReq put_req(m_bucket_name, document_object_name, "../../demo/test_file/document.docx"); + put_req.SetRecvTimeoutInms(1000 * 200); + PutObjectByFileResp put_resp; + CosResult put_result = m_client->PutObject(put_req, &put_resp); + ASSERT_TRUE(put_result.IsSucc()); + } + { + CreateDocumentAuditingJobReq req(m_bucket_name); + CreateDocumentAuditingJobResp resp; + req.SetObject(document_object_name); + req.SetDataId("DataId"); + req.SetType("docx"); + req.SetDetectType("Porn,Ads,Politics,Terrorism,Abuse,Illegal"); + CosResult result = m_client->CreateDocumentAuditingJob(req, &resp); + document_job_id = resp.GetJobsDetail().GetJobId(); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetJobsDetail().GetState(), "Submitted"); + } + } + //提交网页审核任务 + std::string url_job_id; + { + CreateWebPageAuditingJobReq req(m_bucket_name); + CreateWebPageAuditingJobResp resp; + req.SetUrl("https://www.baidu.com/"); + req.SetDataId("DataId"); + req.SetDetectType("Porn,Ads,Politics,Terrorism,Abuse,Illegal"); + CosResult result = m_client->CreateWebPageAuditingJob(req, &resp); + url_job_id = resp.GetJobsDetail().GetJobId(); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetJobsDetail().GetState(), "Submitted"); + } + std::this_thread::sleep_for(std::chrono::seconds(10)); + //查询视频审核结果 + { + DescribeVideoAuditingJobReq req(m_bucket_name); + DescribeVideoAuditingJobResp resp; + req.SetJobId(video_job_id); + CosResult result = m_client->DescribeVideoAuditingJob(req, &resp); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetJobsDetail().GetState(), "Success"); + resp.GetJobsDetail().to_string(); + } + //查询音频审核结果 + { + DescribeAudioAuditingJobReq req(m_bucket_name); + DescribeAudioAuditingJobResp resp; + req.SetJobId(audio_job_id); + CosResult result = m_client->DescribeAudioAuditingJob(req, &resp); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetJobsDetail().GetState(), "Success"); + } + //查询文本审核结果 + { + DescribeTextAuditingJobReq req(m_bucket_name); + DescribeTextAuditingJobResp resp; + req.SetJobId(text_job_id); + CosResult result = m_client->DescribeTextAuditingJob(req, &resp); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetJobsDetail().GetState(), "Success"); + resp.GetJobsDetail().to_string(); + } + //查询文档审核结果 + { + DescribeDocumentAuditingJobReq req(m_bucket_name); + DescribeDocumentAuditingJobResp resp; + req.SetJobId(document_job_id); + CosResult result = m_client->DescribeDocumentAuditingJob(req, &resp); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetJobsDetail().GetState(), "Success"); + resp.GetJobsDetail().GetLabels().to_string(); + if (resp.GetJobsDetail().GetPageSegment().HasResults()){ + resp.GetJobsDetail().GetPageSegment().to_string(); + resp.GetJobsDetail().GetPageSegment().GetResults()[0].to_string(); + resp.GetJobsDetail().to_string(); + } + } + //查询网页审核结果 + { + DescribeWebPageAuditingJobReq req(m_bucket_name); + DescribeWebPageAuditingJobResp resp; + req.SetJobId(url_job_id); + CosResult result = m_client->DescribeWebPageAuditingJob(req, &resp); + ASSERT_TRUE(result.IsSucc()); + ASSERT_EQ(resp.GetJobsDetail().GetState(), "Success"); + resp.GetJobsDetail().to_string(); + } + CosSysConfig::SetUseDnsCache(use_dns_cache); +} + TEST_F(ObjectOpTest, GetObjectByFileTest) { { std::istringstream iss("put_obj_by_stream_normal_string"); @@ -489,6 +1007,35 @@ TEST_F(ObjectOpTest, GetObjectByFileTest) { } } +TEST_F(ObjectOpTest, ResumableGetObjectTest) { + { + std::istringstream iss("put_obj_by_stream_normal_string"); + std::string object_name = "resumable_get_object_test"; + PutObjectByStreamReq put_req(m_bucket_name, object_name, iss); + PutObjectByStreamResp put_resp; + CosResult put_result = m_client->PutObject(put_req, &put_resp); + ASSERT_TRUE(put_result.IsSucc()); + + std::string file_download = "resumable_get_object_test_file_download"; + GetObjectByFileReq get_req(m_bucket_name, object_name, file_download); + GetObjectByFileResp get_resp; + CosResult get_result = m_client->ResumableGetObject(get_req, &get_resp); + + ASSERT_TRUE(get_result.IsSucc()); + + std::string file_md5_download = TestUtils::CalcFileMd5(file_download); + ASSERT_EQ(file_md5_download, get_resp.GetEtag()); + + DeleteObjectReq del_req(m_bucket_name, object_name); + DeleteObjectResp del_resp; + CosResult del_result = m_client->DeleteObject(del_req, &del_resp); + ASSERT_TRUE(del_result.IsSucc()); + + TestUtils::RemoveFile(file_download); + } +} + + TEST_F(ObjectOpTest, MultiPutObjectTest) { { uint64_t part_size = 20 * 1000 * 1000; @@ -667,6 +1214,86 @@ TEST_F(ObjectOpTest, MultiPutObjectTest_OneStep) { } } +TEST_F(ObjectOpTest, UploadPartCopyDataTest) { + //上传一个对象 + { + std::string local_file = "./object_test_upload_part_copy_data_source"; + TestUtils::WriteRandomDatatoFile(local_file, 100 * 1024 * 1024); + PutObjectByFileReq req(m_bucket_name, "object_test_upload_part_copy_data_source", local_file); + req.SetXCosStorageClass(kStorageClassStandard); + PutObjectByFileResp resp; + CosResult result = m_client->PutObject(req, &resp); + ASSERT_TRUE(result.IsSucc()); + TestUtils::RemoveFile(local_file); + } + //分块copy + { + qcloud_cos::HeadObjectReq req(m_bucket_name, "object_test_upload_part_copy_data_source"); + qcloud_cos::HeadObjectResp resp; + uint64_t part_size = 30 * 1024 * 1024; + uint64_t copy_size = 100 * 1024 * 1024; + uint64_t no_copy_size = copy_size; + + std::string object_name_copy = "object_test_upload_part_copy_data_copy"; + InitMultiUploadReq init_req(m_bucket_name, object_name_copy); + InitMultiUploadResp init_resp; + CosResult init_result = m_client->InitMultiUpload(init_req, &init_resp); + ASSERT_TRUE(init_result.IsSucc()); + std::string host = CosSysConfig::GetHost(m_config->GetAppId(), m_config->GetRegion(), + m_bucket_name); + std::vector etags; + std::vector part_numbers; + for (uint64_t part_cnt = 0; no_copy_size > 0; ++part_cnt) { + UploadPartCopyDataReq req(m_bucket_name, object_name_copy, init_resp.GetUploadId(), + part_cnt + 1); + req.SetXCosCopySource(host + "/object_test_upload_part_copy_data_source"); + std::string range = "bytes=" + std::to_string(part_cnt * part_size) + "-"; + if(no_copy_size > part_size) { + range += std::to_string(((part_cnt + 1) * part_size) - 1); + }else range += std::to_string(copy_size - 1); + req.SetXCosCopySourceRange(range); + UploadPartCopyDataResp resp; + CosResult result = m_client->UploadPartCopyData(req, &resp); + ASSERT_TRUE(result.IsSucc()); + if(no_copy_size > part_size) { + no_copy_size -= part_size; + }else { + no_copy_size = 0; + } + etags.push_back(resp.GetEtag()); + part_numbers.push_back(part_cnt + 1); + } + qcloud_cos::CompleteMultiUploadReq com_req(m_bucket_name, object_name_copy, init_resp.GetUploadId()); + qcloud_cos::CompleteMultiUploadResp com_resp; + com_req.SetEtags(etags); + com_req.SetPartNumbers(part_numbers); + qcloud_cos::CosResult com_result = m_client->CompleteMultiUpload(com_req, &com_resp); + ASSERT_TRUE(com_result.IsSucc()); + } +} +TEST_F(ObjectOpTest, CopyTest) { + //上传一个对象 + { + std::string local_file = "./object_test_copy_data_source"; + TestUtils::WriteRandomDatatoFile(local_file, 100 * 1024 * 1024); + PutObjectByFileReq req(m_bucket_name, "object_test_copy_data_source", local_file); + req.SetXCosStorageClass(kStorageClassStandard); + PutObjectByFileResp resp; + CosResult result = m_client->PutObject(req, &resp); + ASSERT_TRUE(result.IsSucc()); + TestUtils::RemoveFile(local_file); + } + { + std::string host = CosSysConfig::GetHost(m_config->GetAppId(), m_config->GetRegion(), + m_bucket_name); + CopyReq req(m_bucket_name, "object_test_copy_data_copy"); + CopyResp resp; + req.SetXCosCopySource(host + "/object_test_copy_data_source"); + CosResult result = m_client->Copy(req, &resp); + ASSERT_TRUE(result.IsSucc()); + } +} + TEST_F(ObjectOpTest, AbortMultiUploadTest) { uint64_t part_size = 20 * 1000 * 1000; uint64_t max_part_num = 3; diff --git a/unittest/src/object_response_test.cpp b/unittest/src/object_response_test.cpp index e2675c4..afecc4b 100644 --- a/unittest/src/object_response_test.cpp +++ b/unittest/src/object_response_test.cpp @@ -7,17 +7,522 @@ #include "gtest/gtest.h" #include "response/object_resp.h" +#include "response/data_process_resp.h" +#include "response/auditing_resp.h" namespace qcloud_cos { -TEST(ObjectRespTest, NormalTest) { +TEST(ObjectRespTest, DocTest) { { - GetObjectResp resp; - std::map input_headers; - input_headers[kReqHeaderContentLen] = "123"; - kReqHeaderContentType kReqHeaderXCosTraceId kReqHeaderXCosReqId - kReqHeaderServer kReqHeaderDate kReqHeaderConnection kReqHeaderEtag - resp.ParseFromHeaders(input_headers); + DocPreviewResp resp; + std::map headers = { + {kRespHeaderXTotalPage, "2"}, + {kRespHeaderXErrNo, "0"}, + {kRespHeaderXTotalSheet, "1"}, + {kRespHeaderXSheetName, "test1"} + }; + resp.ParseFromHeaders(headers); + ASSERT_EQ(resp.GetTotalPage(), 2); + ASSERT_EQ(resp.GetErrNo(), "0"); + ASSERT_EQ(resp.GetTotalSheet(), 1); + ASSERT_EQ(resp.GetSheetName(), "test1"); + } + std::string base_body; + { + CreateDocProcessJobsResp resp; + std::string body; + body += "\n"; + base_body += " \n"; + base_body += " 0\n"; + base_body += " 1\n"; + base_body += " 2\n"; + base_body += " \n"; + base_body += " 3\n"; + base_body += " \n"; + base_body += " 4\n"; + base_body += " \n"; + base_body += " \n"; + base_body += " \n"; + base_body += " 5\n"; + base_body += " 6\n"; + base_body += " 7\n"; + base_body += " 8\n"; + base_body += " 16\n"; + base_body += " 17\n"; + base_body += " 18\n"; + base_body += " 19\n"; + base_body += " 20\n"; + base_body += " 20\n"; + base_body += " 21\n"; + base_body += " 9\n"; + base_body += " \n"; + base_body += " \n"; + base_body += " 10\n"; + base_body += " 11\n"; + base_body += " 12\n"; + base_body += " \n"; + base_body += " \n"; + base_body += " \n"; + base_body += " 22\n"; + base_body += " 23\n"; + base_body += " 24\n"; + base_body += " 32\n"; + base_body += " 25\n"; + base_body += " \n"; + base_body += " 26\n"; + base_body += " 27\n"; + base_body += " 28\n"; + base_body += " 29\n"; + base_body += " 30\n"; + base_body += " 31\n"; + base_body += " \n"; + base_body += " \n"; + base_body += " 13\n"; + base_body += " 14\n"; + base_body += " 15\n"; + base_body += " \n"; + body += base_body + ""; + resp.ParseFromXmlString(body); + ASSERT_EQ(resp.GetJobsDetail().code, "0"); + ASSERT_EQ(resp.GetJobsDetail().create_time, "1"); + ASSERT_EQ(resp.GetJobsDetail().end_time, "2"); + ASSERT_EQ(resp.GetJobsDetail().input.object, "3"); + resp.GetJobsDetail().input.to_string(); + ASSERT_EQ(resp.GetJobsDetail().job_id, "4"); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.src_type, "5"); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.tgt_type, "6"); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.sheet_id, 16); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.start_page, 7); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.end_page, 8); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.image_params, "9"); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.doc_passwd, "17"); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.comments, 18); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.paper_direction, 19); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.quality, 20); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process.zoom, 21); + resp.GetJobsDetail().operation.doc_process.to_string(); + ASSERT_EQ(resp.GetJobsDetail().operation.output.bucket, "10"); + ASSERT_EQ(resp.GetJobsDetail().operation.output.object, "11"); + ASSERT_EQ(resp.GetJobsDetail().operation.output.region, "12"); + resp.GetJobsDetail().operation.output.to_string(); + ASSERT_EQ(resp.GetJobsDetail().queue_id, "13"); + ASSERT_EQ(resp.GetJobsDetail().state, "14"); + ASSERT_EQ(resp.GetJobsDetail().tag, "15"); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.page_infos[0].page_no, 22); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.page_infos[0].tgt_uri, "23"); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.page_infos[0].x_sheet_pics, 24); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.page_infos[0].pic_index, 32); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.page_infos[0].pic_num, 25); + resp.GetJobsDetail().operation.doc_process_result.page_infos[0].to_string(); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.tgt_type, "26"); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.task_id, "31"); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.total_pageount, 27); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.succ_pagecount, 28); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.fail_pagecount, 29); + ASSERT_EQ(resp.GetJobsDetail().operation.doc_process_result.total_sheetcount, 30); + resp.GetJobsDetail().operation.doc_process_result.to_string(); + resp.GetJobsDetail().operation.to_string(); + resp.GetJobsDetail().to_string(); + } + { + DescribeDocProcessJobsResp resp; + std::string body; + body += "\n"; + body += base_body; + body += " 32\n"; + body += ""; + // std::cout << body << std::endl; + resp.ParseFromXmlString(body); + ASSERT_EQ(resp.GetNextToken(), "32"); + } + { + std::string body = "\n"; + body += " 1\n"; + body += " RequestId\n"; + body += " 1\n"; + body += " 2\n"; + body += " \n"; + body += " QueueId\n"; + body += " QueueName\n"; + body += " Active\n"; + body += " \n"; + body += " url\n"; + body += " Event\n"; + body += " Type\n"; + body += " Off\n"; + body += " \n"; + body += " 10000\n"; + body += " 10\n"; + body += " CreateTime\n"; + body += " UpdateTime\n"; + body += " BucketId\n"; + body += " DocProcess\n"; + body += " \n"; + body += " \n"; + body += " 3\n"; + body += " \n"; + body += ""; + DescribeDocProcessQueuesResp resp; + resp.ParseFromXmlString(body); + ASSERT_EQ(resp.GetTotalCount(), 1); + ASSERT_EQ(resp.GetRequestId(), "RequestId"); + ASSERT_EQ(resp.GetPageNumber(), 1); + ASSERT_EQ(resp.GetPageSize(), 2); + ASSERT_EQ(resp.GetQueueList().queue_id, "QueueId"); + ASSERT_EQ(resp.GetQueueList().name, "QueueName"); + ASSERT_EQ(resp.GetQueueList().state, "Active"); + ASSERT_EQ(resp.GetQueueList().notify_config.url, "url"); + ASSERT_EQ(resp.GetQueueList().notify_config.event, "Event"); + ASSERT_EQ(resp.GetQueueList().notify_config.type, "Type"); + ASSERT_EQ(resp.GetQueueList().notify_config.state, "Off"); + ASSERT_EQ(resp.GetQueueList().max_size, 10000); + ASSERT_EQ(resp.GetQueueList().max_concurrent, 10); + ASSERT_EQ(resp.GetQueueList().create_time, "CreateTime"); + ASSERT_EQ(resp.GetQueueList().update_time, "UpdateTime"); + ASSERT_EQ(resp.GetQueueList().bucket_id, "BucketId"); + ASSERT_EQ(resp.GetQueueList().category, "DocProcess"); + resp.GetQueueList().to_string(); + ASSERT_EQ(resp.GetNonExistPIDs().queue_id[0], "3"); + } + { + std::string body = "\n"; + body += " RequestId\n"; + body += " \n"; + body += " QueueId\n"; + body += " QueueName\n"; + body += " Active\n"; + body += " \n"; + body += " url\n"; + body += " Event\n"; + body += " Type\n"; + body += " Off\n"; + body += " \n"; + body += " 10000\n"; + body += " 10\n"; + body += " CreateTime\n"; + body += " UpdateTime\n"; + body += " BucketId\n"; + body += " DocProcess\n"; + body += " \n"; + body += ""; + UpdateDocProcessQueueResp resp; + resp.ParseFromXmlString(body); + ASSERT_EQ(resp.GetRequestId(), "RequestId"); + ASSERT_EQ(resp.GetQueueList().queue_id, "QueueId"); + ASSERT_EQ(resp.GetQueueList().name, "QueueName"); + ASSERT_EQ(resp.GetQueueList().state, "Active"); + ASSERT_EQ(resp.GetQueueList().notify_config.url, "url"); + ASSERT_EQ(resp.GetQueueList().notify_config.event, "Event"); + ASSERT_EQ(resp.GetQueueList().notify_config.type, "Type"); + ASSERT_EQ(resp.GetQueueList().notify_config.state, "Off"); + ASSERT_EQ(resp.GetQueueList().max_size, 10000); + ASSERT_EQ(resp.GetQueueList().max_concurrent, 10); + ASSERT_EQ(resp.GetQueueList().create_time, "CreateTime"); + ASSERT_EQ(resp.GetQueueList().update_time, "UpdateTime"); + ASSERT_EQ(resp.GetQueueList().bucket_id, "BucketId"); + ASSERT_EQ(resp.GetQueueList().category, "DocProcess"); + } +} + +TEST(ObjectRespTest, ObjectTest) { + { + std::string body = "\n"; + body += " Location\n"; + body += " Bucket\n"; + body += " Key\n"; + body += " ETag\n"; + body += ""; + MultiPutObjectResp resp; + resp.ParseFromXmlString(body); + ASSERT_EQ(resp.GetLocation(), "Location"); + ASSERT_EQ(resp.GetBucket(), "Bucket"); + ASSERT_EQ(resp.GetKey(), "Key"); + ASSERT_EQ(resp.GetEtag(), "ETag"); + } + { + std::string body; + body += "\n"; + body += " \n"; + body += " StartTime\n"; + body += " EndTime\n"; + body += " RemoteAddr\n"; + body += " RequestId\n"; + body += " \n"; + body += ""; + GetLiveChannelHistoryResp resp; + resp.ParseFromXmlString(body); + ASSERT_EQ(resp.GetChanHistory()[0].m_start_time, "StartTime"); + ASSERT_EQ(resp.GetChanHistory()[0].m_end_time, "EndTime"); + ASSERT_EQ(resp.GetChanHistory()[0].m_remote_addr, "RemoteAddr"); + ASSERT_EQ(resp.GetChanHistory()[0].m_request_id, "RequestId"); + } + { + std::string body; + body += "\n"; + body += " Live\n"; + body += " ConnectedTime\n"; + body += " RemoteAddr\n"; + body += " RequestId\n"; + body += " \n"; + body += " \n"; + body += ""; + GetLiveChannelStatusResp resp; + resp.ParseFromXmlString(body); + ASSERT_EQ(resp.GetLiveChannelStatus().m_status, "Live"); + ASSERT_EQ(resp.GetLiveChannelStatus().m_connected_time, "ConnectedTime"); + ASSERT_EQ(resp.GetLiveChannelStatus().m_remote_addr, "RemoteAddr"); + ASSERT_EQ(resp.GetLiveChannelStatus().m_request_id, "RequestId"); + ASSERT_EQ(resp.GetLiveChannelStatus().m_video.m_width, "Width"); + ASSERT_EQ(resp.GetLiveChannelStatus().m_video.m_heigh, "Height"); + ASSERT_EQ(resp.GetLiveChannelStatus().m_video.m_framerate, "FrameRate"); + ASSERT_EQ(resp.GetLiveChannelStatus().m_video.m_bandwidth, "Bandwidth"); + ASSERT_EQ(resp.GetLiveChannelStatus().m_video.m_codec, "Codec"); + ASSERT_TRUE(resp.GetLiveChannelStatus().m_has_audio); + ASSERT_EQ(resp.GetLiveChannelStatus().m_audio.m_bandwidth, "Bandwidth"); + ASSERT_EQ(resp.GetLiveChannelStatus().m_audio.m_samplerate, "SampleRate"); + ASSERT_EQ(resp.GetLiveChannelStatus().m_audio.m_codec, "Codec"); + + } + { + std::string body ; + body += "\n"; + body += " \n"; + body += " string1\n"; + body += " true\n"; + body += " string1\n"; + body += " \n"; + body += " \n"; + body += " string2\n"; + body += " string2\n"; + body += " \n"; + body += " \n"; + body += " string3\n"; + body += " false\n"; + body += " string3\n"; + body += " string3\n"; + body += " \n"; + body += " \n"; + body += " string4\n"; + body += " string4\n"; + body += " string4\n"; + body += " string4\n"; + body += " \n"; + body += ""; + DeleteObjectsResp resp; + resp.ParseFromXmlString(body); + ASSERT_EQ(resp.GetErrorMsgs()[0].m_code, "string4"); + ASSERT_EQ(resp.GetErrorMsgs()[0].m_key, "string4"); + ASSERT_EQ(resp.GetErrorMsgs()[0].m_message, "string4"); + ASSERT_EQ(resp.GetErrorMsgs()[0].m_version_id, "string4"); + ASSERT_EQ(resp.GetDeletedInfos()[0].m_key, "string1"); + ASSERT_TRUE(resp.GetDeletedInfos()[0].m_delete_marker); + ASSERT_EQ(resp.GetDeletedInfos()[0].m_delete_marker_version_id, "string1"); + ASSERT_EQ(resp.GetDeletedInfos()[1].m_key, "string2"); + ASSERT_EQ(resp.GetDeletedInfos()[1].m_delete_marker_version_id, "string2"); + ASSERT_EQ(resp.GetDeletedInfos()[2].m_key, "string3"); + ASSERT_TRUE(!resp.GetDeletedInfos()[2].m_delete_marker); + ASSERT_EQ(resp.GetDeletedInfos()[2].m_delete_marker_version_id, "string3"); + ASSERT_EQ(resp.GetDeletedInfos()[2].m_version_id, "string3"); + } +} + +TEST(ObjectRespTest, AudioAuditingRespTest) { + std::string base_body; + { + AudioAuditingResp resp; + std::string body; + body += "\n"; + base_body += " \n"; + base_body += " 0\n"; + base_body += " \n"; + base_body += " 4\n"; + base_body += " 14\n"; + base_body += " 1\n"; + base_body += " 40\n"; + base_body += " \n"; + base_body += " 2\n"; + + base_body += " \n"; + std::string info_body; + info_body += " 3\n"; + info_body += " 3\n"; + info_body += " 3\n"; + info_body += " 3\n"; + info_body += " 3\n"; + info_body += " 3\n"; + info_body += " 3\n"; + info_body += " 3\n"; + info_body += " \n"; + info_body += " 5\n"; + info_body += " 6\n"; + info_body += " \n"; + info_body += " 5\n"; + info_body += " 5\n"; + info_body += " 5\n"; + info_body += " 5\n"; + info_body += " 5\n"; + info_body += " \n"; + info_body += " \n"; + info_body += " \n"; + info_body += " 5\n"; + info_body += " \n"; + info_body += " 5\n"; + info_body += " 5\n"; + info_body += " 5\n"; + info_body += " 5\n"; + info_body += " 5\n"; + info_body += " \n"; + info_body += " \n"; + base_body += info_body; + base_body += " \n"; + + base_body += " \n"; + base_body += info_body; + base_body += " \n"; + + base_body += " \n"; + base_body += info_body; + base_body += " \n"; + + base_body += " \n"; + base_body += info_body; + base_body += " \n"; + + base_body += " \n"; + base_body += info_body; + base_body += " \n"; + + base_body += " \n"; + base_body += info_body; + base_body += " \n"; + + base_body += " \n"; + base_body += " 15\n"; + base_body += " 15\n"; + base_body += " 15\n"; + base_body += " 15\n"; + base_body += " 15\n"; + base_body += " 15\n"; + base_body += " 15\n"; + base_body += " \n"; + base_body += " 13\n"; + base_body += " 15\n"; + base_body += " 15\n"; + base_body += "
\n"; + base_body += " 15\n"; + base_body += " 15\n"; + base_body += " 15\n"; + base_body += " 15\n"; + base_body += " 15\n"; + base_body += " \n"; + base_body += " 15\n"; + base_body += " 15\n"; + base_body += "
\n"; + base_body += "
\n"; + body += base_body + "
"; + resp.ParseFromXmlString(body); + ASSERT_EQ(resp.GetJobsDetail().GetCode(), "0"); + ASSERT_EQ(resp.GetJobsDetail().GetJobId(), "4"); + ASSERT_EQ(resp.GetJobsDetail().GetState(), "14"); + ASSERT_EQ(resp.GetJobsDetail().GetCreationTime(), "1"); + ASSERT_EQ(resp.GetJobsDetail().GetResult(), 40); + ASSERT_EQ(resp.GetJobsDetail().GetLabel(), "41"); + ASSERT_EQ(resp.GetJobsDetail().GetAudioText(), "2"); + ASSERT_TRUE(resp.GetJobsDetail().HasCode()); + ASSERT_TRUE(resp.GetJobsDetail().HasJobId()); + ASSERT_TRUE(resp.GetJobsDetail().HasState()); + ASSERT_TRUE(resp.GetJobsDetail().HasCreationTime()); + ASSERT_TRUE(resp.GetJobsDetail().HasResult()); + ASSERT_TRUE(resp.GetJobsDetail().HasLabel()); + ASSERT_TRUE(resp.GetJobsDetail().HasAudioText()); + ASSERT_TRUE(resp.GetJobsDetail().HasLabel()); + + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetCode(), 3); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetMsg(), "3"); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetCount(), 3); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetHitFlag(), 3); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetScore(), 3); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetSubLabel(), "3"); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetCategory(), "3"); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetKeyWords()[0], "3"); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetOcrResults()[0].GetKeyWords()[0], "6"); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetOcrResults()[0].GetText(), "5"); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetOcrResults()[0].GetLocation().GetX(), 5); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetOcrResults()[0].GetLocation().GetY(), 5); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetOcrResults()[0].GetLocation().GetWidth(), 5); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetOcrResults()[0].GetLocation().GetHeight(), 5); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetOcrResults()[0].GetLocation().GetRotate(), 5); + ASSERT_EQ(resp.GetJobsDetail().GetPornInfo().GetCode(), 3); + + + ASSERT_TRUE(resp.GetJobsDetail().HasPornInfo()); + ASSERT_TRUE(resp.GetJobsDetail().HasAbuseInfo()); + ASSERT_TRUE(resp.GetJobsDetail().HasAdsInfo()); + ASSERT_TRUE(resp.GetJobsDetail().HasIllegalInfo()); + ASSERT_TRUE(resp.GetJobsDetail().HasPoliticsInfo()); + ASSERT_TRUE(resp.GetJobsDetail().HasTerrorismInfo()); + + ASSERT_EQ(resp.GetJobsDetail().getUserInfo().GetTokenId(), "15"); + ASSERT_EQ(resp.GetJobsDetail().getUserInfo().GetNickName(), "15"); + ASSERT_EQ(resp.GetJobsDetail().getUserInfo().GetDeviceId(), "15"); + ASSERT_EQ(resp.GetJobsDetail().getUserInfo().GetAppId(), "15"); + ASSERT_EQ(resp.GetJobsDetail().getUserInfo().GetRoom(), "15"); + ASSERT_EQ(resp.GetJobsDetail().getUserInfo().GetIp(), "15"); + ASSERT_EQ(resp.GetJobsDetail().getUserInfo().GetType(), "15"); + + ASSERT_TRUE(resp.GetJobsDetail().getUserInfo().HasTokenId()); + ASSERT_TRUE(resp.GetJobsDetail().getUserInfo().HasNickName()); + ASSERT_TRUE(resp.GetJobsDetail().getUserInfo().HasDeviceId()); + ASSERT_TRUE(resp.GetJobsDetail().getUserInfo().HasAppId()); + ASSERT_TRUE(resp.GetJobsDetail().getUserInfo().HasRoom()); + ASSERT_TRUE(resp.GetJobsDetail().getUserInfo().HasIp()); + ASSERT_TRUE(resp.GetJobsDetail().getUserInfo().HasType()); + + ASSERT_TRUE(resp.GetJobsDetail().HasUserInfo()); + ASSERT_EQ(resp.GetJobsDetail().GetDataId(), "13"); + ASSERT_EQ(resp.GetJobsDetail().GetUrl(), "15"); + ASSERT_EQ(resp.GetJobsDetail().GetObject(), "15"); + + ASSERT_TRUE(resp.GetJobsDetail().HasDataId()); + ASSERT_TRUE(resp.GetJobsDetail().HasUrl()); + ASSERT_TRUE(resp.GetJobsDetail().HasObject()); + resp.GetJobsDetail().to_string(); + + ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetUrl(),"15"); + ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetDuration(),15); + ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetLabel(),"15"); + ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetOffsetTime(),15); + ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetResult(),15); + ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetText(),"15"); + ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetStartByte(),15); + ASSERT_EQ(resp.GetJobsDetail().GetSection()[0].GetSnapShotTime(),15); + + ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasLabel()); + ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasDuration()); + ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasOffsetTime()); + ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasUrl()); + ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasResult()); + ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasText()); + ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasStartByte()); + ASSERT_TRUE(resp.GetJobsDetail().GetSection()[0].HasSnapShotTime()); + + ASSERT_TRUE(!resp.GetJobsDetail().GetSection()[0].HasAdsInfo()); + ASSERT_TRUE(!resp.GetJobsDetail().GetSection()[0].HasIllegalInfo()); + ASSERT_TRUE(!resp.GetJobsDetail().GetSection()[0].HasPoliticsInfo()); + ASSERT_TRUE(!resp.GetJobsDetail().GetSection()[0].HasTerrorismInfo()); + ASSERT_TRUE(!resp.GetJobsDetail().GetSection()[0].HasPornInfo()); + ASSERT_TRUE(!resp.GetJobsDetail().GetSection()[0].HasAbuseInfo()); + resp.GetJobsDetail().GetSection()[0].to_string(); } }