Improve autotest system

This commit is contained in:
Jérôme Petazzoni
2017-10-25 17:49:30 +02:00
parent 68e0c8fca7
commit 40eab78186
8 changed files with 85 additions and 92 deletions

View File

@@ -1,14 +1,21 @@
#!/usr/bin/env python
import logging
import os
import re
import subprocess
import sys
def print_snippet(snippet):
print(78*'-')
print(snippet)
print(78*'-')
logging.basicConfig(level=logging.DEBUG)
def hrule():
return "="*int(os.environ.get("COLUMNS", "80"))
# A "snippet" is something that the user is supposed to do in the workshop.
# Most of the "snippets" are shell commands.
# Some of them can be key strokes or other actions.
# In the markdown source, they are the code sections (identified by triple-
# quotes) within .exercise[] sections.
class Snippet(object):
@@ -28,26 +35,22 @@ class Slide(object):
def __init__(self, content):
Slide.current_slide += 1
self.number = Slide.current_slide
# Remove commented-out slides
# (remark.js considers ??? to be the separator for speaker notes)
content = re.split("\n\?\?\?\n", content)[0]
self.content = content
self.snippets = []
exercises = re.findall("\.exercise\[(.*)\]", content, re.DOTALL)
for exercise in exercises:
if "```" in exercise and "<br/>`" in exercise:
print("! Exercise on slide {} has both ``` and <br/>` delimiters, skipping."
.format(self.number))
print_snippet(exercise)
elif "```" in exercise:
if "```" in exercise:
for snippet in exercise.split("```")[1::2]:
self.snippets.append(Snippet(self, snippet))
elif "<br/>`" in exercise:
for snippet in re.findall("<br/>`(.*)`", exercise):
self.snippets.append(Snippet(self, snippet))
else:
print(" Exercise on slide {} has neither ``` or <br/>` delimiters, skipping."
.format(self.number))
logging.warning("Exercise on slide {} does not have any ``` snippet."
.format(self.number))
self.debug()
def __str__(self):
text = self.content
@@ -55,6 +58,9 @@ class Slide(object):
text = text.replace(snippet.content, ansi("7")(snippet.content))
return text
def debug(self):
logging.debug("\n{}\n{}\n{}".format(hrule(), self.content, hrule()))
def ansi(code):
return lambda s: "\x1b[{}m{}\x1b[0m".format(code, s)
@@ -64,96 +70,51 @@ content = open(sys.argv[1]).read()
for slide in re.split("\n---?\n", content):
slides.append(Slide(slide))
is_editing_file = False
placeholders = {}
actions = []
for slide in slides:
for snippet in slide.snippets:
content = snippet.content
# Multi-line snippets should be ```highlightsyntax...
# Single-line snippets will be interpreted as shell commands
# Extract the "method" (e.g. bash, keys, ...)
# On multi-line snippets, the method is alone on the first line
# On single-line snippets, the data follows the method immediately
if '\n' in content:
highlight, content = content.split('\n', 1)
method, data = content.split('\n', 1)
else:
highlight = "bash"
content = content.strip()
# If the previous snippet was a file fragment, and the current
# snippet is not YAML or EDIT, complain.
if is_editing_file and highlight not in ["yaml", "edit"]:
print("! On slide {}, previous snippet was YAML, so what do what do?"
.format(slide.number))
print_snippet(content)
is_editing_file = False
if highlight == "yaml":
is_editing_file = True
elif highlight == "placeholder":
for line in content.split('\n'):
variable, value = line.split(' ', 1)
placeholders[variable] = value
elif highlight == "bash":
for variable, value in placeholders.items():
quoted = "`{}`".format(variable)
if quoted in content:
content = content.replace(quoted, value)
del placeholders[variable]
if '`' in content:
print("! The following snippet on slide {} contains a backtick:"
.format(slide.number))
print_snippet(content)
continue
print("_ "+content)
snippet.actions.append((highlight, content))
elif highlight == "edit":
print(". "+content)
snippet.actions.append((highlight, content))
elif highlight == "meta":
print("^ "+content)
snippet.actions.append((highlight, content))
elif highlight == "keys":
print("K "+content)
snippet.actions.append((highlight, content))
else:
print("! Unknown highlight {!r} on slide {}.".format(highlight, slide.number))
if placeholders:
print("! Remaining placeholder values: {}".format(placeholders))
method, data = content.split(' ', 1)
actions.append((slide, snippet, method, data))
actions = sum([snippet.actions for snippet in sum([slide.snippets for slide in slides], [])], [])
# Strip ^{ ... ^} for now
def strip_curly_braces(actions, in_braces=False):
if actions == []:
return []
elif actions[0] == ("meta", "^{"):
return strip_curly_braces(actions[1:], True)
elif actions[0] == ("meta", "^}"):
return strip_curly_braces(actions[1:], False)
elif in_braces:
return strip_curly_braces(actions[1:], True)
else:
return [actions[0]] + strip_curly_braces(actions[1:], False)
actions = strip_curly_braces(actions)
try:
i = int(open("nextstep").read())
logging.info("Loaded next step ({}) from file.".format(i))
except Exception as e:
print("Could not read nextstep file ({}), initializing to 0.".format(e))
logging.warning("Could not read nextstep file ({}), initializing to 0.".format(e))
i = 0
keymaps = { "^C": "\x03" }
while True:
with open("nextstep","w") as f:
f.write(str(i))
typ, cmd = actions[i]
print_snippet(cmd)
print("i={} shall we execute the snippet above with {}?".format(i, typ))
slide, snippet, method, data = actions[i]
data = data.strip()
print(hrule())
print(slide.content.replace(snippet.content, ansi(7)(snippet.content)))
print(hrule())
print("[{}] Shall we execute that snippet above?".format(i))
command = raw_input()
if command == "":
if typ in ["bash", "keys"]:
if typ=="keys" and cmd=="^C":
print("^C detected")
cmd="\x03"
subprocess.check_call(["tmux", "send-keys", "{}\n".format(cmd)])
if method=="keys" and data in keymaps:
print("Mapping {!r} to {!r}.".format(data, keymaps[data]))
data = keymaps[data]
if method in ["bash", "keys"]:
data = re.sub("\n +", "\n", data)
if method == "bash":
data += "\n"
subprocess.check_call(["tmux", "send-keys", "{}".format(data)])
else:
print "DO NOT KNOW HOW TO HANDLE", typ, cmd
print "DO NOT KNOW HOW TO HANDLE {} {!r}".format(method, data)
i += 1
elif command.isdigit():
i = int(command)

View File

@@ -91,6 +91,8 @@ The goo.gl URL expands to:
(You will have to work around the TLS certificate validation warning)
<!-- ```open https://node1:3xxxx/``` -->
]
- We have three authentication options at this point:

View File

@@ -69,6 +69,8 @@ The `LoadBalancer` type is currently only available on AWS, Azure, and GCE.
kubectl get pods -w
```
<!-- ```keys ^C``` -->
]
The `-w` option "watches" events happening on the specified resources.

View File

@@ -10,6 +10,8 @@
kubectl get deployments -w
```
<!-- ```keys ^C``` -->
- Now, create more `worker` replicas:
```bash
kubectl scale deploy/worker --replicas=10

View File

@@ -348,6 +348,8 @@ We should now see the `worker`, well, working happily.
- Open the web UI in your browser (http://node-ip-address:3xxxx/)
<!-- ```open http://node1:3xxxx/``` -->
]
--

View File

@@ -65,6 +65,8 @@ class: extra-details
- Go to [container.training](http://container.training/) to view these slides
- Join the chat room on @@CHAT@@
<!-- ```open http://container.training/``` -->
]
---
@@ -73,6 +75,12 @@ class: pic, in-person
![You get five VMs](you-get-five-vms.jpg)
<!--
```bash
kubectl get all -o name | grep -v services/kubernetes | xargs -n1 kubectl delete
```
-->
---
class: in-person
@@ -102,11 +110,7 @@ done
```
- Type `exit` or `^D` to come back to node1
<!--
```keys
exit
```
-->
<!-- ```keys exit``` -->
]

View File

@@ -79,6 +79,8 @@
kubectl get deployments -w
```
<!-- ```keys ^C``` -->
- Update `worker` either with `kubectl edit`, or by running:
```bash
kubectl set image deploy worker worker=$REGISTRY/worker:$TAG

View File

@@ -264,6 +264,8 @@ class: extra-details
- In your browser, you need to enter the IP address of your node
<!-- ```open http://node1:8000``` -->
]
You should see a speed of approximately 4 hashes/second.
@@ -316,9 +318,25 @@ class: extra-details
- run `top` to see CPU and memory usage (you should see idle cycles)
- run `vmstat 3` to see I/O usage (si/so/bi/bo)
<!--
```bash
top
```
```keys ^C```
-->
- run `vmstat 1` to see I/O usage (si/so/bi/bo)
<br/>(the 4 numbers should be almost zero, except `bo` for logging)
<!--
```bash
vmstat 1
```
```keys ^C```
-->
]
We have available resources.