git-webby 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. data/README.rdoc +74 -0
  2. data/Rakefile +44 -0
  3. data/doc/releases/v0.1.0.rdoc +11 -0
  4. data/git-webby.gemspec +32 -0
  5. data/lib/git/webby.rb +145 -0
  6. data/lib/git/webby/http_backend.rb +248 -0
  7. data/lib/git/webby/version.rb +14 -0
  8. data/test/config_test.rb +30 -0
  9. data/test/fixtures/config.yml +7 -0
  10. data/test/fixtures/htpasswd +4 -0
  11. data/test/fixtures/mycode.git/HEAD +1 -0
  12. data/test/fixtures/mycode.git/config +4 -0
  13. data/test/fixtures/mycode.git/description +1 -0
  14. data/test/fixtures/mycode.git/hooks/applypatch-msg.sample +15 -0
  15. data/test/fixtures/mycode.git/hooks/commit-msg.sample +24 -0
  16. data/test/fixtures/mycode.git/hooks/post-commit.sample +8 -0
  17. data/test/fixtures/mycode.git/hooks/post-receive.sample +15 -0
  18. data/test/fixtures/mycode.git/hooks/post-update.sample +8 -0
  19. data/test/fixtures/mycode.git/hooks/pre-applypatch.sample +14 -0
  20. data/test/fixtures/mycode.git/hooks/pre-commit.sample +46 -0
  21. data/test/fixtures/mycode.git/hooks/pre-rebase.sample +169 -0
  22. data/test/fixtures/mycode.git/hooks/prepare-commit-msg.sample +36 -0
  23. data/test/fixtures/mycode.git/hooks/update.sample +128 -0
  24. data/test/fixtures/mycode.git/info/exclude +6 -0
  25. data/test/fixtures/mycode.git/info/refs +3 -0
  26. data/test/fixtures/mycode.git/objects/02/83eb96425444e17b97182e1ba9f216cc67c132 +0 -0
  27. data/test/fixtures/mycode.git/objects/03/9927042df267a1bc606fc4485b7a79b6a9e3cd +1 -0
  28. data/test/fixtures/mycode.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904 +0 -0
  29. data/test/fixtures/mycode.git/objects/5e/54a0767e0c380f3baab17938d68c7f464cf171 +1 -0
  30. data/test/fixtures/mycode.git/objects/71/6e9568eed27d5ee4378b3ecf6dd095a547bde9 +1 -0
  31. data/test/fixtures/mycode.git/objects/be/118435b9d908fd4a689cd8b0cc98059911a31a +0 -0
  32. data/test/fixtures/mycode.git/objects/db/aefcb5bde664671c73b99515c386dcbc7f22b6 +0 -0
  33. data/test/fixtures/mycode.git/objects/eb/669b878d2013ac70aa5dee75e6357ea81d16ea +0 -0
  34. data/test/fixtures/mycode.git/objects/ed/10cfcf72862e140c97fe899cba2a55f4cb4c20 +0 -0
  35. data/test/fixtures/mycode.git/objects/info/packs +2 -0
  36. data/test/fixtures/mycode.git/objects/pack/pack-40a8636b62258fffd78ec1e8d254116e72d385a9.idx +0 -0
  37. data/test/fixtures/mycode.git/objects/pack/pack-40a8636b62258fffd78ec1e8d254116e72d385a9.pack +0 -0
  38. data/test/fixtures/mycode.git/packed-refs +4 -0
  39. data/test/fixtures/mycode.git/refs/heads/master +1 -0
  40. data/test/fixtures/mycode.git/refs/tags/v0.1.0 +1 -0
  41. data/test/helpers.rb +67 -0
  42. data/test/htpasswd_test.rb +68 -0
  43. data/test/http_backend_authentication_test.rb +69 -0
  44. data/test/http_backend_test.rb +134 -0
  45. metadata +134 -0
@@ -0,0 +1,6 @@
1
+ # git ls-files --others --exclude-from=.git/info/exclude
2
+ # Lines that start with '#' are comments.
3
+ # For a project mostly in C, the following would be a good set of
4
+ # exclude patterns (uncomment them if you want to use them):
5
+ # *.[oa]
6
+ # *~
@@ -0,0 +1,3 @@
1
+ 039927042df267a1bc606fc4485b7a79b6a9e3cd refs/heads/master
2
+ dbaefcb5bde664671c73b99515c386dcbc7f22b6 refs/tags/v0.1.0
3
+ 039927042df267a1bc606fc4485b7a79b6a9e3cd refs/tags/v0.1.0^{}
@@ -0,0 +1 @@
1
+ x��MN�0 @a�9�/��i~K+����LP��:��T���O����%��y�BVk�w!��M<�DER�R(a ���es�C���F���,�U�֔��-� ~͢d�{������1:|���r��K���k�_�h�`!�B��ќz�N�wȼ��~����_Z&Ծ������X'
@@ -0,0 +1 @@
1
+ x��Aj�0@Ѭu��@�4�G�t�c$��-[��
@@ -0,0 +1 @@
1
+ x��A� @Qלb.`3��0�1ƅ�@��$���6�7p���ZJ�8��1� N�K�F�`9�G�<���Œvn
@@ -0,0 +1,2 @@
1
+ P pack-40a8636b62258fffd78ec1e8d254116e72d385a9.pack
2
+
@@ -0,0 +1,4 @@
1
+ # pack-refs with: peeled
2
+ 039927042df267a1bc606fc4485b7a79b6a9e3cd refs/heads/master
3
+ dbaefcb5bde664671c73b99515c386dcbc7f22b6 refs/tags/v0.1.0
4
+ ^039927042df267a1bc606fc4485b7a79b6a9e3cd
@@ -0,0 +1 @@
1
+ 5e54a0767e0c380f3baab17938d68c7f464cf171
@@ -0,0 +1 @@
1
+ dbaefcb5bde664671c73b99515c386dcbc7f22b6
data/test/helpers.rb ADDED
@@ -0,0 +1,67 @@
1
+ # This code extracted from book "Ruby Best Practices" and the code be found
2
+ # in http://github.com/sandal/rbp/blob/master/testing/test_unit_extensions.rb
3
+
4
+ FIXTURES = File.expand_path(File.join(File.dirname(__FILE__), "fixtures")) unless defined? FIXTURES
5
+
6
+ module Test::Unit
7
+ class TestCase
8
+ def self.should(description, &block)
9
+ test_name = "test_#{description.gsub(/\s+/,'_')}".downcase.to_sym
10
+ defined = instance_method(test_name) rescue false
11
+ raise "#{test_name} is already defined in #{self}" if defined
12
+ if block_given?
13
+ define_method(test_name, &block)
14
+ else
15
+ define_method(test_name) do
16
+ flunk "No implementation provided for #{description}"
17
+ end
18
+ end
19
+ end
20
+
21
+ def fixtures(*args)
22
+ File.join(FIXTURES, *(args.map(&:to_s)))
23
+ end
24
+
25
+ def debugger
26
+ end unless defined? debugger
27
+
28
+ end
29
+
30
+ module Assertions
31
+
32
+ def assert_hash_equal(expected, actual, message = nil)
33
+ messages = {}
34
+ expected.keys.each do |key|
35
+ equal = actual[key] == expected[key]
36
+ messages[key] = build_message(message, "#{expected[key]} expected but was <?>", actual[key])
37
+ assert_block(messages[key]) { expected[key] == actual[key] }
38
+ end
39
+ end
40
+ end
41
+
42
+ end
43
+
44
+ class MockProcess
45
+
46
+ def initialize
47
+ @counter = 0
48
+ end
49
+
50
+ def write(data)
51
+ end
52
+
53
+ def read(data)
54
+ end
55
+
56
+ def eof?
57
+ @counter += 1
58
+ @counter > 1 ? true : false
59
+ end
60
+
61
+ end
62
+
63
+ class IO
64
+ def self.popen(*args)
65
+ MockProcess.new
66
+ end
67
+ end
@@ -0,0 +1,68 @@
1
+ require "test/unit"
2
+ require "test/helpers"
3
+ require "git/webby"
4
+
5
+ class HtpasswdTest < Test::Unit::TestCase
6
+
7
+ def setup
8
+ @passwords = {
9
+ "matthew" => "zKOzsdCzE.mEE",
10
+ "mark" => "V5.e7XhcXHmQc",
11
+ "luke" => "1y687odVzuFJs",
12
+ "john" => "BInD5.JEyr5Ng"
13
+ }
14
+ @htpasswd = Git::Webby::Htpasswd.new(fixtures("htpasswd"))
15
+ end
16
+
17
+ def teardown
18
+ File.delete fixtures("htpasswd.tmp") if File.exist? fixtures("htpasswd.tmp")
19
+ end
20
+
21
+ should "find user" do
22
+ @passwords.each do |username, password|
23
+ assert_equal password, @htpasswd.find(username)
24
+ @htpasswd.find username do |pass, salt|
25
+ assert_equal password, pass
26
+ assert_equal password[0,2], salt
27
+ end
28
+ end
29
+ end
30
+
31
+ should "check authentication of the user" do
32
+ @passwords.keys.each do |user|
33
+ assert !@htpasswd.authenticated?(user, "invalid")
34
+ assert @htpasswd.authenticated?(user, "s3kr3t")
35
+ end
36
+ end
37
+
38
+ should "create or update user" do
39
+ Git::Webby::Htpasswd.new fixtures("htpasswd.tmp") do |htpasswd|
40
+ htpasswd.create "judas", "hanged"
41
+ assert htpasswd.include?("judas")
42
+ assert htpasswd.authenticated?("judas", "hanged")
43
+ end
44
+ end
45
+
46
+ should "list users" do
47
+ assert_equal 4, @htpasswd.size
48
+ @passwords.keys.each do |user|
49
+ assert @htpasswd.include?(user)
50
+ end
51
+ end
52
+
53
+ should "destroy user" do
54
+ Git::Webby::Htpasswd.new fixtures("htpasswd.tmp") do |htpasswd|
55
+ htpasswd.create "judas", "hanged"
56
+ assert htpasswd.include?("judas")
57
+
58
+ htpasswd.destroy "judas"
59
+
60
+ assert !htpasswd.include?("judas")
61
+ end
62
+ end
63
+
64
+ should "check invalid user" do
65
+ assert !@htpasswd.authenticated?("nobody", "empty")
66
+ end
67
+
68
+ end
@@ -0,0 +1,69 @@
1
+ require "test/unit"
2
+ require "test/helpers"
3
+ require "rack"
4
+ require "rack/test"
5
+ require "git/webby"
6
+
7
+ class HttpBackendAuthenticationTest < Test::Unit::TestCase
8
+ include Rack::Test::Methods
9
+
10
+ def setup
11
+ # return 500 objects/info/http-alternates
12
+ # objects/info/alternates
13
+ @paths = [
14
+ [ :get, "HEAD" ],
15
+ [ :get, "info/refs" ],
16
+ [ :get, "objects/info/packs" ],
17
+ [ :get, "objects/02/83eb96425444e17b97182e1ba9f216cc67c132" ],
18
+ [ :get, "objects/03/9927042df267a1bc606fc4485b7a79b6a9e3cd" ],
19
+ [ :get, "objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904" ],
20
+ [ :get, "objects/5e/54a0767e0c380f3baab17938d68c7f464cf171" ],
21
+ [ :get, "objects/71/6e9568eed27d5ee4378b3ecf6dd095a547bde9" ],
22
+ [ :get, "objects/be/118435b9d908fd4a689cd8b0cc98059911a31a" ],
23
+ [ :get, "objects/db/aefcb5bde664671c73b99515c386dcbc7f22b6" ],
24
+ [ :get, "objects/eb/669b878d2013ac70aa5dee75e6357ea81d16ea" ],
25
+ [ :get, "objects/ed/10cfcf72862e140c97fe899cba2a55f4cb4c20" ],
26
+ [ :get, "objects/pack/pack-40a8636b62258fffd78ec1e8d254116e72d385a9.idx" ],
27
+ [ :get, "objects/pack/pack-40a8636b62258fffd78ec1e8d254116e72d385a9.pack" ],
28
+ [ :get, "info/refs", { :service => "git-upload-pack" } ],
29
+ [ :get, "info/refs", { :service => "git-receive-pack" } ],
30
+ [ :post, "git-upload-pack", {}, { "CONTENT_TYPE" => "application/x-git-upload-pack-request" } ],
31
+ [ :post, "git-receive-pack", {}, { "CONTENT_TYPE" => "application/x-git-receive-pack-request" } ]
32
+ ]
33
+ end
34
+
35
+ def app
36
+ @app = Git::Webby::HttpBackend.configure do |server|
37
+ server.project_root = fixtures
38
+ server.git_path = "/usr/bin/git"
39
+ server.authenticate = true
40
+ end
41
+ @app
42
+ end
43
+
44
+ should "unauthorize repository paths" do
45
+ @paths.each do |params|
46
+ verb = params.shift
47
+ path = params.shift
48
+ send verb, "/mycode.git/#{path}", *params
49
+ assert_equal 401, response.status
50
+ end
51
+ end
52
+
53
+ should "authorize repository paths" do
54
+ authorize("john", "s3kr3t")
55
+ @paths.each do |params|
56
+ verb = params.shift
57
+ path = params.shift
58
+ send verb, "/mycode.git/#{path}", *params
59
+ assert_equal 200, response.status
60
+ end
61
+ end
62
+
63
+ private
64
+
65
+ def response
66
+ last_response
67
+ end
68
+
69
+ end
@@ -0,0 +1,134 @@
1
+ require "test/unit"
2
+ require "test/helpers"
3
+ require "rack"
4
+ require "rack/test"
5
+ require "git/webby"
6
+
7
+ class HttpBackendTest < Test::Unit::TestCase
8
+ include Rack::Test::Methods
9
+
10
+ def setup
11
+ @objects = [
12
+ "02/83eb96425444e17b97182e1ba9f216cc67c132",
13
+ "03/9927042df267a1bc606fc4485b7a79b6a9e3cd",
14
+ "4b/825dc642cb6eb9a060e54bf8d69288fbee4904",
15
+ "5e/54a0767e0c380f3baab17938d68c7f464cf171",
16
+ "71/6e9568eed27d5ee4378b3ecf6dd095a547bde9",
17
+ "be/118435b9d908fd4a689cd8b0cc98059911a31a",
18
+ "db/aefcb5bde664671c73b99515c386dcbc7f22b6",
19
+ "eb/669b878d2013ac70aa5dee75e6357ea81d16ea",
20
+ "ed/10cfcf72862e140c97fe899cba2a55f4cb4c20"
21
+ ]
22
+ end
23
+
24
+ def app
25
+ @app = Git::Webby::HttpBackend.configure do |server|
26
+ server.project_root = fixtures
27
+ server.git_path = "/usr/bin/git"
28
+ server.get_any_file = true
29
+ server.upload_pack = true
30
+ server.receive_pack = true
31
+ server.authenticate = false
32
+ end
33
+ @app
34
+ end
35
+
36
+ should "get head" do
37
+ get "/mycode.git/HEAD" do
38
+ assert_equal 200, response.status
39
+ assert_equal "ref: refs/heads/master\n", response.body
40
+ end
41
+ end
42
+
43
+ should "get info refs" do
44
+ get "/mycode.git/info/refs" do
45
+ assert_equal 200, response.status
46
+ assert_match "refs/heads/master", response.body
47
+ assert_match "refs/tags/v0.1.0", response.body
48
+ end
49
+ end
50
+
51
+ should "get info alternates" do
52
+ get "/mycode.git/objects/info/alternates" do
53
+ assert_equal 500, response.status # fixtures without alternates
54
+ end
55
+ end
56
+
57
+ should "get info http alternates" do
58
+ get "/mycode.git/objects/info/http-alternates" do
59
+ assert_equal 500, response.status # fixtures without http-alternates
60
+ end
61
+ end
62
+
63
+ should "get object info packs" do
64
+ get "/mycode.git/objects/info/packs" do
65
+ assert_equal 200, response.status
66
+ assert_equal "P pack-40a8636b62258fffd78ec1e8d254116e72d385a9.pack",
67
+ response.body.split("\n").first
68
+ end
69
+ end
70
+
71
+ should "get loose objects" do
72
+ @objects.each do |object|
73
+ get "/mycode.git/objects/#{object}" do
74
+ assert_equal 200, response.status
75
+ assert_equal "application/x-git-loose-object", response.content_type
76
+ end
77
+ end
78
+ end
79
+
80
+ should "get pack file" do
81
+ get "/mycode.git/objects/pack/pack-40a8636b62258fffd78ec1e8d254116e72d385a9.idx" do
82
+ assert_equal 200, response.status
83
+ assert_equal "application/x-git-packed-objects-toc", response.content_type
84
+ end
85
+ end
86
+
87
+ should "get index file" do
88
+ get "/mycode.git/objects/pack/pack-40a8636b62258fffd78ec1e8d254116e72d385a9.pack" do
89
+ assert_equal 200, response.status
90
+ assert_equal "application/x-git-packed-objects", response.content_type
91
+ end
92
+ end
93
+
94
+ should "upload advertisement" do
95
+ get "/mycode.git/info/refs", :service => "git-upload-pack" do
96
+ assert_equal 200, response.status
97
+ assert_equal "application/x-git-upload-pack-advertisement", response.content_type
98
+ assert_equal "001e# service=git-upload-pack", response.body.split("\n").first
99
+ assert_match 'multi_ack_detailed', response.body
100
+ end
101
+ end
102
+
103
+ should "receive advertisement" do
104
+ get "/mycode.git/info/refs", :service => "git-receive-pack" do
105
+ assert_equal 200, response.status
106
+ assert_equal "application/x-git-receive-pack-advertisement", response.content_type
107
+ assert_equal "001f# service=git-receive-pack", response.body.split("\n").first
108
+ assert_match "report-status", response.body
109
+ assert_match "delete-refs", response.body
110
+ assert_match "ofs-delta", response.body
111
+ end
112
+ end
113
+
114
+ # this test use mock in IO.popen. See in test/helpers.rb.
115
+ should "RPC for upload packets" do
116
+ post "/mycode.git/git-upload-pack", {}, {"CONTENT_TYPE" => "application/x-git-upload-pack-request"}
117
+ assert_equal 200, response.status
118
+ assert_equal "application/x-git-upload-pack-result", response.content_type
119
+ end
120
+
121
+ # this test use mock in IO.popen. See in test/helpers.rb.
122
+ should "RPC for receive packets" do
123
+ post "/mycode.git/git-receive-pack", {}, {"CONTENT_TYPE" => "application/x-git-receive-pack-request"}
124
+ assert_equal 200, response.status
125
+ assert_equal "application/x-git-receive-pack-result", response.content_type
126
+ end
127
+
128
+ private
129
+
130
+ def response
131
+ last_response
132
+ end
133
+
134
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: git-webby
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Hallison Batista
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-07-13 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: sinatra
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 15
30
+ segments:
31
+ - 1
32
+ - 0
33
+ version: "1.0"
34
+ type: :runtime
35
+ version_requirements: *id001
36
+ description: |
37
+ Git::Webby is a implementation of the several features:
38
+ - Smart HTTP which works like as git-http-backend.
39
+ - Show info pages about the projects.
40
+
41
+ email: hallison@codigorama.com
42
+ executables: []
43
+
44
+ extensions: []
45
+
46
+ extra_rdoc_files: []
47
+
48
+ files:
49
+ - README.rdoc
50
+ - Rakefile
51
+ - doc/releases/v0.1.0.rdoc
52
+ - git-webby.gemspec
53
+ - lib/git/webby.rb
54
+ - lib/git/webby/http_backend.rb
55
+ - lib/git/webby/version.rb
56
+ - test/config_test.rb
57
+ - test/fixtures/config.yml
58
+ - test/fixtures/htpasswd
59
+ - test/fixtures/mycode.git/HEAD
60
+ - test/fixtures/mycode.git/config
61
+ - test/fixtures/mycode.git/description
62
+ - test/fixtures/mycode.git/hooks/applypatch-msg.sample
63
+ - test/fixtures/mycode.git/hooks/commit-msg.sample
64
+ - test/fixtures/mycode.git/hooks/post-commit.sample
65
+ - test/fixtures/mycode.git/hooks/post-receive.sample
66
+ - test/fixtures/mycode.git/hooks/post-update.sample
67
+ - test/fixtures/mycode.git/hooks/pre-applypatch.sample
68
+ - test/fixtures/mycode.git/hooks/pre-commit.sample
69
+ - test/fixtures/mycode.git/hooks/pre-rebase.sample
70
+ - test/fixtures/mycode.git/hooks/prepare-commit-msg.sample
71
+ - test/fixtures/mycode.git/hooks/update.sample
72
+ - test/fixtures/mycode.git/info/exclude
73
+ - test/fixtures/mycode.git/info/refs
74
+ - test/fixtures/mycode.git/objects/02/83eb96425444e17b97182e1ba9f216cc67c132
75
+ - test/fixtures/mycode.git/objects/03/9927042df267a1bc606fc4485b7a79b6a9e3cd
76
+ - test/fixtures/mycode.git/objects/4b/825dc642cb6eb9a060e54bf8d69288fbee4904
77
+ - test/fixtures/mycode.git/objects/5e/54a0767e0c380f3baab17938d68c7f464cf171
78
+ - test/fixtures/mycode.git/objects/71/6e9568eed27d5ee4378b3ecf6dd095a547bde9
79
+ - test/fixtures/mycode.git/objects/be/118435b9d908fd4a689cd8b0cc98059911a31a
80
+ - test/fixtures/mycode.git/objects/db/aefcb5bde664671c73b99515c386dcbc7f22b6
81
+ - test/fixtures/mycode.git/objects/eb/669b878d2013ac70aa5dee75e6357ea81d16ea
82
+ - test/fixtures/mycode.git/objects/ed/10cfcf72862e140c97fe899cba2a55f4cb4c20
83
+ - test/fixtures/mycode.git/objects/info/packs
84
+ - test/fixtures/mycode.git/objects/pack/pack-40a8636b62258fffd78ec1e8d254116e72d385a9.idx
85
+ - test/fixtures/mycode.git/objects/pack/pack-40a8636b62258fffd78ec1e8d254116e72d385a9.pack
86
+ - test/fixtures/mycode.git/packed-refs
87
+ - test/fixtures/mycode.git/refs/heads/master
88
+ - test/fixtures/mycode.git/refs/tags/v0.1.0
89
+ - test/helpers.rb
90
+ - test/htpasswd_test.rb
91
+ - test/http_backend_authentication_test.rb
92
+ - test/http_backend_test.rb
93
+ has_rdoc: true
94
+ homepage: http://github.com/codigorama/git-webby
95
+ licenses: []
96
+
97
+ post_install_message: |
98
+ ------------------------------------------------------------------------------
99
+ Git::Webby v0.1.0
100
+
101
+ Thanks for use Git::Webby.
102
+ ------------------------------------------------------------------------------
103
+
104
+ rdoc_options: []
105
+
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ hash: 3
114
+ segments:
115
+ - 0
116
+ version: "0"
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ hash: 3
123
+ segments:
124
+ - 0
125
+ version: "0"
126
+ requirements: []
127
+
128
+ rubyforge_project: git-webby
129
+ rubygems_version: 1.3.7
130
+ signing_key:
131
+ specification_version: 3
132
+ summary: Git Web implementation of the Smart HTTP and other features
133
+ test_files: []
134
+