appium.sh 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  1. #!/bin/bash
  2. types=($TYPES)
  3. echo "Available types: ${types[@]}"
  4. echo "Selected type of deployment: $TYPE, Template file: $TEMPLATE"
  5. function prepare_geny_cloud() {
  6. contents=$(cat $TEMPLATE)
  7. # LogIn
  8. echo "Log In"
  9. gmsaas auth login "${USER}" "${PASS}"
  10. # Start device(s)
  11. created_instances=()
  12. echo "Creating device(s) based on given json file..."
  13. for row in $(echo "${contents}" | jq -r '.[] | @base64'); do
  14. get_value() {
  15. echo ${row} | base64 --decode | jq -r ${1}
  16. }
  17. template=$(get_value '.template')
  18. device=$(get_value '.device')
  19. port=$(get_value '.port')
  20. if [[ $device != null ]]; then
  21. echo "Starting \"$device\" with template name \"$template\"..."
  22. instance_uuid=$(gmsaas instances start "${template}" "${device}")
  23. else
  24. echo "Starting Device with Random name..."
  25. random_device_name=$(python3 -c 'import uuid; print(str(uuid.uuid4()).upper())')
  26. instance_uuid=$(gmsaas instances start "${template}" "${random_device_name}")
  27. fi
  28. echo "Instance-ID: \"$instance_uuid\""
  29. created_instances+=("${instance_uuid}")
  30. if [[ $port != null ]]; then
  31. echo "Connect device on port \"$port\"..."
  32. gmsaas instances adbconnect "${instance_uuid}" --adb-serial-port "${port}"
  33. else
  34. echo "Connect device on port..."
  35. gmsaas instances adbconnect "${instance_uuid}"
  36. fi
  37. done
  38. # Store created instances in a file
  39. echo "All created instances: ${created_instances[@]}"
  40. echo "${created_instances[@]}" > "${INSTANCES_PATH}"
  41. }
  42. function prepare_geny_aws() {
  43. contents=$(cat $TEMPLATE)
  44. # Creating aws tf file(s)
  45. echo "Creating tf file(s)"
  46. index=1
  47. port=5555
  48. for row in $(echo "${contents}" | jq -r '.[] | @base64'); do
  49. get_value() {
  50. echo ${row} | base64 --decode | jq -r ${1}
  51. }
  52. region=$(get_value '.region')
  53. android_version=$(get_value '.android_version')
  54. instance=$(get_value '.instance')
  55. ami=$(get_value '.AMI')
  56. sg=$(get_value '.SG')
  57. subnet_id=$(get_value '.subnet_id')
  58. if [[ $subnet_id == null ]]; then
  59. subnet_id=""
  60. fi
  61. echo $region
  62. echo $android_version
  63. echo $instance
  64. echo $ami
  65. echo $sg
  66. echo $subnet_id
  67. #TODO: remove this dirty hack
  68. if [[ $android_version == null ]]; then
  69. echo "[HACK] Version cannot be empty! version will be added!"
  70. android_version="6.0"
  71. fi
  72. #Custom Security Group
  73. if [[ $sg != null ]]; then
  74. echo "Custom security group is found!"
  75. security_group=""
  76. is_array=$(echo "${sg}" | jq 'if type=="array" then true else false end')
  77. if [ $is_array == "true" ]; then
  78. echo "New security group with given rules will be created"
  79. for i in $(echo "${sg}" | jq -r '.[] | @base64'); do
  80. get_value() {
  81. echo ${i} | base64 --decode | jq -r ${1}
  82. }
  83. type=$(get_value '.type')
  84. configs=$(get_value '.configurations')
  85. for c in $(echo "${configs}" | jq -r '.[] | @base64'); do
  86. get_value() {
  87. echo ${c} | base64 --decode | jq -r ${1}
  88. }
  89. from_port=$(get_value '.from_port')
  90. to_port=$(get_value '.to_port')
  91. protocol=$(get_value '.protocol')
  92. cidr_blocks=$(get_value '.cidr_blocks')
  93. security_group+=$(cat <<_EOF
  94. $type {
  95. from_port = $from_port
  96. to_port = $to_port
  97. protocol = "$protocol"
  98. cidr_blocks = ["$cidr_blocks"]
  99. }
  100. _EOF
  101. )
  102. done
  103. done
  104. else
  105. #TODO: remove this dirty hack
  106. echo "Given security group will be used!"
  107. is_array="false"
  108. security_group=$(cat <<_EOF
  109. ingress {
  110. from_port = 22
  111. to_port = 22
  112. protocol = "tcp"
  113. cidr_blocks = ["0.0.0.0/0"]
  114. }
  115. _EOF
  116. )
  117. fi
  118. else
  119. echo "Custom security is not found! It will use default security group!"
  120. security_group=$(cat <<_EOF
  121. ingress {
  122. from_port = 22
  123. to_port = 22
  124. protocol = "tcp"
  125. cidr_blocks = ["0.0.0.0/0"]
  126. }
  127. ingress {
  128. from_port = 80
  129. to_port = 80
  130. protocol = "tcp"
  131. cidr_blocks = ["0.0.0.0/0"]
  132. }
  133. ingress {
  134. from_port = 443
  135. to_port = 443
  136. protocol = "tcp"
  137. cidr_blocks = ["0.0.0.0/0"]
  138. }
  139. ingress {
  140. from_port = 51000
  141. to_port = 51100
  142. protocol = "tcp"
  143. cidr_blocks = ["0.0.0.0/0"]
  144. }
  145. ingress {
  146. from_port = 51000
  147. to_port = 51100
  148. protocol = "udp"
  149. cidr_blocks = ["0.0.0.0/0"]
  150. }
  151. egress {
  152. from_port = 0
  153. to_port = 65535
  154. protocol = "udp"
  155. cidr_blocks = ["0.0.0.0/0"]
  156. }
  157. _EOF
  158. )
  159. fi
  160. aws_tf_content=$(cat <<_EOF
  161. variable "aws_region_$index" {
  162. type = "string"
  163. default = "$region"
  164. }
  165. variable "android_version_$index" {
  166. type = "string"
  167. default = "$android_version"
  168. }
  169. variable "instance_type_$index" {
  170. type = "string"
  171. default = "$instance"
  172. }
  173. variable "subnet_id_$index" {
  174. type = "string"
  175. default = "$subnet_id"
  176. }
  177. provider "aws" {
  178. alias = "provider_$index"
  179. region = "\${var.aws_region_$index}"
  180. }
  181. resource "aws_security_group" "geny_sg_$index" {
  182. provider = "aws.provider_$index"
  183. $security_group
  184. }
  185. data "aws_ami" "geny_aws_$index" {
  186. provider = "aws.provider_$index"
  187. most_recent = true
  188. filter {
  189. name = "name"
  190. values = ["genymotion-ami-\${var.android_version_$index}-*"]
  191. }
  192. owners = ["679593333241"] #Genymotion
  193. }
  194. resource "aws_key_pair" "geny_key_$index" {
  195. provider = "aws.provider_$index"
  196. public_key = "\${file("~/.ssh/id_rsa.pub")}"
  197. }
  198. resource "aws_instance" "geny_aws_$index" {
  199. provider = "aws.provider_$index"
  200. ami="\${data.aws_ami.geny_aws_$index.id}"
  201. instance_type = "\${var.instance_type_$index}"
  202. subnet_id = "\${var.subnet_id_$index}"
  203. vpc_security_group_ids=["\${aws_security_group.geny_sg_$index.name}"]
  204. key_name = "\${aws_key_pair.geny_key_$index.key_name}"
  205. tags {
  206. Name = "DockerAndroid-\${data.aws_ami.geny_aws_$index.id}"
  207. }
  208. count = 1
  209. provisioner "remote-exec" {
  210. connection {
  211. type = "ssh"
  212. user = "shell"
  213. private_key = "\${file("~/.ssh/id_rsa")}"
  214. }
  215. script = "/root/enable_adb.sh"
  216. }
  217. }
  218. output "public_dns_$index" {
  219. value = "\${aws_instance.geny_aws_$index.public_dns}"
  220. }
  221. _EOF
  222. )
  223. echo "$aws_tf_content" > /root/aws_tf_$index.tf
  224. if [[ $ami != null ]]; then
  225. echo "Using given AMI!"
  226. sed -i "s/.*ami=.*/ ami=\"$ami\"/g" /root/aws_tf_$index.tf
  227. else
  228. echo "Custom AMI is not found. It will use the latest AMI!"
  229. fi
  230. if [[ $sg != null ]] && [[ $is_array == "false" ]]; then
  231. echo "Using given security group: $sg"
  232. sed -i "s/.*vpc_security_group_ids=.*/ vpc_security_group_ids=[\"$sg\"]/g" /root/aws_tf_$index.tf
  233. fi
  234. echo "---------------------------------------------------------"
  235. ((index++))
  236. ((port++))
  237. done
  238. # Deploy EC2 instance(s)
  239. echo "Deploy EC2 instance(s) on AWS with Genymotion image based on given json file..."
  240. ./terraform init
  241. ./terraform plan
  242. ./terraform apply -auto-approve
  243. # Workaround to connect adb remotely because there is a issue by using local-exec
  244. time_sleep=5
  245. interval_sleep=1
  246. echo "Connect to adb remotely"
  247. for ((i=index;i>=1;i--)); do
  248. dns=$(./terraform output public_dns_$i)
  249. ((sleep ${interval_sleep} && adb connect localhost:${port}) > /dev/null & ssh -i ~/.ssh/id_rsa -o ServerAliveInterval=60 -o StrictHostKeyChecking=no -q -NL ${port}:localhost:5555 shell@${dns}) &
  250. ((port--))
  251. time_sleep=$((time_sleep+interval_sleep))
  252. done
  253. echo "It will wait for ${time_sleep} until all device(s) to be connected"
  254. sleep ${time_sleep}
  255. adb devices
  256. echo "Process is completed"
  257. }
  258. function run_appium() {
  259. echo "Preparing appium-server..."
  260. CMD="appium --log $APPIUM_LOG"
  261. if [ "$CONNECT_TO_GRID" = true ]; then
  262. NODE_CONFIG_JSON="/root/src/nodeconfig.json"
  263. /root/generate_config.sh $NODE_CONFIG_JSON
  264. CMD+=" --nodeconfig $NODE_CONFIG_JSON"
  265. fi
  266. if [ "$RELAXED_SECURITY" = true ]; then
  267. CMD+=" --relaxed-security"
  268. fi
  269. echo "Preparation is done"
  270. TERM="xterm -T AppiumServer -n AppiumServer -e $CMD"
  271. $TERM
  272. }
  273. function ga(){
  274. if [ "$GA" = true ]; then
  275. echo "Collecting data for improving the project"
  276. description="PROCESSOR: ${SYS_IMG}; VERSION: ${ANDROID_VERSION}; DEVICE: ${DEVICE}; APPIUM: ${APPIUM}; SELENIUM: ${CONNECT_TO_GRID}; MOBILE_TEST: ${MOBILE_WEB_TEST}"
  277. random_user=$(cat /proc/version 2>&1 | sed -e 's/ /_/g' | sed -e 's/[()]//g' | sed -e 's/@.*_gcc_version/_gcc/g' | sed -e 's/__/_/g' | sed -e 's/Linux_version_//g' | sed -e 's/generic_build/genb/g')
  278. random_user="${APP_RELEASE_VERSION}_${random_user}"
  279. payload=(
  280. --data v=${GA_API_VERSION}
  281. --data aip=1
  282. --data tid="${GA_TRACKING_ID}"
  283. --data cid="${random_user}"
  284. --data t="event"
  285. --data ec="${APP_TYPE}"
  286. --data ea="${random_user}"
  287. --data el="${description}"
  288. --data an="docker-android"
  289. --data av="${APP_RELEASE_VERSION}"
  290. )
  291. curl ${GA_ENDPOINT} "${payload[@]}" --silent
  292. else
  293. echo "Nothing to do"
  294. fi
  295. }
  296. function saltstack(){
  297. if [ ! -z "${SALT_MASTER}" ]; then
  298. echo "ENV SALT_MASTER it not empty, salt-minion will be prepared"
  299. echo "master: ${SALT_MASTER}" >> /etc/salt/minion
  300. salt-minion &
  301. echo "salt-minion is running..."
  302. else
  303. echo "SaltStack is disabled"
  304. fi
  305. }
  306. ga
  307. saltstack
  308. if [ "$REAL_DEVICE" = true ]; then
  309. echo "Using real device"
  310. run_appium
  311. elif [ "$GENYMOTION" = true ]; then
  312. echo "Using Genymotion"
  313. echo "${types[@]}"
  314. case $TYPE in
  315. "${types[0]}" )
  316. echo "Using Genymotion-Cloud (SaaS)"
  317. prepare_geny_cloud
  318. run_appium
  319. ;;
  320. "${types[1]}" )
  321. echo "Using Genymotion-AWS"
  322. prepare_geny_aws
  323. run_appium
  324. ;;
  325. esac
  326. else
  327. echo "Using Emulator"
  328. python3 -m src.app
  329. fi