通过 AWS SDK for Go 在 Device Farm 中上传的 Android 应用程序从未从 INITIALIZED 更改状态

Posted

技术标签:

【中文标题】通过 AWS SDK for Go 在 Device Farm 中上传的 Android 应用程序从未从 INITIALIZED 更改状态【英文标题】:Android app uploaded in Device Farm via AWS SDK for Go never changed status from INITIALIZED 【发布时间】:2016-04-21 04:46:48 【问题描述】:

我正在尝试使用 AWS SDK for Go 在 AWS Device Farm 中自动运行应用程序。但是任何使用 Go 版本 SDK 上传的应用程序都不会从“INITIALIZED”更改状态。如果我通过 AWS 控制台 Web UI 上传它们,那么一切都会好起来的。

上传代码示例: func uploadApp(client *devicefarm.DeviceFarm, appType, projectArn string) string params := &devicefarm.CreateUploadInput Name: aws.String(*appName), ProjectArn: aws.String(projectArn), Type: aws.String(appType), resp, err := client.CreateUpload(params) if err != nil log.Fatal("Failed to upload an app because of: ", err.Error()) log.Println("Upload ARN:", *resp.Upload.Arn) return *resp.Upload.Arn 作为回应,我得到了类似的信息: Upload: Arn: "arn:aws:devicefarm:us-west-2:091463382595:upload:c632e325-266b-4bda-a74d-0acec1e2a5ae/9fbbf140-e377-4de9-b7df-dd18a21b2bca", Created: 2016-01-15 14:27:31 +0000 UTC, Name: "app-debug-unaligned.apk", Status: "INITIALIZED", Type: "android_APP", Url: "bla-bla-bla" 随着时间的推移,状态永远不会从“INITIALIZED”改变。正如我所提到的,从 UI 调度运行的应用运行良好。

如何找出原因?

========================================

解决方案:

1) 在CreateUpload 之后,它需要在响应中使用预签名的 S3 链接上传文件 2) 上传应通过 HTTP PUT 请求通过接收到的 URL 执行,文件内容在正文中 3) 在&devicefarm.CreateUploadInput 中应指定ContentType参数。对于 PUT 请求,应使用 Content-Type 标头的相同值 4) 如果 PUT 请求将从 Go 代码发送,则应手动设置 Content-Length 标头

【问题讨论】:

能否提供解决方案代码 类似的东西:gist.github.com/artemnikitin/d8caa2862c0b7762064f5fec39804f91 【参考方案1】:

当您调用 CreateUpload API 时,Device Farm 将返回包含“Url”字段的“Upload”响应。

Upload: Arn: "arn:aws:devicefarm:us-west-2:....", Created: 2016-01-15 14:27:31 +0000 UTC, Name: "app-name.apk", Status: "INITIALIZED", Type: "ANDROID_APP", Url: "bla-bla-bla"

返回的 url,“bla-bla-bla”,是一个预签名的 S3 url,供您上传应用程序。关于使用预签名 url 上传对象的文档:http://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObject.html

您的申请上传后,将处理该应用。您的上传状态将更改为“正在处理”和“成功”(如果出现问题,则为“失败”)。一旦它处于“SUCCEEDED”状态,您就可以使用它来安排运行。

【讨论】:

感谢您的回答。真的不清楚,我需要使用预签名的 URL。但它仍然对我不起作用。根据您的链接,我应该发送一个简单的 HTTP PUT 请求,其中包含正文中的文件。我这样做了,作为回应,我得到了 HTTP 403 错误 <Code>SignatureDoesNotMatch</Code> <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message> 如果在&devicefarm.CreateUploadInput中指定ContentType: aws.String("application/octet-stream")并在之后的PUT请求中设置相同的header,则错误会有所不同:HTTP 501 <Code>NotImplemented</Code><Message>A header you provided implies functionality that is not implemented</Message><Header>Transfer-Encoding</Header> 我想通了。如此处所述:github.com/aws/aws-sdk-go/issues/467。它需要手动设置 Content-Length 值。毕竟一切正常。

以上是关于通过 AWS SDK for Go 在 Device Farm 中上传的 Android 应用程序从未从 INITIALIZED 更改状态的主要内容,如果未能解决你的问题,请参考以下文章

golang Amazon S3使用AWS SDK for Go选择带有JSON的示例

AWS CloudTrail Create API for Go SDK 引发错误消息“InsufficientS3BucketPolicyException:检测到存储桶的 S3 存储桶策略不正确:

构建aws-sdk-go的依赖关系在Go版本1.13上失败

使用go在dynamodb中创建项目

golang aws-sdk-go 之 s3 服务

如何强制删除 S3 存储桶中的所有对象版本,然后最终使用 aws-sdk-go 删除整个存储桶?