mypy [subprocess.Popen] `Item "None" of "Optional[IO[bytes]]" has no attribute "close"` - popen

mypy generates following warning Item "None" of "Optional[IO[bytes]]" has no attribute "close" for the p1.stdout.close()line. How can I fix this error?
#!/usr/bin/env python3
filename = "filename.py"
p1 = subprocess.Popen(["ls", "-ln", filename,], stdout=subprocess.PIPE,)
p2 = subprocess.Popen(["awk", "{print $1}"], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close() # <== `Item "None" of "Optional[IO[bytes]]" has no
# attribute "close"`
close() is an abstractmethod() method in the typing.py file
#abstractmethod
def close(self) -> None:
pass

Related

How can I use Chinese in Alpine headless chrome?

I am using headless chrome based on alpine:3.7 image under docker. However, when I take a screenshot using Chrome DevTools Protocol, I found alpine cannot show languages other than English like the screenshot below.
I have tried to copy font to docker image
COPY NotoSansCJKsc-Regular.otf /usr/share/fonts/
and tried to install font in alpine source:
RUN apk add --no-cache bash \
ttf-ubuntu-font-family \
font-adobe-100dpi \
font-noto \
ttf-dejavu \
But all methods failed. So my question is is Alpine support Chinese? And How can I use it using Docker?
python code to take the screenshot:
import threading
import pychrome
import time
import base64
class EventHandler(object):
screen_lock = threading.Lock()
def __init__(self, browser, tab):
self.browser = browser
self.tab = tab
self.start_frame = None
self.html_content = None
self.is_first_request = True
def frame_start_loading(self, frameId):
if not self.start_frame:
self.start_frame = frameId
def request_intercepted(self, interceptionId, request, **kwargs):
if self.is_first_request:
self.is_first_request = False
headers = request.get('headers', {})
self.tab.Network.continueInterceptedRequest(
interceptionId=interceptionId,
headers=headers,
method='POST',
postData="hello post data: %s" % time.time()
)
else:
self.tab.Network.continueInterceptedRequest(
interceptionId=interceptionId
)
def frame_stop_loading(self, frameId):
if self.start_frame == frameId:
self.tab.Page.stopLoading()
result = self.tab.Runtime.evaluate(expression="document.documentElement.outerHTML")
self.html_content = result.get('result', {}).get('value', "")
print self.html_content
self.tab.stop()
def close_all_tabs(browser):
if len(browser.list_tab()) == 0:
return
for tab in browser.list_tab():
try:
tab.stop()
except pychrome.RuntimeException:
pass
browser.close_tab(tab)
assert len(browser.list_tab()) == 0
if __name__ == '__main__':
# create a browser instance
browser = pychrome.Browser(url="http://127.0.0.1:9222")
print browser.version()
# create a tab
tab = browser.new_tab()
# register callback
def request_will_be_sent(**kwargs):
print("[start] start loading: %s" % kwargs.get('request').get('url'))
tab.set_listener("Network.requestWillBeSent", request_will_be_sent)
def received_callback(**kwargs):
print "[received] response type %s" % kwargs.get('type', '')
resp = kwargs.get('response', {})
resp_status = resp.get('status', '')
resp_headers = resp.get('headersText')
print "response status %s %s" % (resp_status, resp_headers)
tab.set_listener("Network.responseReceived", received_callback)
def frame_stop_loading():
print "frame stop loading"
tab.set_listener("Page.frameStoppedLoading", frame_stop_loading)
def loading_finished(**kwargs):
print "[loading finished]"
# when HTTP request has finished loading
tab.set_listener("Network.loadingFinished", loading_finished)
# start the tab
tab.start()
net = tab.call_method("Network.enable")
navi = tab.call_method("Page.navigate", url="https://www.douban.com", _timeout=5)
tab.wait(5)
screen_data = tab.call_method("Page.captureScreenshot")
image_data = screen_data.get('data', '')
with open("image.png", "wb") as file:
file.write(image_data.decode('base64'))
html = tab.Runtime.evaluate(expression="document.documentElement.outerHTML")
print html['result']['value']
all_cookies = tab.Network.getAllCookies()
print all_cookies
tab.stop()
browser.close_tab(tab)
Install wqy-zenhei package at testing channel will fix it.
echo #edge http://nl.alpinelinux.org/alpine/edge/testing >> /etc/apk/repositories && apk add wqy-zenhei#edge

Groovy Variable $ Dollar Sign in JSON

I've got a JSON file that I am slurping with groovy.
{
"team": "${GLOBAL_TEAM_NAME}",
"jobs": [
{
In the JSON above is a property 'team' that contains a groovy-like variable I want to be resolved at runtime.
teamList.each { tl ->
try
{
def teamSlurper = new JsonSlurperClassic()
def t = teamSlurper.parseText(tl.text)
println "*********************"
println "PROVISIONING JOB FOR: " + t.team
Output:
PROVISIONING JOB FOR: ${GLOBAL_TEAM_NAME}
The above outputs the raw value, but I would like it to resolve the global variable that has been defined for the system.
How can I resolve ${GLOBAL_TEAM_NAME} to its actual system value?
You can do this with Groovy Templates.
def slurper = new groovy.json.JsonSlurperClassic()
def engine = new groovy.text.SimpleTemplateEngine()
def binding = ["GLOBAL_TEAM_NAME": "Avengers"]
def json = '{"team":"${GLOBAL_TEAM_NAME}"}'
def t = slurper.parseText(engine.createTemplate(json).make(binding).toString())
t.team // "Avengers"

Can groovy string interpolation be nested?

I'm trying to add parameter in Jenkins groovy shell script, then wonder if groovy string interpolation can be used nested way like this.
node{
def A = 'C'
def B = 'D'
def CD = 'Value what I want'
sh "echo ${${A}${B}}"
}
Then what I expected is like this;
'Value what I want'
as if I do;
sh "echo ${CD}"
But it gives some error that $ is not found among steps [...]
Is it not possible?
Like this?
import groovy.text.GStringTemplateEngine
// processes a string in "GString" format against the bindings
def postProcess(str, Map bindings) {
new GStringTemplateEngine().createTemplate(str).make(bindings).toString()
}
node{
def A = 'C'
def B = 'D'
def bindings = [
CD: 'Value what I want'
]
// so this builds the "template" echo ${CD}
def template = "echo \${${"${A}${B}"}}"​
// post-process to get: echo Value what I want
def command = postProcess(template, bindings)
sh command
}
In regard to the accepted answer, if you're putting values in a map anyway then you can just interpolate your [key]:
def A = 'C'
def B = 'D'
def bindings = [ CD: 'Value what I want' ]
bindings["${A}${B}"] == 'Value what I want'
${A}${B} is not a correct groovy syntax.
The interpolation just insert the value of expression between ${}.
Even if you change to the correct syntax and create $ method, the result will not be what you want.
def nested = "${${A}+${B}}"
println nested
static $(Closure closure) { //define $ method
closure.call()
}
CD will be printed.

Parsing complex operands in boolean expressions in Python 2.7

I am trying to modify the example code in pyparsing to handle operands that are key value pairs, like:
(Region:US and Region:EU) or (Region:Asia)
This is a boolean expression with three operands - Region:US, Region:EU and Region:Asia. If they were simple operands like x, y and z, I'd be good to go. I don't need to do any special processing on them to break up the key-value pairs. I need to treat the operand in its entirety as though it might have just been x, and need to assign truth values to it and evaluate the full expression.
How might I modify the following code to handle this:
#
# simpleBool.py
#
# Example of defining a boolean logic parser using
# the operatorGrammar helper method in pyparsing.
#
# In this example, parse actions associated with each
# operator expression will "compile" the expression
# into BoolXXX class instances, which can then
# later be evaluated for their boolean value.
#
# Copyright 2006, by Paul McGuire
# Updated 2013-Sep-14 - improved Python 2/3 cross-compatibility
#
from pyparsing import infixNotation, opAssoc, Keyword, Word, alphas
# define classes to be built at parse time, as each matching
# expression type is parsed
class BoolOperand(object):
def __init__(self,t):
self.label = t[0]
self.value = eval(t[0])
def __bool__(self):
return self.value
def __str__(self):
return self.label
__repr__ = __str__
__nonzero__ = __bool__
class BoolBinOp(object):
def __init__(self,t):
self.args = t[0][0::2]
def __str__(self):
sep = " %s " % self.reprsymbol
return "(" + sep.join(map(str,self.args)) + ")"
def __bool__(self):
return self.evalop(bool(a) for a in self.args)
__nonzero__ = __bool__
__repr__ = __str__
class BoolAnd(BoolBinOp):
reprsymbol = '&'
evalop = all
class BoolOr(BoolBinOp):
reprsymbol = '|'
evalop = any
class BoolNot(object):
def __init__(self,t):
self.arg = t[0][1]
def __bool__(self):
v = bool(self.arg)
return not v
def __str__(self):
return "~" + str(self.arg)
__repr__ = __str__
__nonzero__ = __bool__
TRUE = Keyword("True")
FALSE = Keyword("False")
boolOperand = TRUE | FALSE | Word(alphas,max=1)
boolOperand.setParseAction(BoolOperand)
# define expression, based on expression operand and
# list of operations in precedence order
boolExpr = infixNotation( boolOperand,
[
("not", 1, opAssoc.RIGHT, BoolNot),
("and", 2, opAssoc.LEFT, BoolAnd),
("or", 2, opAssoc.LEFT, BoolOr),
])
if __name__ == "__main__":
p = True
q = False
r = True
tests = [("p", True),
("q", False),
("p and q", False),
("p and not q", True),
("not not p", True),
("not(p and q)", True),
("q or not p and r", False),
("q or not p or not r", False),
("q or not (p and r)", False),
("p or q or r", True),
("p or q or r and False", True),
("(p or q or r) and False", False),
]
print("p =", p)
print("q =", q)
print("r =", r)
print()
for t,expected in tests:
res = boolExpr.parseString(t)[0]
success = "PASS" if bool(res) == expected else "FAIL"
print (t,'\n', res, '=', bool(res),'\n', success, '\n')
Instead of p, q, r, I'd like to use "Region:US", "Region:EU" and "Region:Asia." Any ideas?
EDIT: Using Paul McGuire's suggestion, I tried writing the following code which breaks on parsing:
#
# simpleBool.py
#
# Example of defining a boolean logic parser using
# the operatorGrammar helper method in pyparsing.
#
# In this example, parse actions associated with each
# operator expression will "compile" the expression
# into BoolXXX class instances, which can then
# later be evaluated for their boolean value.
#
# Copyright 2006, by Paul McGuire
# Updated 2013-Sep-14 - improved Python 2/3 cross-compatibility
#
from pyparsing import infixNotation, opAssoc, Keyword, Word, alphas
# define classes to be built at parse time, as each matching
# expression type is parsed
class BoolOperand(object):
def __init__(self,t):
self.label = t[0]
self.value = validValues[t[0]]
def __bool__(self):
return self.value
def __str__(self):
return self.label
__repr__ = __str__
__nonzero__ = __bool__
class BoolBinOp(object):
def __init__(self,t):
self.args = t[0][0::2]
def __str__(self):
sep = " %s " % self.reprsymbol
return "(" + sep.join(map(str,self.args)) + ")"
def __bool__(self):
return self.evalop(bool(a) for a in self.args)
__nonzero__ = __bool__
__repr__ = __str__
class BoolAnd(BoolBinOp):
reprsymbol = '&'
evalop = all
class BoolOr(BoolBinOp):
reprsymbol = '|'
evalop = any
class BoolNot(object):
def __init__(self,t):
self.arg = t[0][1]
def __bool__(self):
v = bool(self.arg)
return not v
def __str__(self):
return "~" + str(self.arg)
__repr__ = __str__
__nonzero__ = __bool__
TRUE = Keyword("True")
FALSE = Keyword("False")
boolOperand = TRUE | FALSE | Word(alphas+":",max=1)
boolOperand.setParseAction(BoolOperand)
# define expression, based on expression operand and
# list of operations in precedence order
boolExpr = infixNotation( boolOperand,
[
("not", 1, opAssoc.RIGHT, BoolNot),
("and", 2, opAssoc.LEFT, BoolAnd),
("or", 2, opAssoc.LEFT, BoolOr),
])
if __name__ == "__main__":
validValues = {
"Region:US": False,
"Region:EU": True,
"Type:Global Assets>24": True
}
tests = [("Region:US", True),
("Region:EU", False),
("Region:US and Region:EU", False),
("Region:US and not Region:EU", True),
("not not Region:US", True),
("not(Region:US and Region:EU)", True),
("Region:EU or not Region:US and Type:Global Assets>24", False),
("Region:EU or not Region:US or not Type:Global Assets>24", False),
("Region:EU or not (Region:US and Type:Global Assets>24)", False),
("Region:US or Region:EU or Type:Global Assets>24", True),
("Region:US or Region:EU or Type:Global Assets>24 and False", True),
("(Region:US or Region:EU or Type:Global Assets>24) and False", False),
]
print("Region:US =", validValues["Region:US"])
print("Region:EU =", validValues["Region:EU"])
print("Type:Global Assets>24 =", validValues["Type:Global Assets>24"])
print()
for t,expected in tests:
res = boolExpr.parseString(t)[0]
success = "PASS" if bool(res) == expected else "FAIL"
print (t,'\n', res, '=', bool(res),'\n', success, '\n')
Thanks to Paul McGuire's help, here is the solution:
boolOperand = TRUE | FALSE | Combine(Word(alphas)+":"+quotedString) | Word(alphas+":<>")
This does the parsing as I wanted it.
There are two parts to making this change: changing the parser, and then changing the post-parsing behavior to accommodate these new values.
To parse operands that are not just simple 1-character names, change this line in the parser:
boolOperand = TRUE | FALSE | Word(alphas,max=1)
The simplest (but not strictest would be to just change it to:
boolOperand = TRUE | FALSE | Word(alphas+":")
But this would accept, in addition to your valid values of "Region:US" or "TimeZone:UTC", presumably invalid values like "XouEWRL:sdlkfj", ":sldjf:ljsdf:sdljf", and even ":::::::". If you want to tighten up the parser, you could enforce the key entry to:
valid_key = oneOf("Region Country City State ZIP")
valid_value = Word(alphas+"_")
valid_kv = Combine(valid_key + ":" + valid_value)
boolOperand = TRUE | FALSE | valid_kv
That should take care of the parser.
Second, you will need to change how this entry is evaluated after the parsing is done. In my example, I was emphasizing the parsing part, not the evaluating part, so I left this to simply call the eval() builtin. In your case, you will probably need to initialize a dict of valid values for each acceptable key-value pair, and then change the code in BoolOperand to do a dict lookup instead of calling eval. (This has the added benefit of not calling eval() with user-entered data, which has all kinds of potential for security problems.)

How can I turn the output of my iOS UIAutomation tests into JUnit style output for Jenkins?

I am using UIAutomation scripts to test my iOS application. I've managed to get the scripts running from the command line but now I need to convert the output (pass/fails) in a format that Jenkins can understand, ideally JUnit style.
Has anyone written any scripts to do this before I try & write one?
Many thanks
Maybe you can have a look at : https://github.com/shaune/jasmine-ios-acceptance-tests
Edit :
I've also avoided to use jasmine. To 'listen' start, pass and fail test, I've simply replaced UIALogger.logStart, UIALogger.logFail and UIALogger.logPass :
(function () {
// An anonymous function wrapper helps you keep oldSomeFunction private
var oldSomeFunction = UIALogger.logStart;
UIALogger.logStart = function () {
//UIALogger.logDebug("intercepted a logStart : " + arguments);
OKJunitLogger.reportTestSuiteStarting(arguments[0]);
oldSomeFunction.apply(this, arguments);
}
})();
I bealive you will find what you need here:
https://github.com/shinetech/jenkins-ios-example
What you're interest in is the script call "ocunit2junit.rb"
I used it for a project, it work very well.
#!/usr/bin/ruby
#
# ocunit2junit.rb was written by Christian Hedin <christian.hedin#jayway.com>
# Version: 0.1 - 30/01 2010
# Usage:
# xcodebuild -yoursettings | ocunit2junit.rb
# All output is just passed through to stdout so you don't miss a thing!
# JUnit style XML-report are put in the folder specified below.
#
# Known problems:
# * "Errors" are not cought, only "warnings".
# * It's not possible to click links to failed test in Hudson
# * It's not possible to browse the source code in Hudson
#
# Acknowledgement:
# Big thanks to Steen Lehmann for prettifying this script.
################################################################
# Edit these variables to match your system
#
#
# Where to put the XML-files from your unit tests
TEST_REPORTS_FOLDER = "test-reports"
#
#
# Don't edit below this line
################################################################
require 'time'
require 'FileUtils'
require 'socket'
class ReportParser
attr_reader :exit_code
def initialize(piped_input)
#piped_input = piped_input
#exit_code = 0
FileUtils.rm_rf(TEST_REPORTS_FOLDER)
FileUtils.mkdir(TEST_REPORTS_FOLDER)
parse_input
end
private
def parse_input
#piped_input.each do |piped_row|
puts piped_row
case piped_row
when /Test Suite '(\S+)'.*started at\s+(.*)/
t = Time.parse($2.to_s)
handle_start_test_suite(t)
when /Test Suite '(\S+)'.*finished at\s+(.*)./
t = Time.parse($2.to_s)
handle_end_test_suite($1,t)
when /Test Case '-\[\S+\s+(\S+)\]' started./
test_case = $1
when /Test Case '-\[\S+\s+(\S+)\]' passed \((.*) seconds\)/
test_case = $1
test_case_duration = $2.to_f
handle_test_passed(test_case,test_case_duration)
when /(.*): error: -\[(\S+) (\S+)\] : (.*)/
error_location = $1
test_suite = $2
test_case = $3
error_message = $4
handle_test_error(test_suite,test_case,error_message,error_location)
when /Test Case '-\[\S+ (\S+)\]' failed \((\S+) seconds\)/
test_case = $1
test_case_duration = $2.to_f
handle_test_failed(test_case,test_case_duration)
when /failed with exit code (\d+)/
#exit_code = $1.to_i
when
/BUILD FAILED/
#exit_code = -1;
end
end
end
def handle_start_test_suite(start_time)
#total_failed_test_cases = 0
#total_passed_test_cases = 0
#tests_results = Hash.new # test_case -> duration
#errors = Hash.new # test_case -> error_msg
#ended_current_test_suite = false
#cur_start_time = start_time
end
def handle_end_test_suite(test_name,end_time)
unless #ended_current_test_suite
current_file = File.open("#{TEST_REPORTS_FOLDER}/TEST-#{test_name}.xml", 'w')
host_name = string_to_xml Socket.gethostname
test_name = string_to_xml test_name
test_duration = (end_time - #cur_start_time).to_s
total_tests = #total_failed_test_cases + #total_passed_test_cases
suite_info = '<testsuite errors="0" failures="'+#total_failed_test_cases.to_s+'" hostname="'+host_name+'" name="'+test_name+'" tests="'+total_tests.to_s+'" time="'+test_duration.to_s+'" timestamp="'+end_time.to_s+'">'
current_file << "<?xml version='1.0' encoding='UTF-8' ?>\n"
current_file << suite_info
#tests_results.each do |t|
test_case = string_to_xml t[0]
duration = #tests_results[test_case]
current_file << "<testcase classname='#{test_name}' name='#{test_case}' time='#{duration.to_s}'"
unless #errors[test_case].nil?
# uh oh we got a failure
puts "tests_errors[0]"
puts #errors[test_case][0]
puts "tests_errors[1]"
puts #errors[test_case][1]
message = string_to_xml #errors[test_case][0].to_s
location = string_to_xml #errors[test_case][1].to_s
current_file << ">\n"
current_file << "<failure message='#{message}' type='Failure'>#{location}</failure>\n"
current_file << "</testcase>\n"
else
current_file << " />\n"
end
end
current_file << "</testsuite>\n"
current_file.close
#ended_current_test_suite = true
end
end
def string_to_xml(s)
s.gsub(/&/, '&').gsub(/'/, '"').gsub(/</, '<')
end
def handle_test_passed(test_case,test_case_duration)
#total_passed_test_cases += 1
#tests_results[test_case] = test_case_duration
end
def handle_test_error(test_suite,test_case,error_message,error_location)
# error_message.tr!('<','').tr!('>','')
#errors[test_case] = [ error_message, error_location ]
end
def handle_test_failed(test_case,test_case_duration)
#total_failed_test_cases +=1
#tests_results[test_case] = test_case_duration
end
end
#Main
#piped_input = File.open("tests_fail.txt") # for debugging this script
piped_input = ARGF.read
report = ReportParser.new(piped_input)
exit report.exit_code
Maybe you can use this.
And in Jenkins execute shell:
sh setup.sh sh runTests.sh ./sample/alltests.js "/Users/komejun/Library/Application Support/iPhone Simulator/5.0/Applications/1622F505-8C07-47E0-B0F0-3A125A88B329/Recipes.app/"
And the report will be auto-created in ./ynmsk-report/test.xml
You can use the tuneupjs library. The library provides test runner that generates a xml report (jUnit style). It works with Xcode 6. For the xml report just provide -x param. Check it here: http://www.tuneupjs.org/running.html

Resources